diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/curl/lib | |
parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
download | ydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/curl/lib')
154 files changed, 18668 insertions, 18668 deletions
diff --git a/contrib/libs/curl/lib/altsvc.c b/contrib/libs/curl/lib/altsvc.c index 08cd3a4e51..4ab77fdfc8 100644 --- a/contrib/libs/curl/lib/altsvc.c +++ b/contrib/libs/curl/lib/altsvc.c @@ -1,55 +1,55 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -/* - * The Alt-Svc: header is defined in RFC 7838: - * https://tools.ietf.org/html/rfc7838 - */ -#include "curl_setup.h" - + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + * The Alt-Svc: header is defined in RFC 7838: + * https://tools.ietf.org/html/rfc7838 + */ +#include "curl_setup.h" + #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC) -#include <curl/curl.h> -#include "urldata.h" -#include "altsvc.h" -#include "curl_get_line.h" -#include "strcase.h" -#include "parsedate.h" -#include "sendf.h" -#include "warnless.h" +#include <curl/curl.h> +#include "urldata.h" +#include "altsvc.h" +#include "curl_get_line.h" +#include "strcase.h" +#include "parsedate.h" +#include "sendf.h" +#include "warnless.h" #include "rand.h" #include "rename.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#define MAX_ALTSVC_LINE 4095 -#define MAX_ALTSVC_DATELENSTR "64" -#define MAX_ALTSVC_DATELEN 64 -#define MAX_ALTSVC_HOSTLENSTR "512" -#define MAX_ALTSVC_HOSTLEN 512 -#define MAX_ALTSVC_ALPNLENSTR "10" -#define MAX_ALTSVC_ALPNLEN 10 - + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define MAX_ALTSVC_LINE 4095 +#define MAX_ALTSVC_DATELENSTR "64" +#define MAX_ALTSVC_DATELEN 64 +#define MAX_ALTSVC_HOSTLENSTR "512" +#define MAX_ALTSVC_HOSTLEN 512 +#define MAX_ALTSVC_ALPNLENSTR "10" +#define MAX_ALTSVC_ALPNLEN 10 + #if defined(USE_QUICHE) && !defined(UNITTESTS) #define H3VERSION "h3-29" #elif defined(USE_NGTCP2) && !defined(UNITTESTS) @@ -58,136 +58,136 @@ #define H3VERSION "h3" #endif -static enum alpnid alpn2alpnid(char *name) -{ - if(strcasecompare(name, "h1")) - return ALPN_h1; - if(strcasecompare(name, "h2")) - return ALPN_h2; +static enum alpnid alpn2alpnid(char *name) +{ + if(strcasecompare(name, "h1")) + return ALPN_h1; + if(strcasecompare(name, "h2")) + return ALPN_h2; if(strcasecompare(name, H3VERSION)) - return ALPN_h3; - return ALPN_none; /* unknown, probably rubbish input */ -} - -/* Given the ALPN ID, return the name */ -const char *Curl_alpnid2str(enum alpnid id) -{ - switch(id) { - case ALPN_h1: - return "h1"; - case ALPN_h2: - return "h2"; - case ALPN_h3: + return ALPN_h3; + return ALPN_none; /* unknown, probably rubbish input */ +} + +/* Given the ALPN ID, return the name */ +const char *Curl_alpnid2str(enum alpnid id) +{ + switch(id) { + case ALPN_h1: + return "h1"; + case ALPN_h2: + return "h2"; + case ALPN_h3: return H3VERSION; - default: - return ""; /* bad */ - } -} - - -static void altsvc_free(struct altsvc *as) -{ - free(as->src.host); - free(as->dst.host); - free(as); -} - -static struct altsvc *altsvc_createid(const char *srchost, - const char *dsthost, - enum alpnid srcalpnid, - enum alpnid dstalpnid, - unsigned int srcport, - unsigned int dstport) -{ - struct altsvc *as = calloc(sizeof(struct altsvc), 1); - if(!as) - return NULL; - - as->src.host = strdup(srchost); - if(!as->src.host) - goto error; - as->dst.host = strdup(dsthost); - if(!as->dst.host) - goto error; - - as->src.alpnid = srcalpnid; - as->dst.alpnid = dstalpnid; - as->src.port = curlx_ultous(srcport); - as->dst.port = curlx_ultous(dstport); - - return as; - error: - altsvc_free(as); - return NULL; -} - -static struct altsvc *altsvc_create(char *srchost, - char *dsthost, - char *srcalpn, - char *dstalpn, - unsigned int srcport, - unsigned int dstport) -{ - enum alpnid dstalpnid = alpn2alpnid(dstalpn); - enum alpnid srcalpnid = alpn2alpnid(srcalpn); - if(!srcalpnid || !dstalpnid) - return NULL; - return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid, - srcport, dstport); -} - -/* only returns SERIOUS errors */ -static CURLcode altsvc_add(struct altsvcinfo *asi, char *line) -{ - /* Example line: - h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1 - */ - char srchost[MAX_ALTSVC_HOSTLEN + 1]; - char dsthost[MAX_ALTSVC_HOSTLEN + 1]; - char srcalpn[MAX_ALTSVC_ALPNLEN + 1]; - char dstalpn[MAX_ALTSVC_ALPNLEN + 1]; - char date[MAX_ALTSVC_DATELEN + 1]; - unsigned int srcport; - unsigned int dstport; - unsigned int prio; - unsigned int persist; - int rc; - - rc = sscanf(line, - "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u " - "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u " - "\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u", - srcalpn, srchost, &srcport, - dstalpn, dsthost, &dstport, - date, &persist, &prio); - if(9 == rc) { - struct altsvc *as; + default: + return ""; /* bad */ + } +} + + +static void altsvc_free(struct altsvc *as) +{ + free(as->src.host); + free(as->dst.host); + free(as); +} + +static struct altsvc *altsvc_createid(const char *srchost, + const char *dsthost, + enum alpnid srcalpnid, + enum alpnid dstalpnid, + unsigned int srcport, + unsigned int dstport) +{ + struct altsvc *as = calloc(sizeof(struct altsvc), 1); + if(!as) + return NULL; + + as->src.host = strdup(srchost); + if(!as->src.host) + goto error; + as->dst.host = strdup(dsthost); + if(!as->dst.host) + goto error; + + as->src.alpnid = srcalpnid; + as->dst.alpnid = dstalpnid; + as->src.port = curlx_ultous(srcport); + as->dst.port = curlx_ultous(dstport); + + return as; + error: + altsvc_free(as); + return NULL; +} + +static struct altsvc *altsvc_create(char *srchost, + char *dsthost, + char *srcalpn, + char *dstalpn, + unsigned int srcport, + unsigned int dstport) +{ + enum alpnid dstalpnid = alpn2alpnid(dstalpn); + enum alpnid srcalpnid = alpn2alpnid(srcalpn); + if(!srcalpnid || !dstalpnid) + return NULL; + return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid, + srcport, dstport); +} + +/* only returns SERIOUS errors */ +static CURLcode altsvc_add(struct altsvcinfo *asi, char *line) +{ + /* Example line: + h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1 + */ + char srchost[MAX_ALTSVC_HOSTLEN + 1]; + char dsthost[MAX_ALTSVC_HOSTLEN + 1]; + char srcalpn[MAX_ALTSVC_ALPNLEN + 1]; + char dstalpn[MAX_ALTSVC_ALPNLEN + 1]; + char date[MAX_ALTSVC_DATELEN + 1]; + unsigned int srcport; + unsigned int dstport; + unsigned int prio; + unsigned int persist; + int rc; + + rc = sscanf(line, + "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u " + "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u " + "\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u", + srcalpn, srchost, &srcport, + dstalpn, dsthost, &dstport, + date, &persist, &prio); + if(9 == rc) { + struct altsvc *as; time_t expires = Curl_getdate_capped(date); - as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport); - if(as) { - as->expires = expires; - as->prio = prio; - as->persist = persist ? 1 : 0; - Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node); - } - } - - return CURLE_OK; -} - -/* - * Load alt-svc entries from the given file. The text based line-oriented file - * format is documented here: - * https://github.com/curl/curl/wiki/QUIC-implementation - * - * This function only returns error on major problems that prevents alt-svc - * handling to work completely. It will ignore individual syntactical errors - * etc. - */ -static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) -{ - CURLcode result = CURLE_OK; - char *line = NULL; + as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport); + if(as) { + as->expires = expires; + as->prio = prio; + as->persist = persist ? 1 : 0; + Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node); + } + } + + return CURLE_OK; +} + +/* + * Load alt-svc entries from the given file. The text based line-oriented file + * format is documented here: + * https://github.com/curl/curl/wiki/QUIC-implementation + * + * This function only returns error on major problems that prevents alt-svc + * handling to work completely. It will ignore individual syntactical errors + * etc. + */ +static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) +{ + CURLcode result = CURLE_OK; + char *line = NULL; FILE *fp; /* we need a private copy of the file name so that the altsvc cache file @@ -198,151 +198,151 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) return CURLE_OUT_OF_MEMORY; fp = fopen(file, FOPEN_READTEXT); - if(fp) { - line = malloc(MAX_ALTSVC_LINE); - if(!line) - goto fail; - while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) { - char *lineptr = line; - while(*lineptr && ISBLANK(*lineptr)) - lineptr++; - if(*lineptr == '#') - /* skip commented lines */ - continue; - - altsvc_add(asi, lineptr); - } - free(line); /* free the line buffer */ - fclose(fp); - } - return result; - - fail: + if(fp) { + line = malloc(MAX_ALTSVC_LINE); + if(!line) + goto fail; + while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) { + char *lineptr = line; + while(*lineptr && ISBLANK(*lineptr)) + lineptr++; + if(*lineptr == '#') + /* skip commented lines */ + continue; + + altsvc_add(asi, lineptr); + } + free(line); /* free the line buffer */ + fclose(fp); + } + return result; + + fail: Curl_safefree(asi->filename); - free(line); - fclose(fp); - return CURLE_OUT_OF_MEMORY; -} - -/* - * Write this single altsvc entry to a single output line - */ - -static CURLcode altsvc_out(struct altsvc *as, FILE *fp) -{ - struct tm stamp; - CURLcode result = Curl_gmtime(as->expires, &stamp); - if(result) - return result; - - fprintf(fp, - "%s %s %u " - "%s %s %u " - "\"%d%02d%02d " - "%02d:%02d:%02d\" " - "%u %d\n", - Curl_alpnid2str(as->src.alpnid), as->src.host, as->src.port, - Curl_alpnid2str(as->dst.alpnid), as->dst.host, as->dst.port, - stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday, - stamp.tm_hour, stamp.tm_min, stamp.tm_sec, - as->persist, as->prio); - return CURLE_OK; -} - -/* ---- library-wide functions below ---- */ - -/* - * Curl_altsvc_init() creates a new altsvc cache. - * It returns the new instance or NULL if something goes wrong. - */ -struct altsvcinfo *Curl_altsvc_init(void) -{ - struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1); - if(!asi) - return NULL; - Curl_llist_init(&asi->list, NULL); - - /* set default behavior */ - asi->flags = CURLALTSVC_H1 -#ifdef USE_NGHTTP2 - | CURLALTSVC_H2 -#endif -#ifdef ENABLE_QUIC - | CURLALTSVC_H3 -#endif - ; - return asi; -} - -/* - * Curl_altsvc_load() loads alt-svc from file. - */ -CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file) -{ - CURLcode result; - DEBUGASSERT(asi); - result = altsvc_load(asi, file); - return result; -} - -/* - * Curl_altsvc_ctrl() passes on the external bitmask. - */ -CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl) -{ - DEBUGASSERT(asi); - if(!ctrl) - /* unexpected */ - return CURLE_BAD_FUNCTION_ARGUMENT; - asi->flags = ctrl; - return CURLE_OK; -} - -/* - * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated - * resources. - */ + free(line); + fclose(fp); + return CURLE_OUT_OF_MEMORY; +} + +/* + * Write this single altsvc entry to a single output line + */ + +static CURLcode altsvc_out(struct altsvc *as, FILE *fp) +{ + struct tm stamp; + CURLcode result = Curl_gmtime(as->expires, &stamp); + if(result) + return result; + + fprintf(fp, + "%s %s %u " + "%s %s %u " + "\"%d%02d%02d " + "%02d:%02d:%02d\" " + "%u %d\n", + Curl_alpnid2str(as->src.alpnid), as->src.host, as->src.port, + Curl_alpnid2str(as->dst.alpnid), as->dst.host, as->dst.port, + stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday, + stamp.tm_hour, stamp.tm_min, stamp.tm_sec, + as->persist, as->prio); + return CURLE_OK; +} + +/* ---- library-wide functions below ---- */ + +/* + * Curl_altsvc_init() creates a new altsvc cache. + * It returns the new instance or NULL if something goes wrong. + */ +struct altsvcinfo *Curl_altsvc_init(void) +{ + struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1); + if(!asi) + return NULL; + Curl_llist_init(&asi->list, NULL); + + /* set default behavior */ + asi->flags = CURLALTSVC_H1 +#ifdef USE_NGHTTP2 + | CURLALTSVC_H2 +#endif +#ifdef ENABLE_QUIC + | CURLALTSVC_H3 +#endif + ; + return asi; +} + +/* + * Curl_altsvc_load() loads alt-svc from file. + */ +CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file) +{ + CURLcode result; + DEBUGASSERT(asi); + result = altsvc_load(asi, file); + return result; +} + +/* + * Curl_altsvc_ctrl() passes on the external bitmask. + */ +CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl) +{ + DEBUGASSERT(asi); + if(!ctrl) + /* unexpected */ + return CURLE_BAD_FUNCTION_ARGUMENT; + asi->flags = ctrl; + return CURLE_OK; +} + +/* + * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated + * resources. + */ void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp) -{ +{ struct Curl_llist_element *e; struct Curl_llist_element *n; if(*altsvcp) { struct altsvcinfo *altsvc = *altsvcp; - for(e = altsvc->list.head; e; e = n) { - struct altsvc *as = e->ptr; - n = e->next; - altsvc_free(as); - } + for(e = altsvc->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + altsvc_free(as); + } free(altsvc->filename); - free(altsvc); + free(altsvc); *altsvcp = NULL; /* clear the pointer */ - } -} - -/* - * Curl_altsvc_save() writes the altsvc cache to a file. - */ + } +} + +/* + * Curl_altsvc_save() writes the altsvc cache to a file. + */ CURLcode Curl_altsvc_save(struct Curl_easy *data, struct altsvcinfo *altsvc, const char *file) -{ +{ struct Curl_llist_element *e; struct Curl_llist_element *n; - CURLcode result = CURLE_OK; - FILE *out; + CURLcode result = CURLE_OK; + FILE *out; char *tempstore; unsigned char randsuffix[9]; - - if(!altsvc) - /* no cache activated */ - return CURLE_OK; - + + if(!altsvc) + /* no cache activated */ + return CURLE_OK; + /* if not new name is given, use the one we stored from the load */ if(!file && altsvc->filename) file = altsvc->filename; if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0]) /* marked as read-only, no file or zero length file name */ - return CURLE_OK; + return CURLE_OK; if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix))) return CURLE_FAILED_INIT; @@ -352,7 +352,7 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; out = fopen(tempstore, FOPEN_WRITETEXT); - if(!out) + if(!out) result = CURLE_WRITE_ERROR; else { fputs("# Your alt-svc cache. https://curl.se/docs/alt-svc.html\n" @@ -369,93 +369,93 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data, if(!result && Curl_rename(tempstore, file)) result = CURLE_WRITE_ERROR; - if(result) + if(result) unlink(tempstore); - } + } free(tempstore); - return result; -} - -static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen) -{ - size_t len; - const char *protop; - const char *p = *ptr; - while(*p && ISBLANK(*p)) - p++; - protop = p; - while(*p && !ISBLANK(*p) && (*p != ';') && (*p != '=')) - p++; - len = p - protop; + return result; +} + +static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen) +{ + size_t len; + const char *protop; + const char *p = *ptr; + while(*p && ISBLANK(*p)) + p++; + protop = p; + while(*p && !ISBLANK(*p) && (*p != ';') && (*p != '=')) + p++; + len = p - protop; *ptr = p; - - if(!len || (len >= buflen)) - return CURLE_BAD_FUNCTION_ARGUMENT; - memcpy(alpnbuf, protop, len); - alpnbuf[len] = 0; - return CURLE_OK; -} - -/* altsvc_flush() removes all alternatives for this source origin from the - list */ -static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid, - const char *srchost, unsigned short srcport) -{ + + if(!len || (len >= buflen)) + return CURLE_BAD_FUNCTION_ARGUMENT; + memcpy(alpnbuf, protop, len); + alpnbuf[len] = 0; + return CURLE_OK; +} + +/* altsvc_flush() removes all alternatives for this source origin from the + list */ +static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid, + const char *srchost, unsigned short srcport) +{ struct Curl_llist_element *e; struct Curl_llist_element *n; - for(e = asi->list.head; e; e = n) { - struct altsvc *as = e->ptr; - n = e->next; - if((srcalpnid == as->src.alpnid) && - (srcport == as->src.port) && - strcasecompare(srchost, as->src.host)) { - Curl_llist_remove(&asi->list, e, NULL); - altsvc_free(as); - } - } -} - -#ifdef DEBUGBUILD -/* to play well with debug builds, we can *set* a fixed time this will - return */ -static time_t debugtime(void *unused) -{ - char *timestr = getenv("CURL_TIME"); - (void)unused; - if(timestr) { - unsigned long val = strtol(timestr, NULL, 10); - return (time_t)val; - } - return time(NULL); -} -#define time(x) debugtime(x) -#endif - + for(e = asi->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + if((srcalpnid == as->src.alpnid) && + (srcport == as->src.port) && + strcasecompare(srchost, as->src.host)) { + Curl_llist_remove(&asi->list, e, NULL); + altsvc_free(as); + } + } +} + +#ifdef DEBUGBUILD +/* to play well with debug builds, we can *set* a fixed time this will + return */ +static time_t debugtime(void *unused) +{ + char *timestr = getenv("CURL_TIME"); + (void)unused; + if(timestr) { + unsigned long val = strtol(timestr, NULL, 10); + return (time_t)val; + } + return time(NULL); +} +#define time(x) debugtime(x) +#endif + #define ISNEWLINE(x) (((x) == '\n') || (x) == '\r') -/* - * Curl_altsvc_parse() takes an incoming alt-svc response header and stores - * the data correctly in the cache. - * - * 'value' points to the header *value*. That's contents to the right of the - * header name. +/* + * Curl_altsvc_parse() takes an incoming alt-svc response header and stores + * the data correctly in the cache. + * + * 'value' points to the header *value*. That's contents to the right of the + * header name. * * Currently this function rejects invalid data without returning an error. * Invalid host name, port number will result in the specific alternative * being rejected. Unknown protocols are skipped. - */ -CURLcode Curl_altsvc_parse(struct Curl_easy *data, - struct altsvcinfo *asi, const char *value, - enum alpnid srcalpnid, const char *srchost, - unsigned short srcport) -{ - const char *p = value; - size_t len; - char namebuf[MAX_ALTSVC_HOSTLEN] = ""; - char alpnbuf[MAX_ALTSVC_ALPNLEN] = ""; - struct altsvc *as; - unsigned short dstport = srcport; /* the same by default */ - CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); + */ +CURLcode Curl_altsvc_parse(struct Curl_easy *data, + struct altsvcinfo *asi, const char *value, + enum alpnid srcalpnid, const char *srchost, + unsigned short srcport) +{ + const char *p = value; + size_t len; + char namebuf[MAX_ALTSVC_HOSTLEN] = ""; + char alpnbuf[MAX_ALTSVC_ALPNLEN] = ""; + struct altsvc *as; + unsigned short dstport = srcport; /* the same by default */ + CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); #ifdef CURL_DISABLE_VERBOSE_STRINGS (void)data; #endif @@ -463,23 +463,23 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, infof(data, "Excessive alt-svc header, ignoring...\n"); return CURLE_OK; } - - DEBUGASSERT(asi); - - /* Flush all cached alternatives for this source origin, if any */ - altsvc_flush(asi, srcalpnid, srchost, srcport); - - /* "clear" is a magic keyword */ - if(strcasecompare(alpnbuf, "clear")) { - return CURLE_OK; - } - - do { - if(*p == '=') { - /* [protocol]="[host][:port]" */ + + DEBUGASSERT(asi); + + /* Flush all cached alternatives for this source origin, if any */ + altsvc_flush(asi, srcalpnid, srchost, srcport); + + /* "clear" is a magic keyword */ + if(strcasecompare(alpnbuf, "clear")) { + return CURLE_OK; + } + + do { + if(*p == '=') { + /* [protocol]="[host][:port]" */ enum alpnid dstalpnid = alpn2alpnid(alpnbuf); /* the same by default */ - p++; - if(*p == '\"') { + p++; + if(*p == '\"') { const char *dsthost = ""; const char *value_ptr; char option[32]; @@ -488,13 +488,13 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, bool quoted = FALSE; time_t maxage = 24 * 3600; /* default is 24 hours */ bool persist = FALSE; - p++; - if(*p != ':') { - /* host name starts here */ - const char *hostp = p; - while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-'))) - p++; - len = p - hostp; + p++; + if(*p != ':') { + /* host name starts here */ + const char *hostp = p; + while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-'))) + p++; + len = p - hostp; if(!len || (len >= MAX_ALTSVC_HOSTLEN)) { infof(data, "Excessive alt-svc host name, ignoring...\n"); dstalpnid = ALPN_none; @@ -504,22 +504,22 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, namebuf[len] = 0; dsthost = namebuf; } - } - else { - /* no destination name, use source host */ - dsthost = srchost; - } - if(*p == ':') { - /* a port number */ - unsigned long port = strtoul(++p, &end_ptr, 10); - if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') { - infof(data, "Unknown alt-svc port number, ignoring...\n"); + } + else { + /* no destination name, use source host */ + dsthost = srchost; + } + if(*p == ':') { + /* a port number */ + unsigned long port = strtoul(++p, &end_ptr, 10); + if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') { + infof(data, "Unknown alt-svc port number, ignoring...\n"); dstalpnid = ALPN_none; - } - p = end_ptr; - dstport = curlx_ultous(port); - } - if(*p++ != '\"') + } + p = end_ptr; + dstport = curlx_ultous(port); + } + if(*p++ != '\"') break; /* Handle the optional 'ma' and 'persist' flags. Unknown flags are skipped. */ @@ -568,7 +568,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, else if(strcasecompare("persist", option) && (num == 1)) persist = TRUE; } - } + } if(dstalpnid) { as = altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid, @@ -587,61 +587,61 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, infof(data, "Unknown alt-svc protocol \"%s\", skipping...\n", alpnbuf); } - } + } else break; - /* after the double quote there can be a comma if there's another - string or a semicolon if no more */ - if(*p == ',') { - /* comma means another alternative is presented */ - p++; - result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); - if(result) + /* after the double quote there can be a comma if there's another + string or a semicolon if no more */ + if(*p == ',') { + /* comma means another alternative is presented */ + p++; + result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); + if(result) break; - } - } + } + } else break; - } while(*p && (*p != ';') && (*p != '\n') && (*p != '\r')); - - return CURLE_OK; -} - -/* - * Return TRUE on a match - */ -bool Curl_altsvc_lookup(struct altsvcinfo *asi, - enum alpnid srcalpnid, const char *srchost, - int srcport, - struct altsvc **dstentry, - const int versions) /* one or more bits */ -{ + } while(*p && (*p != ';') && (*p != '\n') && (*p != '\r')); + + return CURLE_OK; +} + +/* + * Return TRUE on a match + */ +bool Curl_altsvc_lookup(struct altsvcinfo *asi, + enum alpnid srcalpnid, const char *srchost, + int srcport, + struct altsvc **dstentry, + const int versions) /* one or more bits */ +{ struct Curl_llist_element *e; struct Curl_llist_element *n; - time_t now = time(NULL); - DEBUGASSERT(asi); - DEBUGASSERT(srchost); - DEBUGASSERT(dstentry); - - for(e = asi->list.head; e; e = n) { - struct altsvc *as = e->ptr; - n = e->next; - if(as->expires < now) { - /* an expired entry, remove */ - Curl_llist_remove(&asi->list, e, NULL); - altsvc_free(as); - continue; - } - if((as->src.alpnid == srcalpnid) && - strcasecompare(as->src.host, srchost) && - (as->src.port == srcport) && - (versions & as->dst.alpnid)) { - /* match */ - *dstentry = as; - return TRUE; - } - } - return FALSE; -} - + time_t now = time(NULL); + DEBUGASSERT(asi); + DEBUGASSERT(srchost); + DEBUGASSERT(dstentry); + + for(e = asi->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + if(as->expires < now) { + /* an expired entry, remove */ + Curl_llist_remove(&asi->list, e, NULL); + altsvc_free(as); + continue; + } + if((as->src.alpnid == srcalpnid) && + strcasecompare(as->src.host, srchost) && + (as->src.port == srcport) && + (versions & as->dst.alpnid)) { + /* match */ + *dstentry = as; + return TRUE; + } + } + return FALSE; +} + #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */ diff --git a/contrib/libs/curl/lib/altsvc.h b/contrib/libs/curl/lib/altsvc.h index 7de519f497..2ab89e7059 100644 --- a/contrib/libs/curl/lib/altsvc.h +++ b/contrib/libs/curl/lib/altsvc.h @@ -1,79 +1,79 @@ -#ifndef HEADER_CURL_ALTSVC_H -#define HEADER_CURL_ALTSVC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +#ifndef HEADER_CURL_ALTSVC_H +#define HEADER_CURL_ALTSVC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC) -#include <curl/curl.h> -#include "llist.h" - -enum alpnid { - ALPN_none = 0, - ALPN_h1 = CURLALTSVC_H1, - ALPN_h2 = CURLALTSVC_H2, - ALPN_h3 = CURLALTSVC_H3 -}; - -struct althost { - char *host; - unsigned short port; - enum alpnid alpnid; -}; - -struct altsvc { - struct althost src; - struct althost dst; - time_t expires; - bool persist; - int prio; +#include <curl/curl.h> +#include "llist.h" + +enum alpnid { + ALPN_none = 0, + ALPN_h1 = CURLALTSVC_H1, + ALPN_h2 = CURLALTSVC_H2, + ALPN_h3 = CURLALTSVC_H3 +}; + +struct althost { + char *host; + unsigned short port; + enum alpnid alpnid; +}; + +struct altsvc { + struct althost src; + struct althost dst; + time_t expires; + bool persist; + int prio; struct Curl_llist_element node; -}; - -struct altsvcinfo { - char *filename; +}; + +struct altsvcinfo { + char *filename; struct Curl_llist list; /* list of entries */ - long flags; /* the publicly set bitmask */ -}; - -const char *Curl_alpnid2str(enum alpnid id); -struct altsvcinfo *Curl_altsvc_init(void); -CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file); + long flags; /* the publicly set bitmask */ +}; + +const char *Curl_alpnid2str(enum alpnid id); +struct altsvcinfo *Curl_altsvc_init(void); +CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file); CURLcode Curl_altsvc_save(struct Curl_easy *data, struct altsvcinfo *asi, const char *file); -CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl); +CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl); void Curl_altsvc_cleanup(struct altsvcinfo **altsvc); -CURLcode Curl_altsvc_parse(struct Curl_easy *data, - struct altsvcinfo *altsvc, const char *value, - enum alpnid srcalpn, const char *srchost, - unsigned short srcport); -bool Curl_altsvc_lookup(struct altsvcinfo *asi, - enum alpnid srcalpnid, const char *srchost, - int srcport, - struct altsvc **dstentry, +CURLcode Curl_altsvc_parse(struct Curl_easy *data, + struct altsvcinfo *altsvc, const char *value, + enum alpnid srcalpn, const char *srchost, + unsigned short srcport); +bool Curl_altsvc_lookup(struct altsvcinfo *asi, + enum alpnid srcalpnid, const char *srchost, + int srcport, + struct altsvc **dstentry, const int versions); /* CURLALTSVC_H* bits */ -#else -/* disabled */ +#else +/* disabled */ #define Curl_altsvc_save(a,b,c) #define Curl_altsvc_cleanup(x) #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */ -#endif /* HEADER_CURL_ALTSVC_H */ +#endif /* HEADER_CURL_ALTSVC_H */ diff --git a/contrib/libs/curl/lib/amigaos.c b/contrib/libs/curl/lib/amigaos.c index d7f7dc70dc..d3b00d9083 100644 --- a/contrib/libs/curl/lib/amigaos.c +++ b/contrib/libs/curl/lib/amigaos.c @@ -22,22 +22,22 @@ #include "curl_setup.h" -#ifdef __AMIGA__ -# include "amigaos.h" -# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) -# include <amitcp/socketbasetags.h> -# endif -# ifdef __libnix__ -# include <stabs.h> -# endif -#endif +#ifdef __AMIGA__ +# include "amigaos.h" +# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) +# include <amitcp/socketbasetags.h> +# endif +# ifdef __libnix__ +# include <stabs.h> +# endif +#endif -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" -#ifdef __AMIGA__ -#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) +#ifdef __AMIGA__ +#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) struct Library *SocketBase = NULL; extern int errno, h_errno; @@ -83,13 +83,13 @@ bool Curl_amiga_init() ADD2EXIT(Curl_amiga_cleanup, -50); #endif -#endif /* HAVE_PROTO_BSDSOCKET_H */ - -#ifdef USE_AMISSL -void Curl_amiga_X509_free(X509 *a) -{ - X509_free(a); -} -#endif /* USE_AMISSL */ -#endif /* __AMIGA__ */ - +#endif /* HAVE_PROTO_BSDSOCKET_H */ + +#ifdef USE_AMISSL +void Curl_amiga_X509_free(X509 *a) +{ + X509_free(a); +} +#endif /* USE_AMISSL */ +#endif /* __AMIGA__ */ + diff --git a/contrib/libs/curl/lib/amigaos.h b/contrib/libs/curl/lib/amigaos.h index 8f6db617c2..02e5bb546a 100644 --- a/contrib/libs/curl/lib/amigaos.h +++ b/contrib/libs/curl/lib/amigaos.h @@ -23,7 +23,7 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL) +#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL) bool Curl_amiga_init(); void Curl_amiga_cleanup(); @@ -35,10 +35,10 @@ void Curl_amiga_cleanup(); #endif -#ifdef USE_AMISSL -#include <openssl/x509v3.h> -void Curl_amiga_X509_free(X509 *a); -#endif /* USE_AMISSL */ - +#ifdef USE_AMISSL +#include <openssl/x509v3.h> +void Curl_amiga_X509_free(X509 *a); +#endif /* USE_AMISSL */ + #endif /* HEADER_CURL_AMIGAOS_H */ - + diff --git a/contrib/libs/curl/lib/asyn-ares.c b/contrib/libs/curl/lib/asyn-ares.c index 6c9d3ff5bf..1747571889 100644 --- a/contrib/libs/curl/lib/asyn-ares.c +++ b/contrib/libs/curl/lib/asyn-ares.c @@ -90,20 +90,20 @@ struct thread_data { struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */ int last_status; - struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */ + struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */ }; -/* How long we are willing to wait for additional parallel responses after - obtaining a "definitive" one. - - This is intended to equal the c-ares default timeout. cURL always uses that - default value. Unfortunately, c-ares doesn't expose its default timeout in - its API, but it is officially documented as 5 seconds. - - See query_completed_cb() for an explanation of how this is used. - */ -#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000 - +/* How long we are willing to wait for additional parallel responses after + obtaining a "definitive" one. + + This is intended to equal the c-ares default timeout. cURL always uses that + default value. Unfortunately, c-ares doesn't expose its default timeout in + its API, but it is officially documented as 5 seconds. + + See query_completed_cb() for an explanation of how this is used. + */ +#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000 + /* * Curl_resolver_global_init() - the generic low-level asynchronous name * resolve API. Called from curl_global_init() to initialize global resolver @@ -212,17 +212,17 @@ void Curl_resolver_cancel(struct connectdata *conn) } /* - * We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We - * never block. - */ -void Curl_resolver_kill(struct connectdata *conn) -{ - /* We don't need to check the resolver state because we can be called safely - at any time and we always do the same thing. */ - Curl_resolver_cancel(conn); -} - -/* + * We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We + * never block. + */ +void Curl_resolver_kill(struct connectdata *conn) +{ + /* We don't need to check the resolver state because we can be called safely + at any time and we always do the same thing. */ + Curl_resolver_cancel(conn); +} + +/* * destroy_async_data() cleans up async resolver data. */ static void destroy_async_data(struct Curl_async *async) @@ -254,14 +254,14 @@ static void destroy_async_data(struct Curl_async *async) */ int Curl_resolver_getsock(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { struct timeval maxtime; struct timeval timebuf; struct timeval *timeout; long milli; int max = ares_getsock((ares_channel)conn->data->state.resolver, - (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE); + (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE); maxtime.tv_sec = CURL_TIMEOUT_RESOLVE; maxtime.tv_usec = 0; @@ -330,9 +330,9 @@ static int waitperform(struct connectdata *conn, timediff_t timeout_ms) /* move through the descriptors and ask for processing on them */ for(i = 0; i < num; i++) ares_process_fd((ares_channel)data->state.resolver, - (pfd[i].revents & (POLLRDNORM|POLLIN))? + (pfd[i].revents & (POLLRDNORM|POLLIN))? pfd[i].fd:ARES_SOCKET_BAD, - (pfd[i].revents & (POLLWRNORM|POLLOUT))? + (pfd[i].revents & (POLLWRNORM|POLLOUT))? pfd[i].fd:ARES_SOCKET_BAD); } return nfds; @@ -357,29 +357,29 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn, waitperform(conn, 0); - /* Now that we've checked for any last minute results above, see if there are - any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer - expires. */ - if(res - && res->num_pending - /* This is only set to non-zero if the timer was started. */ - && (res->happy_eyeballs_dns_time.tv_sec - || res->happy_eyeballs_dns_time.tv_usec) - && (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time) - >= HAPPY_EYEBALLS_DNS_TIMEOUT)) { - /* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer - running. */ - memset( - &res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time)); - - /* Cancel the raw c-ares request, which will fire query_completed_cb() with - ARES_ECANCELLED synchronously for all pending responses. This will - leave us with res->num_pending == 0, which is perfect for the next - block. */ - ares_cancel((ares_channel)data->state.resolver); - DEBUGASSERT(res->num_pending == 0); - } - + /* Now that we've checked for any last minute results above, see if there are + any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer + expires. */ + if(res + && res->num_pending + /* This is only set to non-zero if the timer was started. */ + && (res->happy_eyeballs_dns_time.tv_sec + || res->happy_eyeballs_dns_time.tv_usec) + && (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time) + >= HAPPY_EYEBALLS_DNS_TIMEOUT)) { + /* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer + running. */ + memset( + &res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time)); + + /* Cancel the raw c-ares request, which will fire query_completed_cb() with + ARES_ECANCELLED synchronously for all pending responses. This will + leave us with res->num_pending == 0, which is perfect for the next + block. */ + ares_cancel((ares_channel)data->state.resolver); + DEBUGASSERT(res->num_pending == 0); + } + if(res && !res->num_pending) { (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai); /* temp_ai ownership is moved to the connection, so we need not free-up @@ -404,13 +404,13 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn, /* * Curl_resolver_wait_resolv() * - * Waits for a resolve to finish. This function should be avoided since using + * Waits for a resolve to finish. This function should be avoided since using * this risk getting the multi interface to "hang". * * 'entry' MUST be non-NULL. * - * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, - * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. + * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, + * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. */ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, struct Curl_dns_entry **entry) @@ -490,7 +490,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, if(result) /* close the connection, since we can't return failure here without - cleaning up this connection properly. */ + cleaning up this connection properly. */ connclose(conn, "c-ares resolve failed"); return result; @@ -550,66 +550,66 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */ /* A successful result overwrites any previous error */ if(res->last_status != ARES_SUCCESS) res->last_status = status; - - /* If there are responses still pending, we presume they must be the - complementary IPv4 or IPv6 lookups that we started in parallel in - Curl_resolver_getaddrinfo() (for Happy Eyeballs). If we've got a - "definitive" response from one of a set of parallel queries, we need to - think about how long we're willing to wait for more responses. */ - if(res->num_pending - /* Only these c-ares status values count as "definitive" for these - purposes. For example, ARES_ENODATA is what we expect when there is - no IPv6 entry for a domain name, and that's not a reason to get more - aggressive in our timeouts for the other response. Other errors are - either a result of bad input (which should affect all parallel - requests), local or network conditions, non-definitive server - responses, or us cancelling the request. */ - && (status == ARES_SUCCESS || status == ARES_ENOTFOUND)) { - /* Right now, there can only be up to two parallel queries, so don't - bother handling any other cases. */ - DEBUGASSERT(res->num_pending == 1); - - /* It's possible that one of these parallel queries could succeed - quickly, but the other could always fail or timeout (when we're - talking to a pool of DNS servers that can only successfully resolve - IPv4 address, for example). - - It's also possible that the other request could always just take - longer because it needs more time or only the second DNS server can - fulfill it successfully. But, to align with the philosophy of Happy - Eyeballs, we don't want to wait _too_ long or users will think - requests are slow when IPv6 lookups don't actually work (but IPv4 ones - do). - - So, now that we have a usable answer (some IPv4 addresses, some IPv6 - addresses, or "no such domain"), we start a timeout for the remaining - pending responses. Even though it is typical that this resolved - request came back quickly, that needn't be the case. It might be that - this completing request didn't get a result from the first DNS server - or even the first round of the whole DNS server pool. So it could - already be quite some time after we issued the DNS queries in the - first place. Without modifying c-ares, we can't know exactly where in - its retry cycle we are. We could guess based on how much time has - gone by, but it doesn't really matter. Happy Eyeballs tells us that, - given usable information in hand, we simply don't want to wait "too - much longer" after we get a result. - - We simply wait an additional amount of time equal to the default - c-ares query timeout. That is enough time for a typical parallel - response to arrive without being "too long". Even on a network - where one of the two types of queries is failing or timing out - constantly, this will usually mean we wait a total of the default - c-ares timeout (5 seconds) plus the round trip time for the successful - request, which seems bearable. The downside is that c-ares might race - with us to issue one more retry just before we give up, but it seems - better to "waste" that request instead of trying to guess the perfect - timeout to prevent it. After all, we don't even know where in the - c-ares retry cycle each request is. - */ - res->happy_eyeballs_dns_time = Curl_now(); - Curl_expire( - conn->data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS); - } + + /* If there are responses still pending, we presume they must be the + complementary IPv4 or IPv6 lookups that we started in parallel in + Curl_resolver_getaddrinfo() (for Happy Eyeballs). If we've got a + "definitive" response from one of a set of parallel queries, we need to + think about how long we're willing to wait for more responses. */ + if(res->num_pending + /* Only these c-ares status values count as "definitive" for these + purposes. For example, ARES_ENODATA is what we expect when there is + no IPv6 entry for a domain name, and that's not a reason to get more + aggressive in our timeouts for the other response. Other errors are + either a result of bad input (which should affect all parallel + requests), local or network conditions, non-definitive server + responses, or us cancelling the request. */ + && (status == ARES_SUCCESS || status == ARES_ENOTFOUND)) { + /* Right now, there can only be up to two parallel queries, so don't + bother handling any other cases. */ + DEBUGASSERT(res->num_pending == 1); + + /* It's possible that one of these parallel queries could succeed + quickly, but the other could always fail or timeout (when we're + talking to a pool of DNS servers that can only successfully resolve + IPv4 address, for example). + + It's also possible that the other request could always just take + longer because it needs more time or only the second DNS server can + fulfill it successfully. But, to align with the philosophy of Happy + Eyeballs, we don't want to wait _too_ long or users will think + requests are slow when IPv6 lookups don't actually work (but IPv4 ones + do). + + So, now that we have a usable answer (some IPv4 addresses, some IPv6 + addresses, or "no such domain"), we start a timeout for the remaining + pending responses. Even though it is typical that this resolved + request came back quickly, that needn't be the case. It might be that + this completing request didn't get a result from the first DNS server + or even the first round of the whole DNS server pool. So it could + already be quite some time after we issued the DNS queries in the + first place. Without modifying c-ares, we can't know exactly where in + its retry cycle we are. We could guess based on how much time has + gone by, but it doesn't really matter. Happy Eyeballs tells us that, + given usable information in hand, we simply don't want to wait "too + much longer" after we get a result. + + We simply wait an additional amount of time equal to the default + c-ares query timeout. That is enough time for a typical parallel + response to arrive without being "too long". Even on a network + where one of the two types of queries is failing or timing out + constantly, this will usually mean we wait a total of the default + c-ares timeout (5 seconds) plus the round trip time for the successful + request, which seems bearable. The downside is that c-ares might race + with us to issue one more retry just before we give up, but it seems + better to "waste" that request instead of trying to guess the perfect + timeout to prevent it. After all, we don't even know where in the + c-ares retry cycle each request is. + */ + res->happy_eyeballs_dns_time = Curl_now(); + Curl_expire( + conn->data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS); + } } } @@ -719,11 +719,11 @@ CURLcode Curl_set_dns_servers(struct Curl_easy *data, return CURLE_OK; #if (ARES_VERSION >= 0x010704) -#if (ARES_VERSION >= 0x010b00) - ares_result = ares_set_servers_ports_csv(data->state.resolver, servers); -#else +#if (ARES_VERSION >= 0x010b00) + ares_result = ares_set_servers_ports_csv(data->state.resolver, servers); +#else ares_result = ares_set_servers_csv(data->state.resolver, servers); -#endif +#endif switch(ares_result) { case ARES_SUCCESS: result = CURLE_OK; diff --git a/contrib/libs/curl/lib/asyn-thread.c b/contrib/libs/curl/lib/asyn-thread.c index f3d9fa11a7..c49878bb55 100644 --- a/contrib/libs/curl/lib/asyn-thread.c +++ b/contrib/libs/curl/lib/asyn-thread.c @@ -216,9 +216,9 @@ struct thread_sync_data { duplicate */ int port; #ifdef USE_SOCKETPAIR - struct connectdata *conn; - curl_socket_t sock_pair[2]; /* socket pair */ -#endif + struct connectdata *conn; + curl_socket_t sock_pair[2]; /* socket pair */ +#endif int sock_error; struct Curl_addrinfo *res; #ifdef HAVE_GETADDRINFO @@ -256,14 +256,14 @@ void destroy_thread_sync_data(struct thread_sync_data *tsd) Curl_freeaddrinfo(tsd->res); #ifdef USE_SOCKETPAIR - /* - * close one end of the socket pair (may be done in resolver thread); - * the other end (for reading) is always closed in the parent thread. - */ - if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { - sclose(tsd->sock_pair[1]); - } -#endif + /* + * close one end of the socket pair (may be done in resolver thread); + * the other end (for reading) is always closed in the parent thread. + */ + if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { + sclose(tsd->sock_pair[1]); + } +#endif memset(tsd, 0, sizeof(*tsd)); } @@ -304,11 +304,11 @@ int init_thread_sync_data(struct thread_data *td, #ifdef USE_SOCKETPAIR /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */ if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { - tsd->sock_pair[0] = CURL_SOCKET_BAD; - tsd->sock_pair[1] = CURL_SOCKET_BAD; - goto err_exit; - } -#endif + tsd->sock_pair[0] = CURL_SOCKET_BAD; + tsd->sock_pair[1] = CURL_SOCKET_BAD; + goto err_exit; + } +#endif tsd->sock_error = CURL_ASYNC_SUCCESS; /* Copying hostname string because original can be destroyed by parent @@ -357,8 +357,8 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) char service[12]; int rc; #ifdef USE_SOCKETPAIR - char buf[1]; -#endif + char buf[1]; +#endif msnprintf(service, sizeof(service), "%d", tsd->port); @@ -383,15 +383,15 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) } else { #ifdef USE_SOCKETPAIR - if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { - /* DNS has been resolved, signal client task */ - buf[0] = 1; + if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { + /* DNS has been resolved, signal client task */ + buf[0] = 1; if(swrite(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { - /* update sock_erro to errno */ - tsd->sock_error = SOCKERRNO; - } - } -#endif + /* update sock_erro to errno */ + tsd->sock_error = SOCKERRNO; + } + } +#endif tsd->done = 1; Curl_mutex_release(tsd->mtx); } @@ -451,9 +451,9 @@ static void destroy_async_data(struct Curl_async *async) struct thread_data *td = async->tdata; int done; #ifdef USE_SOCKETPAIR - curl_socket_t sock_rd = td->tsd.sock_pair[0]; - struct connectdata *conn = td->tsd.conn; -#endif + curl_socket_t sock_rd = td->tsd.sock_pair[0]; + struct connectdata *conn = td->tsd.conn; +#endif /* We can't wait any longer for the resolver thread so if it's not done * then it must be orphaned. @@ -511,14 +511,14 @@ static void destroy_async_data(struct Curl_async *async) free(td); } #ifdef USE_SOCKETPAIR - /* - * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE - * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL - */ - if(conn) - Curl_multi_closed(conn->data, sock_rd); - sclose(sock_rd); -#endif + /* + * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE + * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL + */ + if(conn) + Curl_multi_closed(conn->data, sock_rd); + sclose(sock_rd); +#endif } async->tdata = NULL; @@ -619,15 +619,15 @@ static CURLcode resolver_error(struct connectdata *conn) /* * 'entry' may be NULL and then no data is returned */ -static CURLcode thread_wait_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry, - bool report) +static CURLcode thread_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry, + bool report) { struct thread_data *td = conn->async.tdata; CURLcode result = CURLE_OK; DEBUGASSERT(conn && td); - DEBUGASSERT(td->thread_hnd != curl_thread_t_null); + DEBUGASSERT(td->thread_hnd != curl_thread_t_null); /* wait for the thread to resolve the name */ if(Curl_thread_join(&td->thread_hnd)) { @@ -642,56 +642,56 @@ static CURLcode thread_wait_resolv(struct connectdata *conn, if(entry) *entry = conn->async.dns; - if(!conn->async.dns && report) + if(!conn->async.dns && report) /* a name was not resolved, report error */ result = resolver_error(conn); destroy_async_data(&conn->async); - if(!conn->async.dns && report) + if(!conn->async.dns && report) connclose(conn, "asynch resolve failed"); return result; } - + /* - * Until we gain a way to signal the resolver threads to stop early, we must - * simply wait for them and ignore their results. - */ -void Curl_resolver_kill(struct connectdata *conn) -{ + * Until we gain a way to signal the resolver threads to stop early, we must + * simply wait for them and ignore their results. + */ +void Curl_resolver_kill(struct connectdata *conn) +{ struct thread_data *td = conn->async.tdata; - - /* If we're still resolving, we must wait for the threads to fully clean up, - unfortunately. Otherwise, we can simply cancel to clean up any resolver - data. */ - if(td && td->thread_hnd != curl_thread_t_null) - (void)thread_wait_resolv(conn, NULL, FALSE); - else - Curl_resolver_cancel(conn); -} - -/* - * Curl_resolver_wait_resolv() - * - * Waits for a resolve to finish. This function should be avoided since using - * this risk getting the multi interface to "hang". - * - * If 'entry' is non-NULL, make it point to the resolved dns entry - * - * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, - * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. - * - * This is the version for resolves-in-a-thread. - */ -CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - return thread_wait_resolv(conn, entry, TRUE); -} - -/* + + /* If we're still resolving, we must wait for the threads to fully clean up, + unfortunately. Otherwise, we can simply cancel to clean up any resolver + data. */ + if(td && td->thread_hnd != curl_thread_t_null) + (void)thread_wait_resolv(conn, NULL, FALSE); + else + Curl_resolver_cancel(conn); +} + +/* + * Curl_resolver_wait_resolv() + * + * Waits for a resolve to finish. This function should be avoided since using + * this risk getting the multi interface to "hang". + * + * If 'entry' is non-NULL, make it point to the resolved dns entry + * + * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, + * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. + * + * This is the version for resolves-in-a-thread. + */ +CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry) +{ + return thread_wait_resolv(conn, entry, TRUE); +} + +/* * Curl_resolver_is_resolved() is called repeatedly to check if a previous * name resolve request has completed. It should also make sure to time-out if * the operation seems to take too long. @@ -728,7 +728,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn, } else { /* poll for name lookup done with exponential backoff up to 250ms */ - /* should be fine even if this converts to 32 bit */ + /* should be fine even if this converts to 32 bit */ timediff_t elapsed = Curl_timediff(Curl_now(), data->progress.t_startsingle); if(elapsed < 0) @@ -752,45 +752,45 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn, } int Curl_resolver_getsock(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { - int ret_val = 0; + int ret_val = 0; timediff_t milli; timediff_t ms; struct Curl_easy *data = conn->data; struct resdata *reslv = (struct resdata *)data->state.resolver; #ifdef USE_SOCKETPAIR struct thread_data *td = conn->async.tdata; -#else +#else (void)socks; -#endif - +#endif + #ifdef USE_SOCKETPAIR - if(td) { - /* return read fd to client for polling the DNS resolution status */ - socks[0] = td->tsd.sock_pair[0]; - DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn); - td->tsd.conn = conn; - ret_val = GETSOCK_READSOCK(0); - } - else { -#endif - ms = Curl_timediff(Curl_now(), reslv->start); - if(ms < 3) - milli = 0; - else if(ms <= 50) + if(td) { + /* return read fd to client for polling the DNS resolution status */ + socks[0] = td->tsd.sock_pair[0]; + DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn); + td->tsd.conn = conn; + ret_val = GETSOCK_READSOCK(0); + } + else { +#endif + ms = Curl_timediff(Curl_now(), reslv->start); + if(ms < 3) + milli = 0; + else if(ms <= 50) milli = ms/3; - else if(ms <= 250) - milli = 50; - else - milli = 200; - Curl_expire(data, milli, EXPIRE_ASYNC_NAME); + else if(ms <= 250) + milli = 50; + else + milli = 200; + Curl_expire(data, milli, EXPIRE_ASYNC_NAME); #ifdef USE_SOCKETPAIR - } -#endif - - - return ret_val; + } +#endif + + + return ret_val; } #ifndef HAVE_GETADDRINFO @@ -860,8 +860,8 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, memset(&hints, 0, sizeof(hints)); hints.ai_family = pf; - hints.ai_socktype = (conn->transport == TRNSPRT_TCP)? - SOCK_STREAM : SOCK_DGRAM; + hints.ai_socktype = (conn->transport == TRNSPRT_TCP)? + SOCK_STREAM : SOCK_DGRAM; reslv->start = Curl_now(); /* fire up a new resolver thread! */ diff --git a/contrib/libs/curl/lib/asyn.h b/contrib/libs/curl/lib/asyn.h index d252534e78..73a9b7268f 100644 --- a/contrib/libs/curl/lib/asyn.h +++ b/contrib/libs/curl/lib/asyn.h @@ -87,25 +87,25 @@ CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, * * It is called from inside other functions to cancel currently performing * resolver request. Should also free any temporary resources allocated to - * perform a request. This never waits for resolver threads to complete. - * - * It is safe to call this when conn is in any state. + * perform a request. This never waits for resolver threads to complete. + * + * It is safe to call this when conn is in any state. */ void Curl_resolver_cancel(struct connectdata *conn); -/* - * Curl_resolver_kill(). - * - * This acts like Curl_resolver_cancel() except it will block until any threads - * associated with the resolver are complete. This never blocks for resolvers - * that do not use threads. This is intended to be the "last chance" function - * that cleans up an in-progress resolver completely (before its owner is about - * to die). - * - * It is safe to call this when conn is in any state. - */ -void Curl_resolver_kill(struct connectdata *conn); - +/* + * Curl_resolver_kill(). + * + * This acts like Curl_resolver_cancel() except it will block until any threads + * associated with the resolver are complete. This never blocks for resolvers + * that do not use threads. This is intended to be the "last chance" function + * that cleans up an in-progress resolver completely (before its owner is about + * to die). + * + * It is safe to call this when conn is in any state. + */ +void Curl_resolver_kill(struct connectdata *conn); + /* Curl_resolver_getsock() * * This function is called from the multi_getsock() function. 'sock' is a @@ -114,7 +114,7 @@ void Curl_resolver_kill(struct connectdata *conn); * return bitmask indicating what file descriptors (referring to array indexes * in the 'sock' array) to wait for, read/write. */ -int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock); +int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock); /* * Curl_resolver_is_resolved() @@ -131,13 +131,13 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn, /* * Curl_resolver_wait_resolv() * - * Waits for a resolve to finish. This function should be avoided since using + * Waits for a resolve to finish. This function should be avoided since using * this risk getting the multi interface to "hang". * * If 'entry' is non-NULL, make it point to the resolved dns entry * - * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, - * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. + * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, + * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. */ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, struct Curl_dns_entry **dnsentry); @@ -161,7 +161,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, #ifndef CURLRES_ASYNCH /* convert these functions if an asynch resolver isn't used */ #define Curl_resolver_cancel(x) Curl_nop_stmt -#define Curl_resolver_kill(x) Curl_nop_stmt +#define Curl_resolver_kill(x) Curl_nop_stmt #define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST #define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST #define Curl_resolver_duphandle(x,y,z) CURLE_OK diff --git a/contrib/libs/curl/lib/base64.c b/contrib/libs/curl/lib/base64.c index a5875f3fd7..be6f163dc4 100644 --- a/contrib/libs/curl/lib/base64.c +++ b/contrib/libs/curl/lib/base64.c @@ -23,14 +23,14 @@ /* Base64 encoding/decoding */ #include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \ - !defined(CURL_DISABLE_LDAP) || \ + +#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \ + !defined(CURL_DISABLE_LDAP) || \ !defined(CURL_DISABLE_SMTP) || \ !defined(CURL_DISABLE_POP3) || \ !defined(CURL_DISABLE_IMAP) || \ - !defined(CURL_DISABLE_DOH) || defined(USE_SSL) - + !defined(CURL_DISABLE_DOH) || defined(USE_SSL) + #include "urldata.h" /* for the Curl_easy definition */ #include "warnless.h" #include "curl_base64.h" @@ -325,5 +325,5 @@ CURLcode Curl_base64url_encode(struct Curl_easy *data, { return base64_encode(base64url, data, inputbuff, insize, outptr, outlen); } - -#endif /* no users so disabled */ + +#endif /* no users so disabled */ diff --git a/contrib/libs/curl/lib/config-os400.h b/contrib/libs/curl/lib/config-os400.h index 401cc6b4ec..b8676113d7 100644 --- a/contrib/libs/curl/lib/config-os400.h +++ b/contrib/libs/curl/lib/config-os400.h @@ -124,18 +124,18 @@ /* Define if you have the `getpass_r' function. */ #undef HAVE_GETPASS_R -/* Define to 1 if you have the getpeername function. */ -#define HAVE_GETPEERNAME 1 - +/* Define to 1 if you have the getpeername function. */ +#define HAVE_GETPEERNAME 1 + /* Define if you have the `getpwuid' function. */ #define HAVE_GETPWUID /* Define if you have the `getservbyname' function. */ #define HAVE_GETSERVBYNAME -/* Define to 1 if you have the getsockname function. */ -#define HAVE_GETSOCKNAME 1 - +/* Define to 1 if you have the getsockname function. */ +#define HAVE_GETSOCKNAME 1 + /* Define if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY @@ -422,9 +422,9 @@ /* Define if you can safely include both <sys/time.h> and <time.h>. */ #define TIME_WITH_SYS_TIME -/* Define to enable HTTP3 support (experimental, requires NGTCP2 or QUICHE) */ -#undef ENABLE_QUIC - +/* Define to enable HTTP3 support (experimental, requires NGTCP2 or QUICHE) */ +#undef ENABLE_QUIC + /* Version number of package */ #undef VERSION diff --git a/contrib/libs/curl/lib/config-plan9.h b/contrib/libs/curl/lib/config-plan9.h index bfdba1b12c..cc8adde725 100644 --- a/contrib/libs/curl/lib/config-plan9.h +++ b/contrib/libs/curl/lib/config-plan9.h @@ -1,214 +1,214 @@ -#ifndef HEADER_CURL_CONFIG_PLAN9_H -#define HEADER_CURL_CONFIG_PLAN9_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +#ifndef HEADER_CURL_CONFIG_PLAN9_H +#define HEADER_CURL_CONFIG_PLAN9_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#define BUILDING_LIBCURL 1 -#define CURL_CA_BUNDLE "/sys/lib/tls/ca.pem" -#define CURL_CA_PATH "/sys/lib/tls" -#define CURL_STATICLIB 1 -#define ENABLE_IPV6 1 -#define CURL_DISABLE_LDAP 1 - -#define NEED_REENTRANT 1 -#define OS "plan9" -#define PACKAGE "curl" -#define PACKAGE_NAME "curl" + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#define BUILDING_LIBCURL 1 +#define CURL_CA_BUNDLE "/sys/lib/tls/ca.pem" +#define CURL_CA_PATH "/sys/lib/tls" +#define CURL_STATICLIB 1 +#define ENABLE_IPV6 1 +#define CURL_DISABLE_LDAP 1 + +#define NEED_REENTRANT 1 +#define OS "plan9" +#define PACKAGE "curl" +#define PACKAGE_NAME "curl" #define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.se/mail/" -#define PACKAGE_STRING "curl -" -#define PACKAGE_TARNAME "curl" -#define PACKAGE_VERSION "-" -#define RANDOM_FILE "/dev/random" -#define VERSION "0.0.0" /* TODO */ - -#define RETSIGTYPE void - -#define STDC_HEADERS 1 - -#ifdef _BITS64 -#error not implement -#else -#define SIZEOF_INT 4 -#define SIZEOF_SHORT 2 -#define SIZEOF_LONG 4 -#define SIZEOF_OFF_T 8 -#define SIZEOF_CURL_OFF_T 4 /* curl_off_t = timediff_t = int */ -#define SIZEOF_SIZE_T 4 -#define SIZEOF_TIME_T 4 -#endif - -#define HAVE_GETNAMEINFO 1 -#define GETNAMEINFO_QUAL_ARG1 const -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * -#define GETNAMEINFO_TYPE_ARG2 int -#define GETNAMEINFO_TYPE_ARG46 long -#define GETNAMEINFO_TYPE_ARG7 int - -#define HAVE_RECV 1 -#define RECV_TYPE_ARG1 int -#define RECV_TYPE_ARG2 void * -#define RECV_TYPE_ARG3 int -#define RECV_TYPE_ARG4 int -#define RECV_TYPE_RETV int - -#define HAVE_RECVFROM 1 -#define RECVFROM_TYPE_ARG1 int -#define RECVFROM_TYPE_ARG2 void -#define RECVFROM_TYPE_ARG2_IS_VOID 1 -#define RECVFROM_TYPE_ARG3 int -#define RECVFROM_TYPE_ARG4 int -#define RECVFROM_TYPE_ARG5 void -#define RECVFROM_TYPE_ARG5_IS_VOID 1 -#define RECVFROM_TYPE_ARG6 int -#define RECVFROM_TYPE_ARG6_IS_VOID 1 -#define RECVFROM_TYPE_RETV int - -#define HAVE_SELECT 1 -#define SELECT_TYPE_ARG1 int -#define SELECT_TYPE_ARG234 fd_set * -#define SELECT_TYPE_ARG5 struct timeval * -#define SELECT_TYPE_RETV int - -#define HAVE_SEND 1 -#define SEND_TYPE_ARG1 int -#define SEND_TYPE_ARG2 void * -#define SEND_QUAL_ARG2 -#define SEND_TYPE_ARG3 int -#define SEND_TYPE_ARG4 int -#define SEND_TYPE_RETV int - -#define HAVE_ALARM 1 -#define HAVE_ARPA_INET_H 1 -#define HAVE_ASSERT_H 1 -#define HAVE_BASENAME 1 -#define HAVE_BOOL_T 1 -#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 -#define HAVE_ERRNO_H 1 -#define HAVE_FCNTL 1 -#define HAVE_FCNTL_H 1 -#define HAVE_FDOPEN 1 -#define HAVE_FORK 1 -#define HAVE_FREEADDRINFO 1 -#define HAVE_FTRUNCATE 1 -#define HAVE_GETADDRINFO 1 -#define HAVE_GETEUID 1 -#define HAVE_GETHOSTBYADDR 1 -#define HAVE_GETHOSTBYNAME 1 -#define HAVE_GETHOSTNAME 1 -#define HAVE_GETPPID 1 -#define HAVE_GETPROTOBYNAME 1 -#define HAVE_GETPWUID 1 -#define HAVE_GETTIMEOFDAY 1 -#define HAVE_GMTIME_R 1 -#define HAVE_INET_ADDR 1 -#define HAVE_INET_NTOP 1 -#define HAVE_INET_PTON 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_IOCTL 1 -#define HAVE_LIBGEN_H 1 -#define HAVE_LIBZ 1 -#define HAVE_LL 1 -#define HAVE_LOCALE_H 1 -#define HAVE_LOCALTIME_R 1 -#define HAVE_LONGLONG 1 -#define HAVE_NETDB_H 1 -#define HAVE_NETINET_IN_H 1 -#define HAVE_NETINET_TCP_H 1 -#define HAVE_PWD_H 1 -#define HAVE_SYS_SELECT_H 1 - -#define USE_OPENSSL 1 -#define HAVE_OPENSSL_CRYPTO_H 1 -#define HAVE_OPENSSL_ERR_H 1 -#define HAVE_OPENSSL_PEM_H 1 -#define HAVE_OPENSSL_PKCS12_H 1 -#define HAVE_OPENSSL_RSA_H 1 -#define HAVE_OPENSSL_SSL_H 1 -#define HAVE_OPENSSL_X509_H 1 - -#define HAVE_PERROR 1 -#define HAVE_PIPE 1 -#define HAVE_POLL 1 -#define HAVE_POLL_FINE 1 -#define HAVE_POLL_H 1 -#define HAVE_PTHREAD_H 1 -#define HAVE_RAND_STATUS 1 -#define HAVE_SETJMP_H 1 -#define HAVE_SETLOCALE 1 - -#define HAVE_SETSOCKOPT 1 -#define HAVE_SOCK_OPTS 1 /* for /sys/include/ape/sys/socket.h */ - -#define HAVE_SIGACTION 1 -#define HAVE_SIGNAL 1 -#define HAVE_SIGNAL_H 1 -#define HAVE_SIGSETJMP 1 -#define HAVE_SIG_ATOMIC_T 1 -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 -#define HAVE_SOCKET 1 -#define HAVE_SSL_GET_SHUTDOWN 1 -#define HAVE_STDBOOL_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_STDIO_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRCASECMP 1 -#define HAVE_STRDUP 1 -#define HAVE_STRING_H 1 -#define HAVE_STRNCASECMP 1 -#define HAVE_STRSTR 1 -#define HAVE_STRTOK_R 1 -#define HAVE_STRTOLL 1 -#define HAVE_STRUCT_TIMEVAL 1 -#define HAVE_SYS_IOCTL_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_RESOURCE_H 1 -#define HAVE_SYS_SOCKET_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_SYS_UIO_H 1 -#define HAVE_SYS_UN_H 1 -#define HAVE_TERMIOS_H 1 -#define HAVE_TIME_H 1 -#define HAVE_UNAME 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UTIME 1 -#define HAVE_UTIME_H 1 -#define HAVE_WRITEV 1 - -#define HAVE_ZLIB_H 1 - -#define HAVE_POSIX_STRERROR_R 1 -#define HAVE_STRERROR_R 1 -#define STRERROR_R_TYPE_ARG3 int - -#define TIME_WITH_SYS_TIME 1 -#define USE_BLOCKING_SOCKETS 1 -#define USE_MANUAL 1 - -#define __attribute__(x) - -#ifndef __cplusplus -#undef inline -#endif - -#endif /* HEADER_CURL_CONFIG_PLAN9_H */ +#define PACKAGE_STRING "curl -" +#define PACKAGE_TARNAME "curl" +#define PACKAGE_VERSION "-" +#define RANDOM_FILE "/dev/random" +#define VERSION "0.0.0" /* TODO */ + +#define RETSIGTYPE void + +#define STDC_HEADERS 1 + +#ifdef _BITS64 +#error not implement +#else +#define SIZEOF_INT 4 +#define SIZEOF_SHORT 2 +#define SIZEOF_LONG 4 +#define SIZEOF_OFF_T 8 +#define SIZEOF_CURL_OFF_T 4 /* curl_off_t = timediff_t = int */ +#define SIZEOF_SIZE_T 4 +#define SIZEOF_TIME_T 4 +#endif + +#define HAVE_GETNAMEINFO 1 +#define GETNAMEINFO_QUAL_ARG1 const +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * +#define GETNAMEINFO_TYPE_ARG2 int +#define GETNAMEINFO_TYPE_ARG46 long +#define GETNAMEINFO_TYPE_ARG7 int + +#define HAVE_RECV 1 +#define RECV_TYPE_ARG1 int +#define RECV_TYPE_ARG2 void * +#define RECV_TYPE_ARG3 int +#define RECV_TYPE_ARG4 int +#define RECV_TYPE_RETV int + +#define HAVE_RECVFROM 1 +#define RECVFROM_TYPE_ARG1 int +#define RECVFROM_TYPE_ARG2 void +#define RECVFROM_TYPE_ARG2_IS_VOID 1 +#define RECVFROM_TYPE_ARG3 int +#define RECVFROM_TYPE_ARG4 int +#define RECVFROM_TYPE_ARG5 void +#define RECVFROM_TYPE_ARG5_IS_VOID 1 +#define RECVFROM_TYPE_ARG6 int +#define RECVFROM_TYPE_ARG6_IS_VOID 1 +#define RECVFROM_TYPE_RETV int + +#define HAVE_SELECT 1 +#define SELECT_TYPE_ARG1 int +#define SELECT_TYPE_ARG234 fd_set * +#define SELECT_TYPE_ARG5 struct timeval * +#define SELECT_TYPE_RETV int + +#define HAVE_SEND 1 +#define SEND_TYPE_ARG1 int +#define SEND_TYPE_ARG2 void * +#define SEND_QUAL_ARG2 +#define SEND_TYPE_ARG3 int +#define SEND_TYPE_ARG4 int +#define SEND_TYPE_RETV int + +#define HAVE_ALARM 1 +#define HAVE_ARPA_INET_H 1 +#define HAVE_ASSERT_H 1 +#define HAVE_BASENAME 1 +#define HAVE_BOOL_T 1 +#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 +#define HAVE_ERRNO_H 1 +#define HAVE_FCNTL 1 +#define HAVE_FCNTL_H 1 +#define HAVE_FDOPEN 1 +#define HAVE_FORK 1 +#define HAVE_FREEADDRINFO 1 +#define HAVE_FTRUNCATE 1 +#define HAVE_GETADDRINFO 1 +#define HAVE_GETEUID 1 +#define HAVE_GETHOSTBYADDR 1 +#define HAVE_GETHOSTBYNAME 1 +#define HAVE_GETHOSTNAME 1 +#define HAVE_GETPPID 1 +#define HAVE_GETPROTOBYNAME 1 +#define HAVE_GETPWUID 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_GMTIME_R 1 +#define HAVE_INET_ADDR 1 +#define HAVE_INET_NTOP 1 +#define HAVE_INET_PTON 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_IOCTL 1 +#define HAVE_LIBGEN_H 1 +#define HAVE_LIBZ 1 +#define HAVE_LL 1 +#define HAVE_LOCALE_H 1 +#define HAVE_LOCALTIME_R 1 +#define HAVE_LONGLONG 1 +#define HAVE_NETDB_H 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_NETINET_TCP_H 1 +#define HAVE_PWD_H 1 +#define HAVE_SYS_SELECT_H 1 + +#define USE_OPENSSL 1 +#define HAVE_OPENSSL_CRYPTO_H 1 +#define HAVE_OPENSSL_ERR_H 1 +#define HAVE_OPENSSL_PEM_H 1 +#define HAVE_OPENSSL_PKCS12_H 1 +#define HAVE_OPENSSL_RSA_H 1 +#define HAVE_OPENSSL_SSL_H 1 +#define HAVE_OPENSSL_X509_H 1 + +#define HAVE_PERROR 1 +#define HAVE_PIPE 1 +#define HAVE_POLL 1 +#define HAVE_POLL_FINE 1 +#define HAVE_POLL_H 1 +#define HAVE_PTHREAD_H 1 +#define HAVE_RAND_STATUS 1 +#define HAVE_SETJMP_H 1 +#define HAVE_SETLOCALE 1 + +#define HAVE_SETSOCKOPT 1 +#define HAVE_SOCK_OPTS 1 /* for /sys/include/ape/sys/socket.h */ + +#define HAVE_SIGACTION 1 +#define HAVE_SIGNAL 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_SIGSETJMP 1 +#define HAVE_SIG_ATOMIC_T 1 +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 +#define HAVE_SOCKET 1 +#define HAVE_SSL_GET_SHUTDOWN 1 +#define HAVE_STDBOOL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRDUP 1 +#define HAVE_STRING_H 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRUCT_TIMEVAL 1 +#define HAVE_SYS_IOCTL_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_RESOURCE_H 1 +#define HAVE_SYS_SOCKET_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_UIO_H 1 +#define HAVE_SYS_UN_H 1 +#define HAVE_TERMIOS_H 1 +#define HAVE_TIME_H 1 +#define HAVE_UNAME 1 +#define HAVE_UNISTD_H 1 +#define HAVE_UTIME 1 +#define HAVE_UTIME_H 1 +#define HAVE_WRITEV 1 + +#define HAVE_ZLIB_H 1 + +#define HAVE_POSIX_STRERROR_R 1 +#define HAVE_STRERROR_R 1 +#define STRERROR_R_TYPE_ARG3 int + +#define TIME_WITH_SYS_TIME 1 +#define USE_BLOCKING_SOCKETS 1 +#define USE_MANUAL 1 + +#define __attribute__(x) + +#ifndef __cplusplus +#undef inline +#endif + +#endif /* HEADER_CURL_CONFIG_PLAN9_H */ diff --git a/contrib/libs/curl/lib/config-win32.h b/contrib/libs/curl/lib/config-win32.h index 83adf61270..e3095576f8 100644 --- a/contrib/libs/curl/lib/config-win32.h +++ b/contrib/libs/curl/lib/config-win32.h @@ -185,12 +185,12 @@ /* Define if you have the ftruncate function. */ /* #define HAVE_FTRUNCATE 1 */ -/* Define to 1 if you have the `getpeername' function. */ -#define HAVE_GETPEERNAME 1 - -/* Define to 1 if you have the getsockname function. */ -#define HAVE_GETSOCKNAME 1 - +/* Define to 1 if you have the `getpeername' function. */ +#define HAVE_GETPEERNAME 1 + +/* Define to 1 if you have the getsockname function. */ +#define HAVE_GETSOCKNAME 1 + /* Define if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 @@ -585,9 +585,9 @@ Vista # endif #endif -/* Availability of freeaddrinfo, getaddrinfo, getnameinfo and if_nametoindex - functions is quite convoluted, compiler dependent and even build target - dependent. */ +/* Availability of freeaddrinfo, getaddrinfo, getnameinfo and if_nametoindex + functions is quite convoluted, compiler dependent and even build target + dependent. */ #if defined(HAVE_WS2TCPIP_H) # if defined(__POCC__) # define HAVE_FREEADDRINFO 1 @@ -723,7 +723,7 @@ Vista #include <ws2tcpip.h> #if !defined(__MINGW32__) || defined(LUP_SECURE) /* Define to use Unix sockets. */ -#define USE_UNIX_SOCKETS +#define USE_UNIX_SOCKETS #if !defined(UNIX_PATH_MAX) /* Replicating logic present in afunix.h of newer Windows 10 SDK versions */ # define UNIX_PATH_MAX 108 @@ -733,7 +733,7 @@ Vista char sun_path[UNIX_PATH_MAX]; } SOCKADDR_UN, *PSOCKADDR_UN; #endif -#endif +#endif /* ---------------------------------------------------------------- */ /* ADDITIONAL DEFINITIONS */ diff --git a/contrib/libs/curl/lib/conncache.c b/contrib/libs/curl/lib/conncache.c index 49d4410cf8..cb3170c480 100644 --- a/contrib/libs/curl/lib/conncache.c +++ b/contrib/libs/curl/lib/conncache.c @@ -40,8 +40,8 @@ #include "curl_memory.h" #include "memdebug.h" -#define HASHKEY_SIZE 128 - +#define HASHKEY_SIZE 128 + static void conn_llist_dtor(void *user, void *element) { struct connectdata *conn = element; @@ -137,17 +137,17 @@ void Curl_conncache_destroy(struct conncache *connc) /* creates a key to find a bundle for this connection */ static void hashkey(struct connectdata *conn, char *buf, - size_t len, /* something like 128 is fine */ - const char **hostp) + size_t len, /* something like 128 is fine */ + const char **hostp) { const char *hostname; - long port = conn->remote_port; + long port = conn->remote_port; #ifndef CURL_DISABLE_PROXY - if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { hostname = conn->http_proxy.host.name; - port = conn->port; - } + port = conn->port; + } else #endif if(conn->bits.conn_to_host) @@ -155,12 +155,12 @@ static void hashkey(struct connectdata *conn, char *buf, else hostname = conn->host.name; - if(hostp) - /* report back which name we used */ - *hostp = hostname; + if(hostp) + /* report back which name we used */ + *hostp = hostname; /* put the number first so that the hostname gets cut off if too long */ - msnprintf(buf, len, "%ld%s", port, hostname); + msnprintf(buf, len, "%ld%s", port, hostname); } /* Returns number of connections currently held in the connection cache. @@ -180,14 +180,14 @@ size_t Curl_conncache_size(struct Curl_easy *data) **NOTE**: When it returns, it holds the connection cache lock! */ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, - struct conncache *connc, - const char **hostp) + struct conncache *connc, + const char **hostp) { struct connectbundle *bundle = NULL; CONNCACHE_LOCK(conn->data); if(connc) { - char key[HASHKEY_SIZE]; - hashkey(conn, key, sizeof(key), hostp); + char key[HASHKEY_SIZE]; + hashkey(conn, key, sizeof(key), hostp); bundle = Curl_hash_pick(&connc->hash, key, strlen(key)); } @@ -235,17 +235,17 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc, struct Curl_easy *data = conn->data; /* *find_bundle() locks the connection cache */ - bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache, NULL); + bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache, NULL); if(!bundle) { int rc; - char key[HASHKEY_SIZE]; + char key[HASHKEY_SIZE]; result = bundle_create(&bundle); if(result) { goto unlock; } - hashkey(conn, key, sizeof(key), NULL); + hashkey(conn, key, sizeof(key), NULL); rc = conncache_add_bundle(data->state.conn_cache, key, bundle); if(!rc) { @@ -269,15 +269,15 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc, return result; } -/* +/* * Removes the connectdata object from the connection cache, but does *not* * clear the conn->data association. The transfer still owns this connection. * * Pass TRUE/FALSE in the 'lock' argument depending on if the parent function * already holds the lock or not. - */ -void Curl_conncache_remove_conn(struct Curl_easy *data, - struct connectdata *conn, bool lock) + */ +void Curl_conncache_remove_conn(struct Curl_easy *data, + struct connectdata *conn, bool lock) { struct connectbundle *bundle = conn->bundle; struct conncache *connc = data->state.conn_cache; @@ -360,8 +360,8 @@ bool Curl_conncache_foreach(struct Curl_easy *data, NOTE: no locking is done here as this is presumably only done when cleaning up a cache! */ -static struct connectdata * -conncache_find_first_connection(struct conncache *connc) +static struct connectdata * +conncache_find_first_connection(struct conncache *connc) { struct Curl_hash_iterator iter; struct Curl_hash_element *he; @@ -400,7 +400,7 @@ bool Curl_conncache_return_conn(struct Curl_easy *data, data->multi->maxconnects; struct connectdata *conn_candidate = NULL; - conn->lastused = Curl_now(); /* it was used up until now */ + conn->lastused = Curl_now(); /* it was used up until now */ if(maxconnects > 0 && Curl_conncache_size(data) > maxconnects) { infof(data, "Connection cache is full, closing the oldest one.\n"); @@ -444,9 +444,9 @@ Curl_conncache_extract_bundle(struct Curl_easy *data, while(curr) { conn = curr->ptr; - if(!CONN_INUSE(conn) && !conn->data) { + if(!CONN_INUSE(conn) && !conn->data) { /* Set higher score for the age passed since the connection was used */ - score = Curl_timediff(now, conn->lastused); + score = Curl_timediff(now, conn->lastused); if(score > highscore) { highscore = score; @@ -505,7 +505,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data) if(!CONN_INUSE(conn) && !conn->data && !conn->bits.close && !conn->bits.connect_only) { /* Set higher score for the age passed since the connection was used */ - score = Curl_timediff(now, conn->lastused); + score = Curl_timediff(now, conn->lastused); if(score > highscore) { highscore = score; @@ -540,7 +540,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc) connc->closure_handle->state.buffer = buffer; connc->closure_handle->set.buffer_size = READBUFFER_MIN; - conn = conncache_find_first_connection(connc); + conn = conncache_find_first_connection(connc); while(conn) { SIGPIPE_VARIABLE(pipe_st); conn->data = connc->closure_handle; @@ -552,7 +552,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc) (void)Curl_disconnect(connc->closure_handle, conn, FALSE); sigpipe_restore(&pipe_st); - conn = conncache_find_first_connection(connc); + conn = conncache_find_first_connection(connc); } connc->closure_handle->state.buffer = NULL; diff --git a/contrib/libs/curl/lib/conncache.h b/contrib/libs/curl/lib/conncache.h index c5262eb7eb..ac5460ff4b 100644 --- a/contrib/libs/curl/lib/conncache.h +++ b/contrib/libs/curl/lib/conncache.h @@ -75,8 +75,8 @@ void Curl_conncache_destroy(struct conncache *connc); /* return the correct bundle, to a host or a proxy */ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, - struct conncache *connc, - const char **hostp); + struct conncache *connc, + const char **hostp); /* returns number of connections currently held in the connection cache */ size_t Curl_conncache_size(struct Curl_easy *data); @@ -84,8 +84,8 @@ bool Curl_conncache_return_conn(struct Curl_easy *data, struct connectdata *conn); CURLcode Curl_conncache_add_conn(struct conncache *connc, struct connectdata *conn) WARN_UNUSED_RESULT; -void Curl_conncache_remove_conn(struct Curl_easy *data, - struct connectdata *conn, +void Curl_conncache_remove_conn(struct Curl_easy *data, + struct connectdata *conn, bool lock); bool Curl_conncache_foreach(struct Curl_easy *data, struct conncache *connc, diff --git a/contrib/libs/curl/lib/connect.c b/contrib/libs/curl/lib/connect.c index 97489c0f1b..e65d24d9e9 100644 --- a/contrib/libs/curl/lib/connect.c +++ b/contrib/libs/curl/lib/connect.c @@ -75,8 +75,8 @@ #include "conncache.h" #include "multihandle.h" #include "version_win32.h" -#include "quic.h" -#include "socks.h" +#include "quic.h" +#include "socks.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -355,7 +355,7 @@ static CURLcode bindlocal(struct connectdata *conn, conn->ip_version = CURL_IPRESOLVE_V6; #endif - rc = Curl_resolv(conn, dev, 0, FALSE, &h); + rc = Curl_resolv(conn, dev, 0, FALSE, &h); if(rc == CURLRESOLV_PENDING) (void)Curl_resolver_wait_resolv(conn, &h); conn->ip_version = ipver; @@ -366,11 +366,11 @@ static CURLcode bindlocal(struct connectdata *conn, infof(data, "Name '%s' family %i resolved to '%s' family %i\n", dev, af, myhost, h->addr->ai_family); Curl_resolv_unlock(data, h); - if(af != h->addr->ai_family) { - /* bad IP version combo, signal the caller to try another address - family if available */ - return CURLE_UNSUPPORTED_PROTOCOL; - } + if(af != h->addr->ai_family) { + /* bad IP version combo, signal the caller to try another address + family if available */ + return CURLE_UNSUPPORTED_PROTOCOL; + } done = 1; } else { @@ -449,10 +449,10 @@ static CURLcode bindlocal(struct connectdata *conn, curl_socklen_t size = sizeof(add); memset(&add, 0, sizeof(struct Curl_sockaddr_storage)); if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; data->state.os_errno = error = SOCKERRNO; failf(data, "getsockname() failed with errno %d: %s", - error, Curl_strerror(error, buffer, sizeof(buffer))); + error, Curl_strerror(error, buffer, sizeof(buffer))); return CURLE_INTERFACE_FAILED; } infof(data, "Local port: %hu\n", port); @@ -474,12 +474,12 @@ static CURLcode bindlocal(struct connectdata *conn, else break; } - { - char buffer[STRERROR_LEN]; - data->state.os_errno = error = SOCKERRNO; - failf(data, "bind failed with errno %d: %s", - error, Curl_strerror(error, buffer, sizeof(buffer))); - } + { + char buffer[STRERROR_LEN]; + data->state.os_errno = error = SOCKERRNO; + failf(data, "bind failed with errno %d: %s", + error, Curl_strerror(error, buffer, sizeof(buffer))); + } return CURLE_INTERFACE_FAILED; } @@ -586,7 +586,7 @@ static CURLcode trynextip(struct connectdata *conn, while(ai) { if(ai) { - result = singleipconnect(conn, ai, tempindex); + result = singleipconnect(conn, ai, tempindex); if(result == CURLE_COULDNT_CONNECT) { ai = ainext(conn, tempindex, TRUE); continue; @@ -616,8 +616,8 @@ void Curl_persistconninfo(struct connectdata *conn) /* retrieves ip address and port from a sockaddr structure. note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ -bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, long *port) +bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, + char *addr, long *port) { struct sockaddr_in *si = NULL; #ifdef ENABLE_IPV6 @@ -625,8 +625,8 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, #endif #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) struct sockaddr_un *su = NULL; -#else - (void)salen; +#else + (void)salen; #endif switch(sa->sa_family) { @@ -634,7 +634,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, si = (struct sockaddr_in *)(void *) sa; if(Curl_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) { - unsigned short us_port = ntohs(si->sin_port); + unsigned short us_port = ntohs(si->sin_port); *port = us_port; return TRUE; } @@ -644,7 +644,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, si6 = (struct sockaddr_in6 *)(void *) sa; if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr, addr, MAX_IPADR_LEN)) { - unsigned short us_port = ntohs(si6->sin6_port); + unsigned short us_port = ntohs(si6->sin6_port); *port = us_port; return TRUE; } @@ -653,11 +653,11 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) case AF_UNIX: if(salen > (curl_socklen_t)sizeof(sa_family_t)) { - su = (struct sockaddr_un*)sa; - msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); - } - else - addr[0] = 0; /* socket with no name */ + su = (struct sockaddr_un*)sa; + msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); + } + else + addr[0] = 0; /* socket with no name */ *port = 0; return TRUE; #endif @@ -703,7 +703,7 @@ void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd) connection */ void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd) { -#ifdef HAVE_GETSOCKNAME +#ifdef HAVE_GETSOCKNAME char buffer[STRERROR_LEN]; struct Curl_sockaddr_storage ssloc; curl_socklen_t slen; @@ -724,7 +724,7 @@ void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd) #else (void)conn; (void)sockfd; -#endif +#endif } /* retrieves the start/end point information of a socket of an established @@ -745,20 +745,20 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) /* After a TCP connection to the proxy has been verified, this function does the next magic steps. If 'done' isn't set TRUE, it is not done yet and must be called again. - - Note: this function's sub-functions call failf() - -*/ + + Note: this function's sub-functions call failf() + +*/ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, bool *done) -{ - CURLcode result = CURLE_OK; +{ + CURLcode result = CURLE_OK; #ifndef CURL_DISABLE_PROXY CURLproxycode pxresult = CURLPX_OK; - if(conn->bits.socksproxy) { - /* for the secondary socket (FTP), use the "connect to host" - * but ignore the "connect to port" (use the secondary port) - */ + if(conn->bits.socksproxy) { + /* for the secondary socket (FTP), use the "connect to host" + * but ignore the "connect to port" (use the secondary port) + */ const char * const host = conn->bits.httpproxy ? conn->http_proxy.host.name : @@ -771,38 +771,38 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex, sockindex == SECONDARYSOCKET ? conn->secondary_port : conn->bits.conn_to_port ? conn->conn_to_port : conn->remote_port; - switch(conn->socks_proxy.proxytype) { - case CURLPROXY_SOCKS5: - case CURLPROXY_SOCKS5_HOSTNAME: + switch(conn->socks_proxy.proxytype) { + case CURLPROXY_SOCKS5: + case CURLPROXY_SOCKS5_HOSTNAME: pxresult = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd, host, port, sockindex, conn, done); - break; - - case CURLPROXY_SOCKS4: - case CURLPROXY_SOCKS4A: + break; + + case CURLPROXY_SOCKS4: + case CURLPROXY_SOCKS4A: pxresult = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex, conn, done); - break; - - default: - failf(conn->data, "unknown proxytype option given"); - result = CURLE_COULDNT_CONNECT; - } /* switch proxytype */ + break; + + default: + failf(conn->data, "unknown proxytype option given"); + result = CURLE_COULDNT_CONNECT; + } /* switch proxytype */ if(pxresult) { result = CURLE_PROXY; conn->data->info.pxcode = pxresult; } } else -#else +#else (void)conn; (void)sockindex; -#endif /* CURL_DISABLE_PROXY */ +#endif /* CURL_DISABLE_PROXY */ *done = TRUE; /* no SOCKS proxy, so consider us connected */ - - return result; -} - + + return result; +} + /* * post_SOCKS() is called after a successful connect to the peer, which * *could* be a SOCKS proxy @@ -871,23 +871,23 @@ CURLcode Curl_is_connected(struct connectdata *conn, if(conn->tempsock[i] == CURL_SOCKET_BAD) continue; error = 0; -#ifdef ENABLE_QUIC - if(conn->transport == TRNSPRT_QUIC) { - result = Curl_quic_is_connected(conn, i, connected); +#ifdef ENABLE_QUIC + if(conn->transport == TRNSPRT_QUIC) { + result = Curl_quic_is_connected(conn, i, connected); if(!result && *connected) { - /* use this socket from now on */ - conn->sock[sockindex] = conn->tempsock[i]; - conn->ip_addr = conn->tempaddr[i]; - conn->tempsock[i] = CURL_SOCKET_BAD; + /* use this socket from now on */ + conn->sock[sockindex] = conn->tempsock[i]; + conn->ip_addr = conn->tempaddr[i]; + conn->tempsock[i] = CURL_SOCKET_BAD; post_SOCKS(conn, sockindex, connected); - connkeep(conn, "HTTP/3 default"); + connkeep(conn, "HTTP/3 default"); return CURLE_OK; - } + } if(result) error = SOCKERRNO; - } + } else -#endif +#endif { #ifdef mpeix /* Call this function once now, and ignore the results. We do this to @@ -904,7 +904,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, if(rc == 0) { /* no connection yet */ if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr[i]) { - infof(data, "After %" CURL_FORMAT_TIMEDIFF_T + infof(data, "After %" CURL_FORMAT_TIMEDIFF_T "ms connect time, move on!\n", conn->timeoutms_per_addr[i]); error = ETIMEDOUT; } @@ -961,20 +961,20 @@ CURLcode Curl_is_connected(struct connectdata *conn, CURLcode status; #ifndef CURL_DISABLE_VERBOSE_STRINGS char ipaddress[MAX_IPADR_LEN]; - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; Curl_printable_address(conn->tempaddr[i], ipaddress, sizeof(ipaddress)); infof(data, "connect to %s port %ld failed: %s\n", - ipaddress, conn->port, - Curl_strerror(error, buffer, sizeof(buffer))); + ipaddress, conn->port, + Curl_strerror(error, buffer, sizeof(buffer))); #endif conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ? - allow : allow / 2; + allow : allow / 2; ainext(conn, i, TRUE); status = trynextip(conn, sockindex, i); - if((status != CURLE_COULDNT_CONNECT) || - conn->tempsock[other] == CURL_SOCKET_BAD) + if((status != CURLE_COULDNT_CONNECT) || + conn->tempsock[other] == CURL_SOCKET_BAD) /* the last attempt failed and no other sockets remain open */ result = status; } @@ -986,7 +986,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, (conn->tempsock[1] == CURL_SOCKET_BAD)) { /* no more addresses to try */ const char *hostname; - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; /* if the first address family runs out of addresses to try before the happy eyeball timeout, go ahead and try the next family now */ @@ -1007,8 +1007,8 @@ CURLcode Curl_is_connected(struct connectdata *conn, hostname = conn->host.name; failf(data, "Failed to connect to %s port %ld: %s", - hostname, conn->port, - Curl_strerror(error, buffer, sizeof(buffer))); + hostname, conn->port, + Curl_strerror(error, buffer, sizeof(buffer))); Curl_quic_disconnect(conn, 0); Curl_quic_disconnect(conn, 1); @@ -1027,14 +1027,14 @@ CURLcode Curl_is_connected(struct connectdata *conn, return result; } -static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) +static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) { #if defined(TCP_NODELAY) curl_socklen_t onoff = (curl_socklen_t) 1; int level = IPPROTO_TCP; #if !defined(CURL_DISABLE_VERBOSE_STRINGS) struct Curl_easy *data = conn->data; - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; #else (void) conn; #endif @@ -1042,7 +1042,7 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff, sizeof(onoff)) < 0) infof(data, "Could not set TCP_NODELAY: %s\n", - Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); #else (void)conn; (void)sockfd; @@ -1060,11 +1060,11 @@ static void nosigpipe(struct connectdata *conn, struct Curl_easy *data = conn->data; int onoff = 1; if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, - sizeof(onoff)) < 0) { - char buffer[STRERROR_LEN]; + sizeof(onoff)) < 0) { + char buffer[STRERROR_LEN]; infof(data, "Could not set SO_NOSIGPIPE: %s\n", - Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); - } + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + } } #else #define nosigpipe(x,y) Curl_nop_stmt @@ -1140,7 +1140,7 @@ static CURLcode singleipconnect(struct connectdata *conn, #ifdef TCP_FASTOPEN_CONNECT int optval = 1; #endif - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; curl_socket_t *sockp = &conn->tempsock[tempindex]; *sockp = CURL_SOCKET_BAD; @@ -1149,15 +1149,15 @@ static CURLcode singleipconnect(struct connectdata *conn, return result; /* store remote address and port used in this connection attempt */ - if(!Curl_addr2string((struct sockaddr*)&addr.sa_addr, addr.addrlen, - ipaddress, &port)) { + if(!Curl_addr2string((struct sockaddr*)&addr.sa_addr, addr.addrlen, + ipaddress, &port)) { /* malformed address or bug in inet_ntop, try next address */ failf(data, "sa_addr inet_ntop() failed with errno %d: %s", - errno, Curl_strerror(errno, buffer, sizeof(buffer))); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); Curl_closesocket(conn, sockfd); return CURLE_OK; } - infof(data, " Trying %s:%ld...\n", ipaddress, port); + infof(data, " Trying %s:%ld...\n", ipaddress, port); #ifdef ENABLE_IPV6 is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) && @@ -1166,7 +1166,7 @@ static CURLcode singleipconnect(struct connectdata *conn, is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM; #endif if(is_tcp && data->set.tcp_nodelay) - tcpnodelay(conn, sockfd); + tcpnodelay(conn, sockfd); nosigpipe(conn, sockfd); @@ -1219,8 +1219,8 @@ static CURLcode singleipconnect(struct connectdata *conn, Curl_expire(data, conn->timeoutms_per_addr[1], EXPIRE_DNS_PER_NAME2); } - /* Connect TCP and QUIC sockets */ - if(!isconnected && (conn->transport != TRNSPRT_UDP)) { + /* Connect TCP and QUIC sockets */ + if(!isconnected && (conn->transport != TRNSPRT_UDP)) { if(conn->bits.tcp_fastopen) { #if defined(CONNECT_DATA_IDEMPOTENT) /* Darwin */ # if defined(HAVE_BUILTIN_AVAILABLE) @@ -1264,16 +1264,16 @@ static CURLcode singleipconnect(struct connectdata *conn, if(-1 == rc) error = SOCKERRNO; -#ifdef ENABLE_QUIC - else if(conn->transport == TRNSPRT_QUIC) { - /* pass in 'sockfd' separately since it hasn't been put into the - tempsock array at this point */ +#ifdef ENABLE_QUIC + else if(conn->transport == TRNSPRT_QUIC) { + /* pass in 'sockfd' separately since it hasn't been put into the + tempsock array at this point */ result = Curl_quic_connect(conn, sockfd, tempindex, - &addr.sa_addr, addr.addrlen); - if(result) - error = SOCKERRNO; - } -#endif + &addr.sa_addr, addr.addrlen); + if(result) + error = SOCKERRNO; + } +#endif } else { *sockp = sockfd; @@ -1299,7 +1299,7 @@ static CURLcode singleipconnect(struct connectdata *conn, default: /* unknown error, fallthrough and try another address! */ infof(data, "Immediate connect fail for %s: %s\n", - ipaddress, Curl_strerror(error, buffer, sizeof(buffer))); + ipaddress, Curl_strerror(error, buffer, sizeof(buffer))); data->state.os_errno = error; /* connect failed */ @@ -1523,9 +1523,9 @@ CURLcode Curl_socket(struct connectdata *conn, */ addr->family = ai->ai_family; - addr->socktype = (conn->transport == TRNSPRT_TCP) ? SOCK_STREAM : SOCK_DGRAM; - addr->protocol = conn->transport != TRNSPRT_TCP ? IPPROTO_UDP : - ai->ai_protocol; + addr->socktype = (conn->transport == TRNSPRT_TCP) ? SOCK_STREAM : SOCK_DGRAM; + addr->protocol = conn->transport != TRNSPRT_TCP ? IPPROTO_UDP : + ai->ai_protocol; addr->addrlen = ai->ai_addrlen; if(addr->addrlen > sizeof(struct Curl_sockaddr_storage)) @@ -1589,7 +1589,7 @@ void Curl_conncontrol(struct connectdata *conn, if((ctrl == CONNCTRL_STREAM) && (conn->handler->flags & PROTOPT_STREAM)) DEBUGF(infof(conn->data, "Kill stream: %s\n", reason)); - else if((bit)closeit != conn->bits.close) { + else if((bit)closeit != conn->bits.close) { DEBUGF(infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive", reason)); conn->bits.close = closeit; /* the only place in the source code that diff --git a/contrib/libs/curl/lib/connect.h b/contrib/libs/curl/lib/connect.h index a059ea897f..9b1faf8fb7 100644 --- a/contrib/libs/curl/lib/connect.h +++ b/contrib/libs/curl/lib/connect.h @@ -51,9 +51,9 @@ timediff_t Curl_timeleft(struct Curl_easy *data, curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, struct connectdata **connp); -bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, long *port); - +bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, + char *addr, long *port); + /* * Check if a connection seems to be alive. */ diff --git a/contrib/libs/curl/lib/cookie.c b/contrib/libs/curl/lib/cookie.c index 881be2c839..e88678c219 100644 --- a/contrib/libs/curl/lib/cookie.c +++ b/contrib/libs/curl/lib/cookie.c @@ -93,7 +93,7 @@ Example set of cookies: #include "share.h" #include "strtoofft.h" #include "strcase.h" -#include "curl_get_line.h" +#include "curl_get_line.h" #include "curl_memrchr.h" #include "inet_pton.h" #include "parsedate.h" @@ -227,7 +227,7 @@ static bool pathmatch(const char *cookie_path, const char *request_uri) goto pathmatched; } - /* here, cookie_path_len < uri_path_len */ + /* here, cookie_path_len < uri_path_len */ if(uri_path[cookie_path_len] == '/') { ret = TRUE; goto pathmatched; @@ -436,10 +436,10 @@ Curl_cookie_add(struct Curl_easy *data, bool noexpire, /* if TRUE, skip remove_expired() */ char *lineptr, /* first character of the line */ const char *domain, /* default domain */ - const char *path, /* full path used when this cookie is set, + const char *path, /* full path used when this cookie is set, used to get default path for the cookie unless set */ - bool secure) /* TRUE if connection is over secure origin */ + bool secure) /* TRUE if connection is over secure origin */ { struct Cookie *clist; struct Cookie *co; @@ -531,19 +531,19 @@ Curl_cookie_add(struct Curl_easy *data, while(*whatptr && ISBLANK(*whatptr)) whatptr++; - /* - * Check if we have a reserved prefix set before anything else, as we - * otherwise have to test for the prefix in both the cookie name and - * "the rest". Prefixes must start with '__' and end with a '-', so - * only test for names where that can possibly be true. - */ - if(nlen > 3 && name[0] == '_' && name[1] == '_') { + /* + * Check if we have a reserved prefix set before anything else, as we + * otherwise have to test for the prefix in both the cookie name and + * "the rest". Prefixes must start with '__' and end with a '-', so + * only test for names where that can possibly be true. + */ + if(nlen > 3 && name[0] == '_' && name[1] == '_') { if(!strncmp("__Secure-", name, 9)) - co->prefix |= COOKIE_PREFIX__SECURE; + co->prefix |= COOKIE_PREFIX__SECURE; else if(!strncmp("__Host-", name, 7)) - co->prefix |= COOKIE_PREFIX__HOST; - } - + co->prefix |= COOKIE_PREFIX__HOST; + } + if(!co->name) { /* The very first name/value pair is the actual cookie name */ if(!sep) { @@ -563,20 +563,20 @@ Curl_cookie_add(struct Curl_easy *data, /* this was a "<name>=" with no content, and we must allow 'secure' and 'httponly' specified this weirdly */ done = TRUE; - /* - * secure cookies are only allowed to be set when the connection is - * using a secure protocol, or when the cookie is being set by - * reading from file - */ - if(strcasecompare("secure", name)) { - if(secure || !c->running) { - co->secure = TRUE; - } - else { - badcookie = TRUE; - break; - } - } + /* + * secure cookies are only allowed to be set when the connection is + * using a secure protocol, or when the cookie is being set by + * reading from file + */ + if(strcasecompare("secure", name)) { + if(secure || !c->running) { + co->secure = TRUE; + } + else { + badcookie = TRUE; + break; + } + } else if(strcasecompare("httponly", name)) co->httponly = TRUE; else if(sep) @@ -821,14 +821,14 @@ Curl_cookie_add(struct Curl_easy *data, badcookie = TRUE; break; case 1: - /* flag: A TRUE/FALSE value indicating if all machines within a given - domain can access the variable. Set TRUE when the cookie says + /* flag: A TRUE/FALSE value indicating if all machines within a given + domain can access the variable. Set TRUE when the cookie says .domain.com and to false when the domain is complete www.domain.com */ co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE; break; case 2: - /* The file format allows the path field to remain not filled in */ + /* The file format allows the path field to remain not filled in */ if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) { /* only if the path doesn't look like a boolean option! */ co->path = strdup(ptr); @@ -852,13 +852,13 @@ Curl_cookie_add(struct Curl_easy *data, fields++; /* add a field and fall down to secure */ /* FALLTHROUGH */ case 3: - co->secure = FALSE; - if(strcasecompare(ptr, "TRUE")) { - if(secure || c->running) - co->secure = TRUE; - else - badcookie = TRUE; - } + co->secure = FALSE; + if(strcasecompare(ptr, "TRUE")) { + if(secure || c->running) + co->secure = TRUE; + else + badcookie = TRUE; + } break; case 4: if(curlx_strtoofft(ptr, NULL, 10, &co->expires)) @@ -868,13 +868,13 @@ Curl_cookie_add(struct Curl_easy *data, co->name = strdup(ptr); if(!co->name) badcookie = TRUE; - else { - /* For Netscape file format cookies we check prefix on the name */ - if(strncasecompare("__Secure-", co->name, 9)) - co->prefix |= COOKIE_PREFIX__SECURE; - else if(strncasecompare("__Host-", co->name, 7)) - co->prefix |= COOKIE_PREFIX__HOST; - } + else { + /* For Netscape file format cookies we check prefix on the name */ + if(strncasecompare("__Secure-", co->name, 9)) + co->prefix |= COOKIE_PREFIX__SECURE; + else if(strncasecompare("__Host-", co->name, 7)) + co->prefix |= COOKIE_PREFIX__HOST; + } break; case 6: co->value = strdup(ptr); @@ -903,26 +903,26 @@ Curl_cookie_add(struct Curl_easy *data, } - if(co->prefix & COOKIE_PREFIX__SECURE) { - /* The __Secure- prefix only requires that the cookie be set secure */ - if(!co->secure) { - freecookie(co); - return NULL; - } - } - if(co->prefix & COOKIE_PREFIX__HOST) { - /* - * The __Host- prefix requires the cookie to be secure, have a "/" path - * and not have a domain set. - */ - if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch) - ; - else { - freecookie(co); - return NULL; - } - } - + if(co->prefix & COOKIE_PREFIX__SECURE) { + /* The __Secure- prefix only requires that the cookie be set secure */ + if(!co->secure) { + freecookie(co); + return NULL; + } + } + if(co->prefix & COOKIE_PREFIX__HOST) { + /* + * The __Host- prefix requires the cookie to be secure, have a "/" path + * and not have a domain set. + */ + if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch) + ; + else { + freecookie(co); + return NULL; + } + } + if(!c->running && /* read from a file */ c->newsession && /* clean session cookies */ !co->expires) { /* this is a session cookie since it doesn't expire! */ @@ -983,30 +983,30 @@ Curl_cookie_add(struct Curl_easy *data, /* the domains were identical */ if(clist->spath && co->spath) { - if(clist->secure && !co->secure && !secure) { - size_t cllen; - const char *sep; - - /* - * A non-secure cookie may not overlay an existing secure cookie. - * For an existing cookie "a" with path "/login", refuse a new - * cookie "a" with for example path "/login/en", while the path - * "/loginhelper" is ok. - */ - - sep = strchr(clist->spath + 1, '/'); - - if(sep) - cllen = sep - clist->spath; - else - cllen = strlen(clist->spath); - - if(strncasecompare(clist->spath, co->spath, cllen)) { - freecookie(co); - return NULL; - } - } - else if(strcasecompare(clist->spath, co->spath)) + if(clist->secure && !co->secure && !secure) { + size_t cllen; + const char *sep; + + /* + * A non-secure cookie may not overlay an existing secure cookie. + * For an existing cookie "a" with path "/login", refuse a new + * cookie "a" with for example path "/login/en", while the path + * "/loginhelper" is ok. + */ + + sep = strchr(clist->spath + 1, '/'); + + if(sep) + cllen = sep - clist->spath; + else + cllen = strlen(clist->spath); + + if(strncasecompare(clist->spath, co->spath, cllen)) { + freecookie(co); + return NULL; + } + } + else if(strcasecompare(clist->spath, co->spath)) replace_old = TRUE; else replace_old = FALSE; @@ -1141,7 +1141,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, line = malloc(MAX_COOKIE_LINE); if(!line) goto fail; - while(Curl_get_line(line, MAX_COOKIE_LINE, fp)) { + while(Curl_get_line(line, MAX_COOKIE_LINE, fp)) { if(checkprefix("Set-Cookie:", line)) { /* This is a cookie line, get it! */ lineptr = &line[11]; @@ -1154,7 +1154,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, while(*lineptr && ISBLANK(*lineptr)) lineptr++; - Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL, TRUE); + Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL, TRUE); } free(line); /* free the line buffer */ remove_expired(c); /* run this once, not on every cookie */ @@ -1511,10 +1511,10 @@ static int cookie_output(struct Curl_easy *data, char *tempstore = NULL; bool error = false; - if(!c) - /* no cookie engine alive */ - return 0; - + if(!c) + /* no cookie engine alive */ + return 0; + /* at first, remove expired cookies */ remove_expired(c); @@ -1544,10 +1544,10 @@ static int cookie_output(struct Curl_easy *data, out); if(c->numcookies) { - unsigned int i; + unsigned int i; size_t nvalid = 0; - struct Cookie **array; - + struct Cookie **array; + array = calloc(1, sizeof(struct Cookie *) * c->numcookies); if(!array) { goto error; @@ -1565,7 +1565,7 @@ static int cookie_output(struct Curl_easy *data, qsort(array, nvalid, sizeof(struct Cookie *), cookie_sort_ct); for(i = 0; i < nvalid; i++) { - char *format_ptr = get_netscape_format(array[i]); + char *format_ptr = get_netscape_format(array[i]); if(format_ptr == NULL) { fprintf(out, "#\n# Fatal libcurl error\n"); free(array); diff --git a/contrib/libs/curl/lib/cookie.h b/contrib/libs/curl/lib/cookie.h index 2b62da3fce..066396f0d5 100644 --- a/contrib/libs/curl/lib/cookie.h +++ b/contrib/libs/curl/lib/cookie.h @@ -44,16 +44,16 @@ struct Cookie { bool livecookie; /* updated from a server, not a stored file */ bool httponly; /* true if the httponly directive is present */ int creationtime; /* time when the cookie was written */ - unsigned char prefix; /* bitmap fields indicating which prefix are set */ + unsigned char prefix; /* bitmap fields indicating which prefix are set */ }; -/* - * Available cookie prefixes, as defined in - * draft-ietf-httpbis-rfc6265bis-02 - */ -#define COOKIE_PREFIX__SECURE (1<<0) -#define COOKIE_PREFIX__HOST (1<<1) - +/* + * Available cookie prefixes, as defined in + * draft-ietf-httpbis-rfc6265bis-02 + */ +#define COOKIE_PREFIX__SECURE (1<<0) +#define COOKIE_PREFIX__HOST (1<<1) + #define COOKIE_HASH_SIZE 256 struct CookieInfo { @@ -93,8 +93,8 @@ struct Curl_easy; struct Cookie *Curl_cookie_add(struct Curl_easy *data, struct CookieInfo *, bool header, bool noexpiry, char *lineptr, - const char *domain, const char *path, - bool secure); + const char *domain, const char *path, + bool secure); struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *, const char *, bool); diff --git a/contrib/libs/curl/lib/curl_addrinfo.c b/contrib/libs/curl/lib/curl_addrinfo.c index c0e8e2063e..9007259d4c 100644 --- a/contrib/libs/curl/lib/curl_addrinfo.c +++ b/contrib/libs/curl/lib/curl_addrinfo.c @@ -510,7 +510,7 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \ defined(HAVE_FREEADDRINFO) /* - * curl_dbg_freeaddrinfo() + * curl_dbg_freeaddrinfo() * * This is strictly for memory tracing and are using the same style as the * family otherwise present in memdebug.c. I put these ones here since they @@ -518,11 +518,11 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, */ void -curl_dbg_freeaddrinfo(struct addrinfo *freethis, - int line, const char *source) +curl_dbg_freeaddrinfo(struct addrinfo *freethis, + int line, const char *source) { - curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n", - source, line, (void *)freethis); + curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n", + source, line, (void *)freethis); #ifdef USE_LWIPSOCK lwip_freeaddrinfo(freethis); #else @@ -534,7 +534,7 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis, #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) /* - * curl_dbg_getaddrinfo() + * curl_dbg_getaddrinfo() * * This is strictly for memory tracing and are using the same style as the * family otherwise present in memdebug.c. I put these ones here since they @@ -542,11 +542,11 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis, */ int -curl_dbg_getaddrinfo(const char *hostname, - const char *service, - const struct addrinfo *hints, - struct addrinfo **result, - int line, const char *source) +curl_dbg_getaddrinfo(const char *hostname, + const char *service, + const struct addrinfo *hints, + struct addrinfo **result, + int line, const char *source) { #ifdef USE_LWIPSOCK int res = lwip_getaddrinfo(hostname, service, hints, result); @@ -555,11 +555,11 @@ curl_dbg_getaddrinfo(const char *hostname, #endif if(0 == res) /* success */ - curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n", - source, line, (void *)*result); + curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n", + source, line, (void *)*result); else - curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n", - source, line); + curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n", + source, line); return res; } #endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */ diff --git a/contrib/libs/curl/lib/curl_addrinfo.h b/contrib/libs/curl/lib/curl_addrinfo.h index d9fb7d1db5..73a8c1b334 100644 --- a/contrib/libs/curl/lib/curl_addrinfo.h +++ b/contrib/libs/curl/lib/curl_addrinfo.h @@ -85,14 +85,14 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \ defined(HAVE_FREEADDRINFO) void -curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source); +curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source); #endif #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) int -curl_dbg_getaddrinfo(const char *hostname, const char *service, - const struct addrinfo *hints, struct addrinfo **result, - int line, const char *source); +curl_dbg_getaddrinfo(const char *hostname, const char *service, + const struct addrinfo *hints, struct addrinfo **result, + int line, const char *source); #endif #ifdef HAVE_GETADDRINFO diff --git a/contrib/libs/curl/lib/curl_config-ios.h b/contrib/libs/curl/lib/curl_config-ios.h index 1a3c869dfb..f73a2e43f3 100644 --- a/contrib/libs/curl/lib/curl_config-ios.h +++ b/contrib/libs/curl/lib/curl_config-ios.h @@ -1,8 +1,8 @@ -#pragma once - -#include "curl_config-osx.h" - -#undef USE_OPENSSL -#undef USE_TLS_SRP -#define USE_DARWINSSL 1 -#define HAVE_LDAP_SSL 1 +#pragma once + +#include "curl_config-osx.h" + +#undef USE_OPENSSL +#undef USE_TLS_SRP +#define USE_DARWINSSL 1 +#define HAVE_LDAP_SSL 1 diff --git a/contrib/libs/curl/lib/curl_config-linux.h b/contrib/libs/curl/lib/curl_config-linux.h index 98b02c2345..0dfa912535 100644 --- a/contrib/libs/curl/lib/curl_config-linux.h +++ b/contrib/libs/curl/lib/curl_config-linux.h @@ -28,9 +28,9 @@ /* to disable DICT */ /* #undef CURL_DISABLE_DICT */ -/* disable DoH */ -/* #undef CURL_DISABLE_DOH */ - +/* disable DoH */ +/* #undef CURL_DISABLE_DOH */ + /* to disable FILE */ /* #undef CURL_DISABLE_FILE */ @@ -46,9 +46,9 @@ /* to disable HTTP */ /* #undef CURL_DISABLE_HTTP */ -/* disable HTTP authentication */ -/* #undef CURL_DISABLE_HTTP_AUTH */ - +/* disable HTTP authentication */ +/* #undef CURL_DISABLE_HTTP_AUTH */ + /* to disable IMAP */ /* #undef CURL_DISABLE_IMAP */ @@ -61,36 +61,36 @@ /* to disable --libcurl C code generation option */ /* #undef CURL_DISABLE_LIBCURL_OPTION */ -/* disable mime API */ -/* #undef CURL_DISABLE_MIME */ - +/* disable mime API */ +/* #undef CURL_DISABLE_MIME */ + /* to disable MQTT */ /* #undef CURL_DISABLE_MQTT */ -/* disable netrc parsing */ -/* #undef CURL_DISABLE_NETRC */ - +/* disable netrc parsing */ +/* #undef CURL_DISABLE_NETRC */ + /* if the OpenSSL configuration won't be loaded automatically */ /* #undef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG */ -/* disable date parsing */ -/* #undef CURL_DISABLE_PARSEDATE */ - +/* disable date parsing */ +/* #undef CURL_DISABLE_PARSEDATE */ + /* to disable POP3 */ /* #undef CURL_DISABLE_POP3 */ -/* disable progress-meter */ -/* #undef CURL_DISABLE_PROGRESS_METER */ - +/* disable progress-meter */ +/* #undef CURL_DISABLE_PROGRESS_METER */ + /* to disable proxies */ /* #undef CURL_DISABLE_PROXY */ /* to disable RTSP */ /* #undef CURL_DISABLE_RTSP */ -/* disable DNS shuffling */ -/* #undef CURL_DISABLE_SHUFFLE_DNS */ - +/* disable DNS shuffling */ +/* #undef CURL_DISABLE_SHUFFLE_DNS */ + /* to disable SMB/CIFS */ /* #undef CURL_DISABLE_SMB */ @@ -281,9 +281,9 @@ /* Define to 1 if you have the `getpass_r' function. */ /* #undef HAVE_GETPASS_R */ -/* Define to 1 if you have the getpeername function. */ -#define HAVE_GETPEERNAME 1 - +/* Define to 1 if you have the getpeername function. */ +#define HAVE_GETPEERNAME 1 + /* Define to 1 if you have the `getppid' function. */ #define HAVE_GETPPID 1 @@ -299,9 +299,9 @@ /* Define to 1 if you have the getservbyport_r function. */ #define HAVE_GETSERVBYPORT_R 1 -/* Define to 1 if you have the getsockname function. */ -#define HAVE_GETSOCKNAME 1 - +/* Define to 1 if you have the getsockname function. */ +#define HAVE_GETSOCKNAME 1 + /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 @@ -493,17 +493,17 @@ #define HAVE_NET_IF_H 1 /* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */ -#define HAVE_NGHTTP2_NGHTTP2_H 1 - -/* Define to 1 if you have the <nghttp3/nghttp3.h> header file. */ -/* #undef HAVE_NGHTTP3_NGHTTP3_H */ - -/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto.h> header file. */ -/* #undef HAVE_NGTCP2_NGTCP2_CRYPTO_H */ - -/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */ -/* #undef HAVE_NGTCP2_NGTCP2_H */ - +#define HAVE_NGHTTP2_NGHTTP2_H 1 + +/* Define to 1 if you have the <nghttp3/nghttp3.h> header file. */ +/* #undef HAVE_NGHTTP3_NGHTTP3_H */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto.h> header file. */ +/* #undef HAVE_NGTCP2_NGTCP2_CRYPTO_H */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */ +/* #undef HAVE_NGTCP2_NGTCP2_H */ + /* if you have an old MIT Kerberos version, lacking GSS_C_NT_HOSTBASED_SERVICE */ /* #undef HAVE_OLD_GSSMIT */ @@ -529,9 +529,9 @@ /* Define to 1 if you have the <openssl/ssl.h> header file. */ #define HAVE_OPENSSL_SSL_H 1 -/* Define to 1 if you have the `OpenSSL_version' function. */ -#define HAVE_OPENSSL_VERSION 1 - +/* Define to 1 if you have the `OpenSSL_version' function. */ +#define HAVE_OPENSSL_VERSION 1 + /* Define to 1 if you have the <openssl/x509.h> header file. */ #define HAVE_OPENSSL_X509_H 1 @@ -556,9 +556,9 @@ /* Define to 1 if you have a working POSIX-style strerror_r function. */ /* #undef HAVE_POSIX_STRERROR_R */ -/* Define to 1 if you have the <proto/bsdsocket.h> header file. */ -/* #undef HAVE_PROTO_BSDSOCKET_H */ - +/* Define to 1 if you have the <proto/bsdsocket.h> header file. */ +/* #undef HAVE_PROTO_BSDSOCKET_H */ + /* if you have <pthread.h> */ /* #undef HAVE_PTHREAD_H */ @@ -568,9 +568,9 @@ /* Define to 1 if you have the `quiche_conn_set_qlog_fd' function. */ /* #undef HAVE_QUICHE_CONN_SET_QLOG_FD */ -/* Define to 1 if you have the <quiche.h> header file. */ -/* #undef HAVE_QUICHE_H */ - +/* Define to 1 if you have the <quiche.h> header file. */ +/* #undef HAVE_QUICHE_H */ + /* Define to 1 if you have the `RAND_egd' function. */ /* #undef HAVE_RAND_EGD */ @@ -641,7 +641,7 @@ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the `SSLv2_client_method' function. */ -/* #undef HAVE_SSLV2_CLIENT_METHOD */ +/* #undef HAVE_SSLV2_CLIENT_METHOD */ /* Define to 1 if you have the `SSL_get_ech_status' function. */ /* #undef HAVE_SSL_GET_ECH_STATUS */ @@ -772,9 +772,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 -/* Define to 1 if you have the `usleep' function. */ -#define HAVE_USLEEP 1 - +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + /* Define to 1 if you have the `utime' function. */ #define HAVE_UTIME 1 @@ -947,13 +947,13 @@ #define SIZEOF_CURL_OFF_T 8 /* The number of bytes in type int */ -#ifndef SIZEOF_INT -#error undefined SIZEOF_INT -#endif +#ifndef SIZEOF_INT +#error undefined SIZEOF_INT +#endif /* The number of bytes in type long */ -#ifndef SIZEOF_LONG -#error undefined SIZEOF_LONG +#ifndef SIZEOF_LONG +#error undefined SIZEOF_LONG #endif /* The number of bytes in type long long */ @@ -963,17 +963,17 @@ #define SIZEOF_OFF_T 8 /* The number of bytes in type short */ -#ifndef SIZEOF_SHORT -#error undefined SIZEOF_SHORT -#endif +#ifndef SIZEOF_SHORT +#error undefined SIZEOF_SHORT +#endif /* The number of bytes in type size_t */ -#ifndef SIZEOF_SIZE_T -#error undefined SIZEOF_SIZE_T -#endif +#ifndef SIZEOF_SIZE_T +#error undefined SIZEOF_SIZE_T +#endif /* The number of bytes in type time_t */ -#define SIZEOF_TIME_T SIZEOF_LONG +#define SIZEOF_TIME_T SIZEOF_LONG /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 @@ -984,9 +984,9 @@ /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ #define TIME_WITH_SYS_TIME 1 -/* if AmiSSL is in use */ -/* #undef USE_AMISSL */ - +/* if AmiSSL is in use */ +/* #undef USE_AMISSL */ + /* Define to enable c-ares support */ #define USE_ARES 1 @@ -1030,20 +1030,20 @@ /* #undef USE_METALINK */ /* if nghttp2 is in use */ -#define USE_NGHTTP2 1 - -/* if nghttp3 is in use */ -/* #undef USE_NGHTTP3 */ - -/* if ngtcp2 is in use */ -/* #undef USE_NGTCP2 */ - +#define USE_NGHTTP2 1 + +/* if nghttp3 is in use */ +/* #undef USE_NGHTTP3 */ + +/* if ngtcp2 is in use */ +/* #undef USE_NGTCP2 */ + /* if ngtcp2_crypto_gnutls is in use */ /* #undef USE_NGTCP2_CRYPTO_GNUTLS */ -/* if ngtcp2_crypto_openssl is in use */ -/* #undef USE_NGTCP2_CRYPTO_OPENSSL */ - +/* if ngtcp2_crypto_openssl is in use */ +/* #undef USE_NGTCP2_CRYPTO_OPENSSL */ + /* if NSS is enabled */ /* #undef USE_NSS */ @@ -1053,15 +1053,15 @@ /* if OpenSSL is in use */ #define USE_OPENSSL 1 -/* if quiche is in use */ -/* #undef USE_QUICHE */ +/* if quiche is in use */ +/* #undef USE_QUICHE */ /* to enable Windows native SSL/TLS support */ /* #undef USE_SCHANNEL */ -/* enable Secure Transport */ -/* #undef USE_SECTRANSP */ - +/* enable Secure Transport */ +/* #undef USE_SECTRANSP */ + /* if you want POSIX threaded DNS lookup */ /* #undef USE_THREADS_POSIX */ @@ -1094,9 +1094,9 @@ /* if wolfSSH is in use */ /* #undef USE_WOLFSSH */ -/* if wolfSSL is enabled */ -/* #undef USE_WOLFSSL */ - +/* if wolfSSL is enabled */ +/* #undef USE_WOLFSSL */ + /* Version number of package */ #define VERSION "-" diff --git a/contrib/libs/curl/lib/curl_config-osx.h b/contrib/libs/curl/lib/curl_config-osx.h index 6c61d83a3b..a18d7a75e7 100644 --- a/contrib/libs/curl/lib/curl_config-osx.h +++ b/contrib/libs/curl/lib/curl_config-osx.h @@ -25,9 +25,9 @@ /* to disable DICT */ /* #undef CURL_DISABLE_DICT */ -/* disable DoH */ -/* #undef CURL_DISABLE_DOH */ - +/* disable DoH */ +/* #undef CURL_DISABLE_DOH */ + /* to disable FILE */ /* #undef CURL_DISABLE_FILE */ @@ -40,9 +40,9 @@ /* to disable HTTP */ /* #undef CURL_DISABLE_HTTP */ -/* disable HTTP authentication */ -/* #undef CURL_DISABLE_HTTP_AUTH */ - +/* disable HTTP authentication */ +/* #undef CURL_DISABLE_HTTP_AUTH */ + /* to disable IMAP */ /* #undef CURL_DISABLE_IMAP */ @@ -55,33 +55,33 @@ /* to disable --libcurl C code generation option */ /* #undef CURL_DISABLE_LIBCURL_OPTION */ -/* disable mime API */ -/* #undef CURL_DISABLE_MIME */ - -/* disable netrc parsing */ -/* #undef CURL_DISABLE_NETRC */ - +/* disable mime API */ +/* #undef CURL_DISABLE_MIME */ + +/* disable netrc parsing */ +/* #undef CURL_DISABLE_NETRC */ + /* if the OpenSSL configuration won't be loaded automatically */ /* #undef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG */ -/* disable date parsing */ -/* #undef CURL_DISABLE_PARSEDATE */ - +/* disable date parsing */ +/* #undef CURL_DISABLE_PARSEDATE */ + /* to disable POP3 */ /* #undef CURL_DISABLE_POP3 */ -/* disable progress-meter */ -/* #undef CURL_DISABLE_PROGRESS_METER */ - +/* disable progress-meter */ +/* #undef CURL_DISABLE_PROGRESS_METER */ + /* to disable proxies */ /* #undef CURL_DISABLE_PROXY */ /* to disable RTSP */ /* #undef CURL_DISABLE_RTSP */ -/* disable DNS shuffling */ -/* #undef CURL_DISABLE_SHUFFLE_DNS */ - +/* disable DNS shuffling */ +/* #undef CURL_DISABLE_SHUFFLE_DNS */ + /* to disable SMB/CIFS */ /* #undef CURL_DISABLE_SMB */ @@ -269,9 +269,9 @@ /* Define to 1 if you have the `getpass_r' function. */ /* #undef HAVE_GETPASS_R */ -/* Define to 1 if you have the getpeername function. */ -#define HAVE_GETPEERNAME 1 - +/* Define to 1 if you have the getpeername function. */ +#define HAVE_GETPEERNAME 1 + /* Define to 1 if you have the `getppid' function. */ #define HAVE_GETPPID 1 @@ -287,9 +287,9 @@ /* Define to 1 if you have the getservbyport_r function. */ /* #undef HAVE_GETSERVBYPORT_R */ -/* Define to 1 if you have the getsockname function. */ -#define HAVE_GETSOCKNAME 1 - +/* Define to 1 if you have the getsockname function. */ +#define HAVE_GETSOCKNAME 1 + /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 @@ -485,17 +485,17 @@ #define HAVE_NET_IF_H 1 /* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */ -#define HAVE_NGHTTP2_NGHTTP2_H 1 - -/* Define to 1 if you have the <nghttp3/nghttp3.h> header file. */ -/* #undef HAVE_NGHTTP3_NGHTTP3_H */ - -/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto.h> header file. */ -/* #undef HAVE_NGTCP2_NGTCP2_CRYPTO_H */ - -/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */ -/* #undef HAVE_NGTCP2_NGTCP2_H */ - +#define HAVE_NGHTTP2_NGHTTP2_H 1 + +/* Define to 1 if you have the <nghttp3/nghttp3.h> header file. */ +/* #undef HAVE_NGHTTP3_NGHTTP3_H */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto.h> header file. */ +/* #undef HAVE_NGTCP2_NGTCP2_CRYPTO_H */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */ +/* #undef HAVE_NGTCP2_NGTCP2_H */ + /* if you have an old MIT Kerberos version, lacking GSS_C_NT_HOSTBASED_SERVICE */ /* #undef HAVE_OLD_GSSMIT */ @@ -518,9 +518,9 @@ /* Define to 1 if you have the <openssl/ssl.h> header file. */ #define HAVE_OPENSSL_SSL_H 1 -/* Define to 1 if you have the `OpenSSL_version' function. */ -#define HAVE_OPENSSL_VERSION 1 - +/* Define to 1 if you have the `OpenSSL_version' function. */ +#define HAVE_OPENSSL_VERSION 1 + /* Define to 1 if you have the <openssl/x509.h> header file. */ #define HAVE_OPENSSL_X509_H 1 @@ -545,18 +545,18 @@ /* Define to 1 if you have a working POSIX-style strerror_r function. */ #define HAVE_POSIX_STRERROR_R 1 -/* Define to 1 if you have the <proto/bsdsocket.h> header file. */ -/* #undef HAVE_PROTO_BSDSOCKET_H */ - +/* Define to 1 if you have the <proto/bsdsocket.h> header file. */ +/* #undef HAVE_PROTO_BSDSOCKET_H */ + /* if you have <pthread.h> */ #define HAVE_PTHREAD_H 1 /* Define to 1 if you have the <pwd.h> header file. */ #define HAVE_PWD_H 1 -/* Define to 1 if you have the <quiche.h> header file. */ -/* #undef HAVE_QUICHE_H */ - +/* Define to 1 if you have the <quiche.h> header file. */ +/* #undef HAVE_QUICHE_H */ + /* Define to 1 if you have the `RAND_egd' function. */ /* #undef HAVE_RAND_EGD */ @@ -627,7 +627,7 @@ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the `SSLv2_client_method' function. */ -/* #undef HAVE_SSLV2_CLIENT_METHOD */ +/* #undef HAVE_SSLV2_CLIENT_METHOD */ /* Define to 1 if you have the <ssl.h> header file. */ /* #undef HAVE_SSL_H */ @@ -752,9 +752,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 -/* Define to 1 if you have the `usleep' function. */ -#define HAVE_USLEEP 1 - +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + /* Define to 1 if you have the `utime' function. */ #define HAVE_UTIME 1 @@ -915,14 +915,14 @@ #define SIZEOF_CURL_OFF_T 8 /* The number of bytes in type int */ -#ifndef SIZEOF_INT -#error undefined SIZEOF_INT -#endif +#ifndef SIZEOF_INT +#error undefined SIZEOF_INT +#endif /* The number of bytes in type long */ -#ifndef SIZEOF_LONG -#error undefined SIZEOF_LONG -#endif +#ifndef SIZEOF_LONG +#error undefined SIZEOF_LONG +#endif /* The number of bytes in type long long */ /* #undef SIZEOF_LONG_LONG */ @@ -931,17 +931,17 @@ #define SIZEOF_OFF_T 8 /* The number of bytes in type short */ -#ifndef SIZEOF_SHORT -#error undefined SIZEOF_SHORT -#endif +#ifndef SIZEOF_SHORT +#error undefined SIZEOF_SHORT +#endif /* The number of bytes in type size_t */ -#ifndef SIZEOF_SIZE_T -#error undefined SIZEOF_SIZE_T -#endif +#ifndef SIZEOF_SIZE_T +#error undefined SIZEOF_SIZE_T +#endif /* The number of bytes in type time_t */ -#define SIZEOF_TIME_T SIZEOF_LONG +#define SIZEOF_TIME_T SIZEOF_LONG /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 @@ -952,12 +952,12 @@ /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ #define TIME_WITH_SYS_TIME 1 -/* to enable alt-svc */ -/* #undef USE_ALTSVC */ - -/* if AmiSSL is in use */ -/* #undef USE_AMISSL */ - +/* to enable alt-svc */ +/* #undef USE_ALTSVC */ + +/* if AmiSSL is in use */ +/* #undef USE_AMISSL */ + /* Define to enable c-ares support */ #define USE_ARES 1 @@ -992,17 +992,17 @@ /* #undef USE_METALINK */ /* if nghttp2 is in use */ -#define USE_NGHTTP2 1 - -/* if nghttp3 is in use */ -/* #undef USE_NGHTTP3 */ - -/* if ngtcp2 is in use */ -/* #undef USE_NGTCP2 */ - -/* if ngtcp2_crypto_openssl is in use */ -/* #undef USE_NGTCP2_CRYPTO_OPENSSL */ - +#define USE_NGHTTP2 1 + +/* if nghttp3 is in use */ +/* #undef USE_NGHTTP3 */ + +/* if ngtcp2 is in use */ +/* #undef USE_NGTCP2 */ + +/* if ngtcp2_crypto_openssl is in use */ +/* #undef USE_NGTCP2_CRYPTO_OPENSSL */ + /* if NSS is enabled */ /* #undef USE_NSS */ @@ -1012,15 +1012,15 @@ /* if OpenSSL is in use */ #define USE_OPENSSL 1 -/* if quiche is in use */ -/* #undef USE_QUICHE */ +/* if quiche is in use */ +/* #undef USE_QUICHE */ /* to enable Windows native SSL/TLS support */ /* #undef USE_SCHANNEL */ -/* enable Secure Transport */ -/* #undef USE_SECTRANSP */ - +/* enable Secure Transport */ +/* #undef USE_SECTRANSP */ + /* if you want POSIX threaded DNS lookup */ #define USE_THREADS_POSIX 1 @@ -1050,9 +1050,9 @@ /* to enable SSPI support */ /* #undef USE_WINDOWS_SSPI */ -/* if wolfSSL is enabled */ -/* #undef USE_WOLFSSL */ - +/* if wolfSSL is enabled */ +/* #undef USE_WOLFSSL */ + /* Version number of package */ #define VERSION "-" diff --git a/contrib/libs/curl/lib/curl_config-win.h b/contrib/libs/curl/lib/curl_config-win.h index 0b18d75b5c..0e02013b43 100644 --- a/contrib/libs/curl/lib/curl_config-win.h +++ b/contrib/libs/curl/lib/curl_config-win.h @@ -21,9 +21,9 @@ /* to disable DICT */ /* #undef CURL_DISABLE_DICT */ -/* disable DoH */ -/* #undef CURL_DISABLE_DOH */ - +/* disable DoH */ +/* #undef CURL_DISABLE_DOH */ + /* to disable FILE */ /* #undef CURL_DISABLE_FILE */ @@ -33,9 +33,9 @@ /* to disable GOPHER */ /* #undef CURL_DISABLE_GOPHER */ -/* disable HTTP authentication */ -/* #undef CURL_DISABLE_HTTP_AUTH */ - +/* disable HTTP authentication */ +/* #undef CURL_DISABLE_HTTP_AUTH */ + /* to disable IMAP */ /* #undef CURL_DISABLE_IMAP */ @@ -48,27 +48,27 @@ /* to disable LDAPS */ #define CURL_DISABLE_LDAPS 1 -/* to disable --libcurl C code generation option */ -/* #undef CURL_DISABLE_LIBCURL_OPTION */ - -/* disable mime API */ -/* #undef CURL_DISABLE_MIME */ - -/* disable netrc parsing */ -/* #undef CURL_DISABLE_NETRC */ - -/* if the OpenSSL configuration won't be loaded automatically */ -/* #undef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG */ - -/* disable date parsing */ -/* #undef CURL_DISABLE_PARSEDATE */ - +/* to disable --libcurl C code generation option */ +/* #undef CURL_DISABLE_LIBCURL_OPTION */ + +/* disable mime API */ +/* #undef CURL_DISABLE_MIME */ + +/* disable netrc parsing */ +/* #undef CURL_DISABLE_NETRC */ + +/* if the OpenSSL configuration won't be loaded automatically */ +/* #undef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG */ + +/* disable date parsing */ +/* #undef CURL_DISABLE_PARSEDATE */ + /* to disable POP3 */ /* #undef CURL_DISABLE_POP3 */ -/* disable progress-meter */ -/* #undef CURL_DISABLE_PROGRESS_METER */ - +/* disable progress-meter */ +/* #undef CURL_DISABLE_PROGRESS_METER */ + /* to disable proxies */ /* #undef CURL_DISABLE_PROXY */ @@ -78,9 +78,9 @@ /* to disable SMB */ /* #undef CURL_DISABLE_SMB */ -/* disable DNS shuffling */ -/* #undef CURL_DISABLE_SHUFFLE_DNS */ - +/* disable DNS shuffling */ +/* #undef CURL_DISABLE_SHUFFLE_DNS */ + /* to disable SMTP */ /* #undef CURL_DISABLE_SMTP */ @@ -253,9 +253,9 @@ /* Define to 1 if you have the `getpass_r' function. */ /* #undef HAVE_GETPASS_R */ -/* Define to 1 if you have the getpeername function. */ -#define HAVE_GETPEERNAME 1 - +/* Define to 1 if you have the getpeername function. */ +#define HAVE_GETPEERNAME 1 + /* Define to 1 if you have the `getppid' function. */ /* #undef HAVE_GETPPID */ @@ -274,9 +274,9 @@ /* Define to 1 if you have the getservbyport_r function. */ /* #undef HAVE_GETSERVBYPORT_R */ -/* Define to 1 if you have the getsockname function. */ -#define HAVE_GETSOCKNAME 1 - +/* Define to 1 if you have the getsockname function. */ +#define HAVE_GETSOCKNAME 1 + /* Define to 1 if you have the `gettimeofday' function. */ /* #undef HAVE_GETTIMEOFDAY */ @@ -470,18 +470,18 @@ /* Define to 1 if you have the <net/if.h> header file. */ /* #undef HAVE_NET_IF_H */ -/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */ -#define HAVE_NGHTTP2_NGHTTP2_H 1 - -/* Define to 1 if you have the <nghttp3/nghttp3.h> header file. */ -/* #undef HAVE_NGHTTP3_NGHTTP3_H */ - -/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto.h> header file. */ -/* #undef HAVE_NGTCP2_NGTCP2_CRYPTO_H */ - -/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */ -/* #undef HAVE_NGTCP2_NGTCP2_H */ - +/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */ +#define HAVE_NGHTTP2_NGHTTP2_H 1 + +/* Define to 1 if you have the <nghttp3/nghttp3.h> header file. */ +/* #undef HAVE_NGHTTP3_NGHTTP3_H */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto.h> header file. */ +/* #undef HAVE_NGTCP2_NGTCP2_CRYPTO_H */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */ +/* #undef HAVE_NGTCP2_NGTCP2_H */ + /* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */ /* #undef HAVE_OLD_GSSMIT */ @@ -506,9 +506,9 @@ /* Define to 1 if you have the <openssl/ssl.h> header file. */ /* #undef HAVE_OPENSSL_SSL_H */ -/* Define to 1 if you have the `OpenSSL_version' function. */ -#define HAVE_OPENSSL_VERSION 1 - +/* Define to 1 if you have the `OpenSSL_version' function. */ +#define HAVE_OPENSSL_VERSION 1 + /* Define to 1 if you have the <openssl/x509.h> header file. */ #define HAVE_OPENSSL_X509_H 1 @@ -533,18 +533,18 @@ /* Define to 1 if you have a working POSIX-style strerror_r function. */ /* #undef HAVE_POSIX_STRERROR_R */ -/* Define to 1 if you have the <proto/bsdsocket.h> header file. */ -/* #undef HAVE_PROTO_BSDSOCKET_H */ - +/* Define to 1 if you have the <proto/bsdsocket.h> header file. */ +/* #undef HAVE_PROTO_BSDSOCKET_H */ + /* Define to 1 if you have the <pthread.h> header file */ /* #undef HAVE_PTHREAD_H */ /* Define to 1 if you have the <pwd.h> header file. */ /* #undef HAVE_PWD_H */ -/* Define to 1 if you have the <quiche.h> header file. */ -/* #undef HAVE_QUICHE_H */ - +/* Define to 1 if you have the <quiche.h> header file. */ +/* #undef HAVE_QUICHE_H */ + /* Define to 1 if you have the `RAND_egd' function. */ /* #undef HAVE_RAND_EGD */ @@ -626,8 +626,8 @@ /* Define to 1 if you have the `socket' function. */ #define HAVE_SOCKET 1 -/* Define to 1 if you have the `SSLv2_client_method' function. */ -/* #undef HAVE_SSLV2_CLIENT_METHOD */ +/* Define to 1 if you have the `SSLv2_client_method' function. */ +/* #undef HAVE_SSLV2_CLIENT_METHOD */ /* Define to 1 if you have the <ssl.h> header file. */ /* #undef HAVE_SSL_H */ @@ -761,9 +761,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ /* #undef HAVE_UNISTD_H */ -/* Define to 1 if you have the `usleep' function. */ -#define HAVE_USLEEP 1 - +/* Define to 1 if you have the `usleep' function. */ +#define HAVE_USLEEP 1 + /* Define to 1 if you have the `utime' function. */ #define HAVE_UTIME 1 @@ -931,19 +931,19 @@ #define SEND_TYPE_RETV int /* The size of `int', as computed by sizeof. */ -#ifndef SIZEOF_INT -#error undefined SIZEOF_INT -#endif +#ifndef SIZEOF_INT +#error undefined SIZEOF_INT +#endif /* The size of `short', as computed by sizeof. */ -#ifndef SIZEOF_SHORT -#error undefined SIZEOF_SHORT -#endif +#ifndef SIZEOF_SHORT +#error undefined SIZEOF_SHORT +#endif /* The size of `long', as computed by sizeof. */ -#ifndef SIZEOF_LONG -#error undefined SIZEOF_LONG -#endif +#ifndef SIZEOF_LONG +#error undefined SIZEOF_LONG +#endif /* The size of `off_t', as computed by sizeof. */ #define SIZEOF_OFF_T 4 @@ -952,9 +952,9 @@ #define SIZEOF_CURL_OFF_T 8 /* The size of `size_t', as computed by sizeof. */ -#ifndef SIZEOF_SIZE_T -#error undefined SIZEOF_SIZE_T -#endif +#ifndef SIZEOF_SIZE_T +#error undefined SIZEOF_SIZE_T +#endif /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 8 @@ -968,14 +968,14 @@ /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ /* #undef TIME_WITH_SYS_TIME */ -/* to enable alt-svc */ -/* #undef USE_ALTSVC */ +/* to enable alt-svc */ +/* #undef USE_ALTSVC */ -/* if AmiSSL is in use */ -/* #undef USE_AMISSL */ +/* if AmiSSL is in use */ +/* #undef USE_AMISSL */ -/* Define to enable c-ares support */ -#define USE_ARES 1 +/* Define to enable c-ares support */ +#define USE_ARES 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ @@ -995,78 +995,78 @@ /* If you want to build curl with the built-in manual */ /* #undef USE_MANUAL */ -/* if mbedTLS is enabled */ -/* #undef USE_MBEDTLS */ - -/* if MesaLink is enabled */ -/* #undef USE_MESALINK */ - -/* Define to enable metalink support */ -/* #undef USE_METALINK */ - -/* to enable NGHTTP2 */ -/* #undef USE_NGHTTP2 */ - -/* if nghttp3 is in use */ -/* #undef USE_NGHTTP3 */ - -/* if ngtcp2 is in use */ -/* #undef USE_NGTCP2 */ - -/* if ngtcp2_crypto_openssl is in use */ -/* #undef USE_NGTCP2_CRYPTO_OPENSSL */ - +/* if mbedTLS is enabled */ +/* #undef USE_MBEDTLS */ + +/* if MesaLink is enabled */ +/* #undef USE_MESALINK */ + +/* Define to enable metalink support */ +/* #undef USE_METALINK */ + +/* to enable NGHTTP2 */ +/* #undef USE_NGHTTP2 */ + +/* if nghttp3 is in use */ +/* #undef USE_NGHTTP3 */ + +/* if ngtcp2 is in use */ +/* #undef USE_NGTCP2 */ + +/* if ngtcp2_crypto_openssl is in use */ +/* #undef USE_NGTCP2_CRYPTO_OPENSSL */ + /* if NSS is enabled */ /* #undef USE_NSS */ -/* Use OpenLDAP-specific code */ +/* Use OpenLDAP-specific code */ /* #undef USE_OPENLDAP */ /* if OpenSSL is in use */ #define USE_OPENSSL 1 -/* if quiche is in use */ -/* #undef USE_QUICHE */ - -/* to enable Windows SSL */ -/* #undef USE_SCHANNEL */ - -/* enable Secure Transport */ -/* #undef USE_SECTRANSP */ - -/* Define if you want to enable POSIX threaded DNS lookup */ -/* #undef USE_THREADS_POSIX */ - -/* Define if you want to enable WIN32 threaded DNS lookup */ -/* #undef USE_THREADS_WIN32 */ - -/* Use TLS-SRP authentication */ -#define USE_TLS_SRP 1 - +/* if quiche is in use */ +/* #undef USE_QUICHE */ + +/* to enable Windows SSL */ +/* #undef USE_SCHANNEL */ + +/* enable Secure Transport */ +/* #undef USE_SECTRANSP */ + +/* Define if you want to enable POSIX threaded DNS lookup */ +/* #undef USE_THREADS_POSIX */ + +/* Define if you want to enable WIN32 threaded DNS lookup */ +/* #undef USE_THREADS_WIN32 */ + +/* Use TLS-SRP authentication */ +#define USE_TLS_SRP 1 + /* if Unix domain sockets are enabled */ /* #undef USE_UNIX_SOCKETS */ -/* enable multiple SSL backends */ -/* #undef CURL_WITH_MULTI_SSL */ - -/* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */ -/* #undef USE_WIN32_IDN */ - +/* enable multiple SSL backends */ +/* #undef CURL_WITH_MULTI_SSL */ + +/* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */ +/* #undef USE_WIN32_IDN */ + /* Define to 1 if you are building a Windows target with large file support. */ #define USE_WIN32_LARGE_FILES 1 -/* Use Windows LDAP implementation */ -/* #undef USE_WIN32_LDAP */ - -/* Define to 1 if you are building a Windows target without large file - support. */ -/* #undef USE_WIN32_SMALL_FILES */ - +/* Use Windows LDAP implementation */ +/* #undef USE_WIN32_LDAP */ + +/* Define to 1 if you are building a Windows target without large file + support. */ +/* #undef USE_WIN32_SMALL_FILES */ + /* to enable SSPI support */ /* #undef USE_WINDOWS_SSPI */ -/* if wolfSSL is enabled */ -/* #undef USE_WOLFSSL */ +/* if wolfSSL is enabled */ +/* #undef USE_WOLFSSL */ /* Version number of package */ /* #undef VERSION */ diff --git a/contrib/libs/curl/lib/curl_config.h b/contrib/libs/curl/lib/curl_config.h index b81f7b33d5..e58dec7079 100644 --- a/contrib/libs/curl/lib/curl_config.h +++ b/contrib/libs/curl/lib/curl_config.h @@ -1,21 +1,21 @@ #pragma once -#include <util/system/platform.h> - -#if defined(__ANDROID__) && defined(MAPSMOBI_BUILD) -# include "curl_config-android-maps-mobile.h" -#elif defined(__ANDROID__) -# include "curl_config-android.h" -#elif defined(__IOS__) && defined(MAPSMOBI_BUILD) -# include "curl_config-ios-maps-mobile.h" -#elif defined(__IOS__) -# include "curl_config-ios.h" -#elif defined(__APPLE__) -# include "curl_config-osx.h" -#elif defined(_MSC_VER) -# include "curl_config-win.h" -#else -# include "curl_config-linux.h" +#include <util/system/platform.h> + +#if defined(__ANDROID__) && defined(MAPSMOBI_BUILD) +# include "curl_config-android-maps-mobile.h" +#elif defined(__ANDROID__) +# include "curl_config-android.h" +#elif defined(__IOS__) && defined(MAPSMOBI_BUILD) +# include "curl_config-ios-maps-mobile.h" +#elif defined(__IOS__) +# include "curl_config-ios.h" +#elif defined(__APPLE__) +# include "curl_config-osx.h" +#elif defined(_MSC_VER) +# include "curl_config-win.h" +#else +# include "curl_config-linux.h" #endif #if defined(_musl_) @@ -24,7 +24,7 @@ // Do not misrepresent host on Android and iOS. #undef OS -#define OS "arcadia" +#define OS "arcadia" // c-ares resolver is known to be buggy. // diff --git a/contrib/libs/curl/lib/curl_endian.c b/contrib/libs/curl/lib/curl_endian.c index 740ec733dc..2fc25bc173 100644 --- a/contrib/libs/curl/lib/curl_endian.c +++ b/contrib/libs/curl/lib/curl_endian.c @@ -83,7 +83,7 @@ unsigned short Curl_read16_be(const unsigned char *buf) #if (CURL_SIZEOF_CURL_OFF_T > 4) /* - * write32_le() + * write32_le() * * This function converts a 32-bit integer from the native endian format, * to little endian format ready for sending down the wire. @@ -93,7 +93,7 @@ unsigned short Curl_read16_be(const unsigned char *buf) * value [in] - The 32-bit integer value. * buffer [in] - A pointer to the output buffer. */ -static void write32_le(const int value, unsigned char *buffer) +static void write32_le(const int value, unsigned char *buffer) { buffer[0] = (char)(value & 0x000000FF); buffer[1] = (char)((value & 0x0000FF00) >> 8); @@ -118,7 +118,7 @@ void Curl_write64_le(const long long value, unsigned char *buffer) void Curl_write64_le(const __int64 value, unsigned char *buffer) #endif { - write32_le((int)value, buffer); - write32_le((int)(value >> 32), buffer + 4); + write32_le((int)value, buffer); + write32_le((int)(value >> 32), buffer + 4); } #endif /* CURL_SIZEOF_CURL_OFF_T > 4 */ diff --git a/contrib/libs/curl/lib/curl_fnmatch.c b/contrib/libs/curl/lib/curl_fnmatch.c index fa9f7b95c5..4bfa58598e 100644 --- a/contrib/libs/curl/lib/curl_fnmatch.c +++ b/contrib/libs/curl/lib/curl_fnmatch.c @@ -21,7 +21,7 @@ ***************************************************************************/ #include "curl_setup.h" -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP #include <curl/curl.h> #include "curl_fnmatch.h" @@ -385,5 +385,5 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string) } #endif - -#endif /* if FTP is disabled */ + +#endif /* if FTP is disabled */ diff --git a/contrib/libs/curl/lib/curl_get_line.c b/contrib/libs/curl/lib/curl_get_line.c index 1cceeaa114..438ede7046 100644 --- a/contrib/libs/curl/lib/curl_get_line.c +++ b/contrib/libs/curl/lib/curl_get_line.c @@ -1,60 +1,60 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + #if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \ defined(USE_HSTS) -#include "curl_get_line.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * get_line() makes sure to only return complete whole lines that fit in 'len' - * bytes and end with a newline. - */ -char *Curl_get_line(char *buf, int len, FILE *input) -{ - bool partial = FALSE; - while(1) { - char *b = fgets(buf, len, input); - if(b) { - size_t rlen = strlen(b); - if(rlen && (b[rlen-1] == '\n')) { - if(partial) { - partial = FALSE; - continue; - } - return b; - } - /* read a partial, discard the next piece that ends with newline */ - partial = TRUE; - } - else - break; - } - return NULL; -} +#include "curl_get_line.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * get_line() makes sure to only return complete whole lines that fit in 'len' + * bytes and end with a newline. + */ +char *Curl_get_line(char *buf, int len, FILE *input) +{ + bool partial = FALSE; + while(1) { + char *b = fgets(buf, len, input); + if(b) { + size_t rlen = strlen(b); + if(rlen && (b[rlen-1] == '\n')) { + if(partial) { + partial = FALSE; + continue; + } + return b; + } + /* read a partial, discard the next piece that ends with newline */ + partial = TRUE; + } + else + break; + } + return NULL; +} #endif /* if not disabled */ diff --git a/contrib/libs/curl/lib/curl_get_line.h b/contrib/libs/curl/lib/curl_get_line.h index ef1f8126d8..597aa09a9c 100644 --- a/contrib/libs/curl/lib/curl_get_line.h +++ b/contrib/libs/curl/lib/curl_get_line.h @@ -1,29 +1,29 @@ -#ifndef HEADER_CURL_GET_LINE_H -#define HEADER_CURL_GET_LINE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +#ifndef HEADER_CURL_GET_LINE_H +#define HEADER_CURL_GET_LINE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* get_line() makes sure to only return complete whole lines that fit in 'len' - * bytes and end with a newline. */ -char *Curl_get_line(char *buf, int len, FILE *input); - -#endif /* HEADER_CURL_GET_LINE_H */ + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* get_line() makes sure to only return complete whole lines that fit in 'len' + * bytes and end with a newline. */ +char *Curl_get_line(char *buf, int len, FILE *input); + +#endif /* HEADER_CURL_GET_LINE_H */ diff --git a/contrib/libs/curl/lib/curl_md4.h b/contrib/libs/curl/lib/curl_md4.h index e09d0d74ad..f9dafcb53c 100644 --- a/contrib/libs/curl/lib/curl_md4.h +++ b/contrib/libs/curl/lib/curl_md4.h @@ -24,13 +24,13 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_CRYPTO_AUTH) +#if !defined(CURL_DISABLE_CRYPTO_AUTH) + +#define MD4_DIGEST_LENGTH 16 -#define MD4_DIGEST_LENGTH 16 - void Curl_md4it(unsigned char *output, const unsigned char *input, const size_t len); -#endif /* !defined(CURL_DISABLE_CRYPTO_AUTH) */ +#endif /* !defined(CURL_DISABLE_CRYPTO_AUTH) */ #endif /* HEADER_CURL_MD4_H */ diff --git a/contrib/libs/curl/lib/curl_md5.h b/contrib/libs/curl/lib/curl_md5.h index fd6e292363..5739c89ca4 100644 --- a/contrib/libs/curl/lib/curl_md5.h +++ b/contrib/libs/curl/lib/curl_md5.h @@ -54,8 +54,8 @@ void Curl_md5it(unsigned char *output, const unsigned char *input, struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params); CURLcode Curl_MD5_update(struct MD5_context *context, - const unsigned char *data, - unsigned int len); + const unsigned char *data, + unsigned int len); CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result); #endif diff --git a/contrib/libs/curl/lib/curl_memory.h b/contrib/libs/curl/lib/curl_memory.h index de050e7a9d..5806290637 100644 --- a/contrib/libs/curl/lib/curl_memory.h +++ b/contrib/libs/curl/lib/curl_memory.h @@ -39,7 +39,7 @@ * * File lib/strdup.c is an exception, given that it provides a strdup * clone implementation while using malloc. Extra care needed inside - * this one. + * this one. * * The need for curl_memory.h inclusion is due to libcurl's feature * of allowing library user to provide memory replacement functions, diff --git a/contrib/libs/curl/lib/curl_ntlm_core.c b/contrib/libs/curl/lib/curl_ntlm_core.c index a6c2e73b87..b35b566a71 100644 --- a/contrib/libs/curl/lib/curl_ntlm_core.c +++ b/contrib/libs/curl/lib/curl_ntlm_core.c @@ -38,7 +38,7 @@ 3. USE_GNUTLS 4. USE_NSS 5. USE_MBEDTLS - 6. USE_SECTRANSP + 6. USE_SECTRANSP 7. USE_OS400CRYPTO 8. USE_WIN32_CRYPTO @@ -91,9 +91,9 @@ #elif defined(USE_MBEDTLS) # error #include <mbedtls/des.h> -# include "curl_md4.h" +# include "curl_md4.h" -#elif defined(USE_SECTRANSP) +#elif defined(USE_SECTRANSP) # include <CommonCrypto/CommonCryptor.h> # include <CommonCrypto/CommonDigest.h> @@ -115,7 +115,7 @@ #include "warnless.h" #include "curl_endian.h" #include "curl_des.h" -#include "curl_md4.h" +#include "curl_md4.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -216,7 +216,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out, bool rv = FALSE; /* use internal slot for DES encryption (requires NSS to be initialized) */ - PK11SlotInfo *slot = PK11_GetInternalKeySlot(); + PK11SlotInfo *slot = PK11_GetInternalKeySlot(); if(!slot) return FALSE; @@ -280,7 +280,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out, return mbedtls_des_crypt_ecb(&ctx, in, out) == 0; } -#elif defined(USE_SECTRANSP) +#elif defined(USE_SECTRANSP) static bool encrypt_des(const unsigned char *in, unsigned char *out, const unsigned char *key_56) @@ -427,7 +427,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, setup_des_key(keys + 14, &des); gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8); gcry_cipher_close(des); -#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ +#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) encrypt_des(plaintext, results, keys); encrypt_des(plaintext, results + 8, keys + 7); @@ -491,7 +491,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data, setup_des_key(pw + 7, &des); gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8); gcry_cipher_close(des); -#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ +#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) encrypt_des(magic, lmbuffer, pw); encrypt_des(magic, lmbuffer + 8, pw + 7); @@ -541,7 +541,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data, CURLcode result; if(len > SIZE_T_MAX/2) /* avoid integer overflow */ return CURLE_OUT_OF_MEMORY; - pw = len ? malloc(len * 2) : (unsigned char *)strdup(""); + pw = len ? malloc(len * 2) : (unsigned char *)strdup(""); if(!pw) return CURLE_OUT_OF_MEMORY; @@ -555,10 +555,10 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data, if(result) return result; - /* Create NT hashed password. */ - Curl_md4it(ntbuffer, pw, 2 * len); + /* Create NT hashed password. */ + Curl_md4it(ntbuffer, pw, 2 * len); - memset(ntbuffer + 16, 0, 21 - 16); + memset(ntbuffer + 16, 0, 21 - 16); free(pw); @@ -680,7 +680,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */ memcpy(ptr + 8, &ntlm->nonce[0], 8); result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8, - NTLMv2_BLOB_LEN + 8, hmac_output); + NTLMv2_BLOB_LEN + 8, hmac_output); if(result) { free(ptr); return result; diff --git a/contrib/libs/curl/lib/curl_ntlm_wb.c b/contrib/libs/curl/lib/curl_ntlm_wb.c index d59c55ecfc..c11757f557 100644 --- a/contrib/libs/curl/lib/curl_ntlm_wb.c +++ b/contrib/libs/curl/lib/curl_ntlm_wb.c @@ -53,8 +53,8 @@ #include "url.h" #include "strerror.h" #include "strdup.h" -#include "strcase.h" - +#include "strcase.h" + /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -125,7 +125,7 @@ static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, struct passwd pw, *pw_res; char pwbuf[1024]; #endif - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; #if defined(CURL_DISABLE_VERBOSE_STRINGS) (void) data; @@ -185,13 +185,13 @@ static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, if(access(ntlm_auth, X_OK) != 0) { failf(data, "Could not access ntlm_auth: %s errno %d: %s", - ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer))); + ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer))); goto done; } if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) { failf(data, "Could not open socket pair. errno %d: %s", - errno, Curl_strerror(errno, buffer, sizeof(buffer))); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); goto done; } @@ -200,7 +200,7 @@ static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, sclose(sockfds[0]); sclose(sockfds[1]); failf(data, "Could not fork. errno %d: %s", - errno, Curl_strerror(errno, buffer, sizeof(buffer))); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); goto done; } else if(!child_pid) { @@ -212,13 +212,13 @@ static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, sclose_nolog(sockfds[0]); if(dup2(sockfds[1], STDIN_FILENO) == -1) { failf(data, "Could not redirect child stdin. errno %d: %s", - errno, Curl_strerror(errno, buffer, sizeof(buffer))); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); exit(1); } if(dup2(sockfds[1], STDOUT_FILENO) == -1) { failf(data, "Could not redirect child stdout. errno %d: %s", - errno, Curl_strerror(errno, buffer, sizeof(buffer))); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); exit(1); } @@ -238,7 +238,7 @@ static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, sclose_nolog(sockfds[1]); failf(data, "Could not execl(). errno %d: %s", - errno, Curl_strerror(errno, buffer, sizeof(buffer))); + errno, Curl_strerror(errno, buffer, sizeof(buffer))); exit(1); } @@ -329,49 +329,49 @@ done: return CURLE_REMOTE_ACCESS_DENIED; } -CURLcode Curl_input_ntlm_wb(struct connectdata *conn, - bool proxy, - const char *header) -{ +CURLcode Curl_input_ntlm_wb(struct connectdata *conn, + bool proxy, + const char *header) +{ struct ntlmdata *ntlm = proxy ? &conn->proxyntlm : &conn->ntlm; - curlntlm *state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state; - - if(!checkprefix("NTLM", header)) - return CURLE_BAD_CONTENT_ENCODING; - - header += strlen("NTLM"); - while(*header && ISSPACE(*header)) - header++; - - if(*header) { + curlntlm *state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state; + + if(!checkprefix("NTLM", header)) + return CURLE_BAD_CONTENT_ENCODING; + + header += strlen("NTLM"); + while(*header && ISSPACE(*header)) + header++; + + if(*header) { ntlm->challenge = strdup(header); if(!ntlm->challenge) - return CURLE_OUT_OF_MEMORY; - - *state = NTLMSTATE_TYPE2; /* We got a type-2 message */ - } - else { - if(*state == NTLMSTATE_LAST) { - infof(conn->data, "NTLM auth restarted\n"); - Curl_http_auth_cleanup_ntlm_wb(conn); - } - else if(*state == NTLMSTATE_TYPE3) { - infof(conn->data, "NTLM handshake rejected\n"); - Curl_http_auth_cleanup_ntlm_wb(conn); - *state = NTLMSTATE_NONE; - return CURLE_REMOTE_ACCESS_DENIED; - } - else if(*state >= NTLMSTATE_TYPE1) { - infof(conn->data, "NTLM handshake failure (internal error)\n"); - return CURLE_REMOTE_ACCESS_DENIED; - } - - *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */ - } - - return CURLE_OK; -} - + return CURLE_OUT_OF_MEMORY; + + *state = NTLMSTATE_TYPE2; /* We got a type-2 message */ + } + else { + if(*state == NTLMSTATE_LAST) { + infof(conn->data, "NTLM auth restarted\n"); + Curl_http_auth_cleanup_ntlm_wb(conn); + } + else if(*state == NTLMSTATE_TYPE3) { + infof(conn->data, "NTLM handshake rejected\n"); + Curl_http_auth_cleanup_ntlm_wb(conn); + *state = NTLMSTATE_NONE; + return CURLE_REMOTE_ACCESS_DENIED; + } + else if(*state >= NTLMSTATE_TYPE1) { + infof(conn->data, "NTLM handshake failure (internal error)\n"); + return CURLE_REMOTE_ACCESS_DENIED; + } + + *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */ + } + + return CURLE_OK; +} + /* * This is for creating ntlm header output by delegating challenge/response * to Samba's winbind daemon helper ntlm_auth. @@ -384,7 +384,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy) /* point to the name and password for this */ const char *userp; struct ntlmdata *ntlm; - curlntlm *state; + curlntlm *state; struct auth *authp; struct Curl_easy *data = conn->data; @@ -398,7 +398,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy) allocuserpwd = &data->state.aptr.proxyuserpwd; userp = conn->http_proxy.user; ntlm = &conn->proxyntlm; - state = &conn->proxy_ntlm_state; + state = &conn->proxy_ntlm_state; authp = &conn->data->state.authproxy; #else return CURLE_NOT_BUILT_IN; @@ -408,7 +408,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy) allocuserpwd = &data->state.aptr.userpwd; userp = conn->user; ntlm = &conn->ntlm; - state = &conn->http_ntlm_state; + state = &conn->http_ntlm_state; authp = &conn->data->state.authhost; } authp->done = FALSE; @@ -417,7 +417,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy) if(!userp) userp = ""; - switch(*state) { + switch(*state) { case NTLMSTATE_TYPE1: default: /* Use Samba's 'winbind' daemon to support NTLM authentication, @@ -449,7 +449,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy) if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; break; - + case NTLMSTATE_TYPE2: { char *input = aprintf("TT %s\n", ntlm->challenge); if(!input) @@ -464,9 +464,9 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy) proxy ? "Proxy-" : "", ntlm->response); DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); - *state = NTLMSTATE_TYPE3; /* we sent a type-3 */ + *state = NTLMSTATE_TYPE3; /* we sent a type-3 */ authp->done = TRUE; - Curl_http_auth_cleanup_ntlm_wb(conn); + Curl_http_auth_cleanup_ntlm_wb(conn); if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; break; @@ -474,10 +474,10 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy) case NTLMSTATE_TYPE3: /* connection is already authenticated, * don't send a header in future requests */ - *state = NTLMSTATE_LAST; - /* FALLTHROUGH */ - case NTLMSTATE_LAST: - Curl_safefree(*allocuserpwd); + *state = NTLMSTATE_LAST; + /* FALLTHROUGH */ + case NTLMSTATE_LAST: + Curl_safefree(*allocuserpwd); authp->done = TRUE; break; } diff --git a/contrib/libs/curl/lib/curl_ntlm_wb.h b/contrib/libs/curl/lib/curl_ntlm_wb.h index d7885000ea..4f847d22ca 100644 --- a/contrib/libs/curl/lib/curl_ntlm_wb.h +++ b/contrib/libs/curl/lib/curl_ntlm_wb.h @@ -27,14 +27,14 @@ #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ defined(NTLM_WB_ENABLED) -/* this is for ntlm header input */ -CURLcode Curl_input_ntlm_wb(struct connectdata *conn, bool proxy, - const char *header); - -/* this is for creating ntlm header output */ +/* this is for ntlm header input */ +CURLcode Curl_input_ntlm_wb(struct connectdata *conn, bool proxy, + const char *header); + +/* this is for creating ntlm header output */ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy); -void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn); +void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn); #endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */ diff --git a/contrib/libs/curl/lib/curl_path.c b/contrib/libs/curl/lib/curl_path.c index 445afd872e..8c8cbc2468 100644 --- a/contrib/libs/curl/lib/curl_path.c +++ b/contrib/libs/curl/lib/curl_path.c @@ -22,8 +22,8 @@ #include "curl_setup.h" -#if defined(USE_SSH) - +#if defined(USE_SSH) + #include <curl/curl.h> #include "curl_memory.h" #include "curl_path.h" @@ -55,7 +55,7 @@ CURLcode Curl_getworkingpath(struct connectdata *conn, } if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) /* It is referenced to the home directory, so strip the leading '/~/' */ - memcpy(real_path, working_path + 3, working_path_len - 2); + memcpy(real_path, working_path + 3, working_path_len - 2); else memcpy(real_path, working_path, 1 + working_path_len); } @@ -195,5 +195,5 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) Curl_safefree(*path); return CURLE_QUOTE_ERROR; } - -#endif /* if SSH is used */ + +#endif /* if SSH is used */ diff --git a/contrib/libs/curl/lib/curl_rtmp.c b/contrib/libs/curl/lib/curl_rtmp.c index 66a007cca4..ba471a2a19 100644 --- a/contrib/libs/curl/lib/curl_rtmp.c +++ b/contrib/libs/curl/lib/curl_rtmp.c @@ -205,13 +205,13 @@ static CURLcode rtmp_setup_connection(struct connectdata *conn) RTMP_Free(r); return CURLE_URL_MALFORMAT; } - conn->proto.rtmp = r; + conn->proto.rtmp = r; return CURLE_OK; } static CURLcode rtmp_connect(struct connectdata *conn, bool *done) { - RTMP *r = conn->proto.rtmp; + RTMP *r = conn->proto.rtmp; SET_RCVTIMEO(tv, 10); r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET]; @@ -245,18 +245,18 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done) static CURLcode rtmp_do(struct connectdata *conn, bool *done) { - struct Curl_easy *data = conn->data; - RTMP *r = conn->proto.rtmp; + struct Curl_easy *data = conn->data; + RTMP *r = conn->proto.rtmp; if(!RTMP_ConnectStream(r, 0)) return CURLE_FAILED_INIT; if(conn->data->set.upload) { - Curl_pgrsSetUploadSize(data, data->state.infilesize); - Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + Curl_pgrsSetUploadSize(data, data->state.infilesize); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); } else - Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); *done = TRUE; return CURLE_OK; } @@ -274,10 +274,10 @@ static CURLcode rtmp_done(struct connectdata *conn, CURLcode status, static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead_connection) { - RTMP *r = conn->proto.rtmp; + RTMP *r = conn->proto.rtmp; (void)dead_connection; if(r) { - conn->proto.rtmp = NULL; + conn->proto.rtmp = NULL; RTMP_Close(r); RTMP_Free(r); } @@ -287,7 +287,7 @@ static CURLcode rtmp_disconnect(struct connectdata *conn, static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err) { - RTMP *r = conn->proto.rtmp; + RTMP *r = conn->proto.rtmp; ssize_t nread; (void)sockindex; /* unused */ @@ -308,7 +308,7 @@ static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf, static ssize_t rtmp_send(struct connectdata *conn, int sockindex, const void *buf, size_t len, CURLcode *err) { - RTMP *r = conn->proto.rtmp; + RTMP *r = conn->proto.rtmp; ssize_t num; (void)sockindex; /* unused */ diff --git a/contrib/libs/curl/lib/curl_sasl.c b/contrib/libs/curl/lib/curl_sasl.c index 0c7165c9f3..94b17a1d86 100644 --- a/contrib/libs/curl/lib/curl_sasl.c +++ b/contrib/libs/curl/lib/curl_sasl.c @@ -31,9 +31,9 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_POP3) - +#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_POP3) + #include <curl/curl.h> #include "urldata.h" @@ -86,14 +86,14 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) #if defined(USE_KERBEROS5) /* Cleanup the gssapi structure */ if(authused == SASL_MECH_GSSAPI) { - Curl_auth_cleanup_gssapi(&conn->krb5); + Curl_auth_cleanup_gssapi(&conn->krb5); } #endif #if defined(USE_NTLM) /* Cleanup the NTLM structure */ if(authused == SASL_MECH_NTLM) { - Curl_auth_cleanup_ntlm(&conn->ntlm); + Curl_auth_cleanup_ntlm(&conn->ntlm); } #endif @@ -299,7 +299,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, #if defined(USE_KERBEROS5) if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() && Curl_auth_user_contains_domain(conn->user)) { - sasl->mutual_auth = FALSE; + sasl->mutual_auth = FALSE; mech = SASL_MECH_STRING_GSSAPI; state1 = SASL_GSSAPI; state2 = SASL_GSSAPI_TOKEN; @@ -309,7 +309,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, result = Curl_auth_create_gssapi_user_message(data, conn->user, conn->passwd, service, - data->conn->host.name, + data->conn->host.name, sasl->mutual_auth, NULL, &conn->krb5, &resp, &len); @@ -366,9 +366,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, sasl->authused = SASL_MECH_XOAUTH2; if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_xoauth_bearer_message(data, conn->user, + result = Curl_auth_create_xoauth_bearer_message(data, conn->user, oauth_bearer, - &resp, &len); + &resp, &len); } else if(enabledmechs & SASL_MECH_PLAIN) { mech = SASL_MECH_STRING_PLAIN; @@ -376,8 +376,8 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, sasl->authused = SASL_MECH_PLAIN; if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_plain_message(data, conn->sasl_authzid, - conn->user, conn->passwd, + result = Curl_auth_create_plain_message(data, conn->sasl_authzid, + conn->user, conn->passwd, &resp, &len); } else if(enabledmechs & SASL_MECH_LOGIN) { @@ -466,9 +466,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, *progress = SASL_DONE; return result; case SASL_PLAIN: - result = Curl_auth_create_plain_message(data, conn->sasl_authzid, - conn->user, conn->passwd, - &resp, &len); + result = Curl_auth_create_plain_message(data, conn->sasl_authzid, + conn->user, conn->passwd, + &resp, &len); break; case SASL_LOGIN: result = Curl_auth_create_login_message(data, conn->user, &resp, &len); @@ -531,7 +531,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, result = Curl_auth_create_gssapi_user_message(data, conn->user, conn->passwd, service, - data->conn->host.name, + data->conn->host.name, sasl->mutual_auth, NULL, &conn->krb5, &resp, &len); @@ -577,9 +577,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, newstate = SASL_OAUTH2_RESP; } else - result = Curl_auth_create_xoauth_bearer_message(data, conn->user, + result = Curl_auth_create_xoauth_bearer_message(data, conn->user, oauth_bearer, - &resp, &len); + &resp, &len); break; case SASL_OAUTH2_RESP: @@ -640,4 +640,4 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, return result; } -#endif /* protocols are enabled that use SASL */ +#endif /* protocols are enabled that use SASL */ diff --git a/contrib/libs/curl/lib/curl_setup.h b/contrib/libs/curl/lib/curl_setup.h index 8edd47ac51..83fabb0e01 100644 --- a/contrib/libs/curl/lib/curl_setup.h +++ b/contrib/libs/curl/lib/curl_setup.h @@ -99,10 +99,10 @@ # include "config-vxworks.h" #endif -#ifdef __PLAN9__ -# include "config-plan9.h" -#endif - +#ifdef __PLAN9__ +# include "config-plan9.h" +#endif + #endif /* HAVE_CONFIG_H */ /* ================================================================ */ @@ -273,13 +273,13 @@ #endif #ifdef __AMIGA__ -# include <exec/types.h> -# include <exec/execbase.h> -# include <proto/exec.h> -# include <proto/dos.h> +# include <exec/types.h> +# include <exec/execbase.h> +# include <proto/exec.h> +# include <proto/dos.h> # include <unistd.h> -# ifdef HAVE_PROTO_BSDSOCKET_H -# error #include <proto/bsdsocket.h> /* ensure bsdsocket.library use */ +# ifdef HAVE_PROTO_BSDSOCKET_H +# error #include <proto/bsdsocket.h> /* ensure bsdsocket.library use */ # define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0) # endif /* @@ -609,8 +609,8 @@ int netware_init(void); #define LIBIDN_REQUIRED_VERSION "0.4.1" #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ - defined(USE_MBEDTLS) || \ - defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ + defined(USE_MBEDTLS) || \ + defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) || \ defined(USE_BEARSSL) #define USE_SSL /* SSL support has been enabled */ @@ -653,10 +653,10 @@ int netware_init(void); #error "No longer supported. Set CURLOPT_CAINFO at runtime instead." #endif -#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH) -#define USE_SSH -#endif - +#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH) +#define USE_SSH +#endif + /* * Provide a mechanism to silence picky compilers, such as gcc 4.6+. * Parameters should of course normally not be unused, but for example when @@ -788,14 +788,14 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result); #endif -#ifdef DEBUGBUILD -#define UNITTEST -#else -#define UNITTEST static -#endif - -#if defined(USE_NGTCP2) || defined(USE_QUICHE) -#define ENABLE_QUIC -#endif - +#ifdef DEBUGBUILD +#define UNITTEST +#else +#define UNITTEST static +#endif + +#if defined(USE_NGTCP2) || defined(USE_QUICHE) +#define ENABLE_QUIC +#endif + #endif /* HEADER_CURL_SETUP_H */ diff --git a/contrib/libs/curl/lib/dict.c b/contrib/libs/curl/lib/dict.c index 1cd4e5428e..15d3954aa3 100644 --- a/contrib/libs/curl/lib/dict.c +++ b/contrib/libs/curl/lib/dict.c @@ -247,7 +247,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) failf(data, "Failed sending DICT request"); return result; } - Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); /* no upload */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); /* no upload */ } else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || @@ -293,7 +293,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) failf(data, "Failed sending DICT request"); return result; } - Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); } else { @@ -315,7 +315,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done) return result; } - Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); } } diff --git a/contrib/libs/curl/lib/doh.c b/contrib/libs/curl/lib/doh.c index c0d480da6f..c2b76de53a 100644 --- a/contrib/libs/curl/lib/doh.c +++ b/contrib/libs/curl/lib/doh.c @@ -22,8 +22,8 @@ #include "curl_setup.h" -#ifndef CURL_DISABLE_DOH - +#ifndef CURL_DISABLE_DOH + #include "urldata.h" #include "curl_addrinfo.h" #include "doh.h" @@ -192,7 +192,7 @@ static int Curl_doh_done(struct Curl_easy *doh, CURLcode result) struct Curl_easy *data = doh->set.dohfor; /* so one of the DOH request done for the 'data' transfer is now complete! */ data->req.doh.pending--; - infof(data, "a DOH request is completed, %u to go\n", data->req.doh.pending); + infof(data, "a DOH request is completed, %u to go\n", data->req.doh.pending); if(result) infof(data, "DOH request %s\n", curl_easy_strerror(result)); @@ -205,11 +205,11 @@ static int Curl_doh_done(struct Curl_easy *doh, CURLcode result) return 0; } -#define ERROR_CHECK_SETOPT(x,y) \ -do { \ - result = curl_easy_setopt(doh, x, y); \ - if(result) \ - goto error; \ +#define ERROR_CHECK_SETOPT(x,y) \ +do { \ + result = curl_easy_setopt(doh, x, y); \ + if(result) \ + goto error; \ } while(0) static CURLcode dohprobe(struct Curl_easy *data, @@ -281,20 +281,20 @@ static CURLcode dohprobe(struct Curl_easy *data, ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); #endif ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); - if(data->set.verbose) - ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); - if(data->set.no_signal) - ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L); - - /* Inherit *some* SSL options from the user's transfer. This is a - best-guess as to which options are needed for compatibility. #3661 */ - if(data->set.ssl.falsestart) - ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); - if(data->set.ssl.primary.verifyhost) - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L); + if(data->set.verbose) + ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); + if(data->set.no_signal) + ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L); + + /* Inherit *some* SSL options from the user's transfer. This is a + best-guess as to which options are needed for compatibility. #3661 */ + if(data->set.ssl.falsestart) + ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); + if(data->set.ssl.primary.verifyhost) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L); #ifndef CURL_DISABLE_PROXY - if(data->set.proxy_ssl.primary.verifyhost) - ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L); + if(data->set.proxy_ssl.primary.verifyhost) + ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L); if(data->set.proxy_ssl.primary.verifypeer) ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L); if(data->set.str[STRING_SSL_CAFILE_PROXY]) { @@ -315,45 +315,45 @@ static CURLcode dohprobe(struct Curl_easy *data, data->set.str[STRING_SSL_CAPATH_PROXY]); } #endif - if(data->set.ssl.primary.verifypeer) - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); - if(data->set.ssl.primary.verifystatus) - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L); - if(data->set.str[STRING_SSL_CAFILE_ORIG]) { - ERROR_CHECK_SETOPT(CURLOPT_CAINFO, - data->set.str[STRING_SSL_CAFILE_ORIG]); - } - if(data->set.str[STRING_SSL_CAPATH_ORIG]) { - ERROR_CHECK_SETOPT(CURLOPT_CAPATH, - data->set.str[STRING_SSL_CAPATH_ORIG]); - } - if(data->set.str[STRING_SSL_CRLFILE_ORIG]) { - ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, - data->set.str[STRING_SSL_CRLFILE_ORIG]); - } - if(data->set.ssl.certinfo) - ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); - if(data->set.str[STRING_SSL_RANDOM_FILE]) { - ERROR_CHECK_SETOPT(CURLOPT_RANDOM_FILE, - data->set.str[STRING_SSL_RANDOM_FILE]); - } - if(data->set.str[STRING_SSL_EGDSOCKET]) { - ERROR_CHECK_SETOPT(CURLOPT_EGDSOCKET, - data->set.str[STRING_SSL_EGDSOCKET]); - } - if(data->set.ssl.no_revoke) - ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); + if(data->set.ssl.primary.verifypeer) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); + if(data->set.ssl.primary.verifystatus) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L); + if(data->set.str[STRING_SSL_CAFILE_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CAINFO, + data->set.str[STRING_SSL_CAFILE_ORIG]); + } + if(data->set.str[STRING_SSL_CAPATH_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CAPATH, + data->set.str[STRING_SSL_CAPATH_ORIG]); + } + if(data->set.str[STRING_SSL_CRLFILE_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, + data->set.str[STRING_SSL_CRLFILE_ORIG]); + } + if(data->set.ssl.certinfo) + ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); + if(data->set.str[STRING_SSL_RANDOM_FILE]) { + ERROR_CHECK_SETOPT(CURLOPT_RANDOM_FILE, + data->set.str[STRING_SSL_RANDOM_FILE]); + } + if(data->set.str[STRING_SSL_EGDSOCKET]) { + ERROR_CHECK_SETOPT(CURLOPT_EGDSOCKET, + data->set.str[STRING_SSL_EGDSOCKET]); + } + if(data->set.ssl.no_revoke) + ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); else if(data->set.ssl.revoke_best_effort) ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_REVOKE_BEST_EFFORT); - if(data->set.ssl.fsslctx) - ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); - if(data->set.ssl.fsslctxp) - ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); + if(data->set.ssl.fsslctx) + ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); + if(data->set.ssl.fsslctxp) + ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); if(data->set.str[STRING_SSL_EC_CURVES]) { ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES, data->set.str[STRING_SSL_EC_CURVES]); } - + doh->set.fmultidone = Curl_doh_done; doh->set.dohfor = data; /* identify for which transfer this is done */ p->easy = doh; @@ -641,7 +641,7 @@ UNITTEST DOHcode doh_decode(const unsigned char *doh, ancount = get16bit(doh, 6); while(ancount) { - unsigned short class; + unsigned short class; unsigned int ttl; rc = skipqname(doh, dohlen, &index); @@ -948,9 +948,9 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn, result = CURLE_COULDNT_RESOLVE_HOST; /* until we know better */ if(!rc[DOH_PROBE_SLOT_IPADDR_V4] || !rc[DOH_PROBE_SLOT_IPADDR_V6]) { /* we have an address, of one kind or other */ - struct Curl_dns_entry *dns; - struct Curl_addrinfo *ai; - + struct Curl_dns_entry *dns; + struct Curl_addrinfo *ai; + infof(data, "DOH Host name: %s\n", data->req.doh.host); showdoh(data, &de); @@ -991,5 +991,5 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn, /* else wait for pending DOH transactions to complete */ return CURLE_OK; } - -#endif /* CURL_DISABLE_DOH */ + +#endif /* CURL_DISABLE_DOH */ diff --git a/contrib/libs/curl/lib/doh.h b/contrib/libs/curl/lib/doh.h index 1897da2721..0867584ced 100644 --- a/contrib/libs/curl/lib/doh.h +++ b/contrib/libs/curl/lib/doh.h @@ -25,8 +25,8 @@ #include "urldata.h" #include "curl_addrinfo.h" -#ifndef CURL_DISABLE_DOH - +#ifndef CURL_DISABLE_DOH + /* * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name * and returns a 'Curl_addrinfo *' with the address information. @@ -40,7 +40,7 @@ struct Curl_addrinfo *Curl_doh(struct connectdata *conn, CURLcode Curl_doh_is_resolved(struct connectdata *conn, struct Curl_dns_entry **dns); -int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks); +int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks); typedef enum { DOH_OK, @@ -100,10 +100,10 @@ DOHcode doh_decode(const unsigned char *doh, void de_init(struct dohentry *d); void de_cleanup(struct dohentry *d); #endif - -#else /* if DOH is disabled */ -#define Curl_doh(a,b,c,d) NULL -#define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST -#endif - + +#else /* if DOH is disabled */ +#define Curl_doh(a,b,c,d) NULL +#define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST +#endif + #endif /* HEADER_CURL_DOH_H */ diff --git a/contrib/libs/curl/lib/easy.c b/contrib/libs/curl/lib/easy.c index fbb32cf156..dc790b01df 100644 --- a/contrib/libs/curl/lib/easy.c +++ b/contrib/libs/curl/lib/easy.c @@ -75,7 +75,7 @@ #include "vssh/ssh.h" #include "setopt.h" #include "http_digest.h" -#include "system_win32.h" +#include "system_win32.h" #include "http2.h" #include "dynbuf.h" #include "altsvc.h" @@ -150,12 +150,12 @@ static CURLcode global_init(long flags, bool memoryfuncs) goto fail; } -#ifdef WIN32 - if(Curl_win32_init(flags)) { - DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); +#ifdef WIN32 + if(Curl_win32_init(flags)) { + DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); goto fail; - } -#endif + } +#endif #ifdef __AMIGA__ if(!Curl_amiga_init()) { @@ -175,8 +175,8 @@ static CURLcode global_init(long flags, bool memoryfuncs) goto fail; } -#if defined(USE_SSH) - if(Curl_ssh_init()) { +#if defined(USE_SSH) + if(Curl_ssh_init()) { goto fail; } #endif @@ -254,13 +254,13 @@ void curl_global_cleanup(void) Curl_ssl_cleanup(); Curl_resolver_global_cleanup(); -#ifdef WIN32 - Curl_win32_cleanup(init_flags); -#endif +#ifdef WIN32 + Curl_win32_cleanup(init_flags); +#endif Curl_amiga_cleanup(); - Curl_ssh_cleanup(); + Curl_ssh_cleanup(); #ifdef USE_WOLFSSH (void)wolfSSH_Cleanup(); @@ -411,8 +411,8 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ mask. Convert from libcurl bitmask to the poll one. */ m->socket.events = socketcb2poll(what); infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s, - (what&CURL_POLL_IN)?"IN":"", - (what&CURL_POLL_OUT)?"OUT":""); + (what&CURL_POLL_IN)?"IN":"", + (what&CURL_POLL_OUT)?"OUT":""); } break; } @@ -435,8 +435,8 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ m->socket.revents = 0; ev->list = m; infof(easy, "socket cb: socket %d ADDED as %s%s\n", s, - (what&CURL_POLL_IN)?"IN":"", - (what&CURL_POLL_OUT)?"OUT":""); + (what&CURL_POLL_IN)?"IN":"", + (what&CURL_POLL_OUT)?"OUT":""); } else return CURLE_OUT_OF_MEMORY; @@ -543,7 +543,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) return CURLE_RECV_ERROR; if(mcode) - return CURLE_URL_MALFORMAT; + return CURLE_URL_MALFORMAT; /* we don't really care about the "msgs_in_queue" value returned in the second argument */ @@ -587,9 +587,9 @@ static CURLcode easy_transfer(struct Curl_multi *multi) while(!done && !mcode) { int still_running = 0; - mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL); + mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL); - if(!mcode) + if(!mcode) mcode = curl_multi_perform(multi, &still_running); /* only read 'still_running' if curl_multi_perform() return OK */ @@ -975,10 +975,10 @@ void curl_easy_reset(struct Curl_easy *data) /* zero out authentication data: */ memset(&data->state.authhost, 0, sizeof(struct auth)); memset(&data->state.authproxy, 0, sizeof(struct auth)); - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) - Curl_http_auth_cleanup_digest(data); -#endif + +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) + Curl_http_auth_cleanup_digest(data); +#endif } /* @@ -1084,9 +1084,9 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) /* if not pausing again, force a recv/send check of this connection as the data might've been read off the socket already */ data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT; - if(data->multi) - Curl_update_timer(data->multi); - } + if(data->multi) + Curl_update_timer(data->multi); + } if(!data->state.done) /* This transfer may have been moved in or out of the bundle, update the @@ -1186,35 +1186,35 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, } /* - * Wrapper to call functions in Curl_conncache_foreach() - * - * Returns always 0. - */ -static int conn_upkeep(struct connectdata *conn, - void *param) -{ - /* Param is unused. */ - (void)param; - - if(conn->handler->connection_check) { - /* Do a protocol-specific keepalive check on the connection. */ - conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE); - } - - return 0; /* continue iteration */ -} - -static CURLcode upkeep(struct conncache *conn_cache, void *data) -{ - /* Loop over every connection and make connection alive. */ - Curl_conncache_foreach(data, - conn_cache, - data, - conn_upkeep); - return CURLE_OK; -} - -/* + * Wrapper to call functions in Curl_conncache_foreach() + * + * Returns always 0. + */ +static int conn_upkeep(struct connectdata *conn, + void *param) +{ + /* Param is unused. */ + (void)param; + + if(conn->handler->connection_check) { + /* Do a protocol-specific keepalive check on the connection. */ + conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE); + } + + return 0; /* continue iteration */ +} + +static CURLcode upkeep(struct conncache *conn_cache, void *data) +{ + /* Loop over every connection and make connection alive. */ + Curl_conncache_foreach(data, + conn_cache, + data, + conn_upkeep); + return CURLE_OK; +} + +/* * Performs connection upkeep for the given session handle. */ CURLcode curl_easy_upkeep(struct Curl_easy *data) @@ -1225,7 +1225,7 @@ CURLcode curl_easy_upkeep(struct Curl_easy *data) if(data->multi_easy) { /* Use the common function to keep connections alive. */ - return upkeep(&data->multi_easy->conn_cache, data); + return upkeep(&data->multi_easy->conn_cache, data); } else { /* No connections, so just return success */ diff --git a/contrib/libs/curl/lib/file.c b/contrib/libs/curl/lib/file.c index 1051e806e1..a65eb7798d 100644 --- a/contrib/libs/curl/lib/file.c +++ b/contrib/libs/curl/lib/file.c @@ -301,7 +301,7 @@ static CURLcode file_upload(struct connectdata *conn) if(result) break; - if(!readcount) + if(!readcount) break; nread = readcount; diff --git a/contrib/libs/curl/lib/fileinfo.c b/contrib/libs/curl/lib/fileinfo.c index 5831342613..b7e9f0f5e8 100644 --- a/contrib/libs/curl/lib/fileinfo.c +++ b/contrib/libs/curl/lib/fileinfo.c @@ -21,7 +21,7 @@ ***************************************************************************/ #include "curl_setup.h" -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP #include "strdup.h" #include "fileinfo.h" #include "curl_memory.h" @@ -41,4 +41,4 @@ void Curl_fileinfo_cleanup(struct fileinfo *finfo) Curl_safefree(finfo->info.b_data); free(finfo); } -#endif +#endif diff --git a/contrib/libs/curl/lib/formdata.c b/contrib/libs/curl/lib/formdata.c index 5d332a30f3..769f06a705 100644 --- a/contrib/libs/curl/lib/formdata.c +++ b/contrib/libs/curl/lib/formdata.c @@ -24,8 +24,8 @@ #include <curl/curl.h> -#include "formdata.h" -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME) +#include "formdata.h" +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME) #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include <libgen.h> @@ -569,7 +569,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if(((form->flags & HTTPPOST_FILENAME) || (form->flags & HTTPPOST_BUFFER)) && !form->contenttype) { - char *f = (form->flags & HTTPPOST_BUFFER)? + char *f = (form->flags & HTTPPOST_BUFFER)? form->showfilename : form->value; char const *type; type = Curl_mime_contenttype(f); @@ -917,8 +917,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data, return result; } -#else -/* if disabled */ +#else +/* if disabled */ CURLFORMcode curl_formadd(struct curl_httppost **httppost, struct curl_httppost **last_post, ...) @@ -943,4 +943,4 @@ void curl_formfree(struct curl_httppost *form) /* does nothing HTTP is disabled */ } -#endif /* if disabled */ +#endif /* if disabled */ diff --git a/contrib/libs/curl/lib/formdata.h b/contrib/libs/curl/lib/formdata.h index 09603bc405..5a021ceb92 100644 --- a/contrib/libs/curl/lib/formdata.h +++ b/contrib/libs/curl/lib/formdata.h @@ -22,10 +22,10 @@ * ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_MIME - +#include "curl_setup.h" + +#ifndef CURL_DISABLE_MIME + /* used by FormAdd for temporary storage */ struct FormInfo { char *name; @@ -51,10 +51,10 @@ CURLcode Curl_getformdata(struct Curl_easy *data, curl_mimepart *, struct curl_httppost *post, curl_read_callback fread_func); -#else -/* disabled */ -#define Curl_getformdata(a,b,c,d) CURLE_NOT_BUILT_IN -#endif +#else +/* disabled */ +#define Curl_getformdata(a,b,c,d) CURLE_NOT_BUILT_IN +#endif + - #endif /* HEADER_CURL_FORMDATA_H */ diff --git a/contrib/libs/curl/lib/ftp.c b/contrib/libs/curl/lib/ftp.c index 3f1699fbc3..bc35574217 100644 --- a/contrib/libs/curl/lib/ftp.c +++ b/contrib/libs/curl/lib/ftp.c @@ -132,8 +132,8 @@ static CURLcode ftp_connect(struct connectdata *conn, bool *done); static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection); static CURLcode ftp_do_more(struct connectdata *conn, int *completed); static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done); -static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks); -static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks); +static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks); +static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks); static CURLcode ftp_doing(struct connectdata *conn, bool *dophase_done); static CURLcode ftp_setup_connection(struct connectdata *conn); @@ -363,7 +363,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received) struct ftp_conn *ftpc = &conn->proto.ftpc; struct pingpong *pp = &ftpc->pp; int result; - timediff_t timeout_ms; + timediff_t timeout_ms; ssize_t nread; int ftpcode; @@ -448,12 +448,12 @@ static CURLcode InitiateTransfer(struct connectdata *conn) /* set the SO_SNDBUF for the secondary socket for those who need it */ Curl_sndbufset(conn->sock[SECONDARYSOCKET]); - Curl_setup_transfer(data, -1, -1, FALSE, SECONDARYSOCKET); + Curl_setup_transfer(data, -1, -1, FALSE, SECONDARYSOCKET); } else { /* FTP download: */ - Curl_setup_transfer(data, SECONDARYSOCKET, - conn->proto.ftpc.retr_size_saved, FALSE, -1); + Curl_setup_transfer(data, SECONDARYSOCKET, + conn->proto.ftpc.retr_size_saved, FALSE, -1); } conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */ @@ -474,7 +474,7 @@ static CURLcode InitiateTransfer(struct connectdata *conn) static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected) { struct Curl_easy *data = conn->data; - timediff_t timeout_ms; + timediff_t timeout_ms; CURLcode result = CURLE_OK; *connected = FALSE; @@ -547,7 +547,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, char * const buf = data->state.buffer; #endif int code; - CURLcode result = Curl_pp_readresp(sockfd, pp, &code, size); + CURLcode result = Curl_pp_readresp(sockfd, pp, &code, size); #if defined(HAVE_GSSAPI) /* handle the security-oriented responses 6xx ***/ @@ -787,13 +787,13 @@ static CURLcode ftp_state_pwd(struct connectdata *conn) /* For the FTP "protocol connect" and "doing" phases only */ static int ftp_getsock(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { - return Curl_pp_getsock(&conn->proto.ftpc.pp, socks); + return Curl_pp_getsock(&conn->proto.ftpc.pp, socks); } /* For the FTP "DO_MORE" phase only */ -static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks) +static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks) { struct ftp_conn *ftpc = &conn->proto.ftpc; @@ -833,7 +833,7 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks) return bits; } - return Curl_pp_getsock(&conn->proto.ftpc.pp, socks); + return Curl_pp_getsock(&conn->proto.ftpc.pp, socks); } /* This is called after the FTP_QUOTE state is passed. @@ -927,7 +927,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, unsigned short port_max = 0; unsigned short port; bool possibly_non_local = TRUE; - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; char *addr = NULL; /* Step 1, figure out what is requested, @@ -1040,7 +1040,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, sslen = sizeof(ss); if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { failf(data, "getsockname() failed: %s", - Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); free(addr); return CURLE_FTP_PORT_FAILED; } @@ -1061,7 +1061,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, } /* resolv ip/host to ip */ - rc = Curl_resolv(conn, host, 0, FALSE, &h); + rc = Curl_resolv(conn, host, 0, FALSE, &h); if(rc == CURLRESOLV_PENDING) (void)Curl_resolver_wait_resolv(conn, &h); if(h) { @@ -1095,8 +1095,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, break; } if(!ai) { - failf(data, "socket failure: %s", - Curl_strerror(error, buffer, sizeof(buffer))); + failf(data, "socket failure: %s", + Curl_strerror(error, buffer, sizeof(buffer))); return CURLE_FTP_PORT_FAILED; } @@ -1121,12 +1121,12 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, * the control connection instead and restart the port loop */ infof(data, "bind(port=%hu) on non-local address failed: %s\n", port, - Curl_strerror(error, buffer, sizeof(buffer))); + Curl_strerror(error, buffer, sizeof(buffer))); sslen = sizeof(ss); if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { failf(data, "getsockname() failed: %s", - Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); Curl_closesocket(conn, portsock); return CURLE_FTP_PORT_FAILED; } @@ -1136,7 +1136,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, } if(error != EADDRINUSE && error != EACCES) { failf(data, "bind(port=%hu) failed: %s", port, - Curl_strerror(error, buffer, sizeof(buffer))); + Curl_strerror(error, buffer, sizeof(buffer))); Curl_closesocket(conn, portsock); return CURLE_FTP_PORT_FAILED; } @@ -1159,7 +1159,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, sslen = sizeof(ss); if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) { failf(data, "getsockname() failed: %s", - Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); Curl_closesocket(conn, portsock); return CURLE_FTP_PORT_FAILED; } @@ -1167,8 +1167,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn, /* step 4, listen on the socket */ if(listen(portsock, 1)) { - failf(data, "socket failure: %s", - Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + failf(data, "socket failure: %s", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); Curl_closesocket(conn, portsock); return CURLE_FTP_PORT_FAILED; } @@ -1485,13 +1485,13 @@ static CURLcode ftp_state_list(struct connectdata *conn) static CURLcode ftp_state_retr_prequote(struct connectdata *conn) { /* We've sent the TYPE, now we must send the list of prequote strings */ - return ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE); + return ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE); } static CURLcode ftp_state_stor_prequote(struct connectdata *conn) { /* We've sent the TYPE, now we must send the list of prequote strings */ - return ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE); + return ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE); } static CURLcode ftp_state_type(struct connectdata *conn) @@ -1628,7 +1628,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn, infof(data, "File already completely uploaded\n"); /* no data to transfer */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); /* Set ->transfer so that we won't get any error in * ftp_done() because we didn't transfer anything! */ @@ -1922,7 +1922,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, */ const char * const host_name = conn->bits.socksproxy ? conn->socks_proxy.host.name : conn->http_proxy.host.name; - rc = Curl_resolv(conn, host_name, (int)conn->port, FALSE, &addr); + rc = Curl_resolv(conn, host_name, (int)conn->port, FALSE, &addr); if(rc == CURLRESOLV_PENDING) /* BLOCKING, ignores the return code but 'addr' will be NULL in case of failure */ @@ -1951,7 +1951,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, return CURLE_OUT_OF_MEMORY; } - rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr); + rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr); if(rc == CURLRESOLV_PENDING) /* BLOCKING */ (void)Curl_resolver_wait_resolv(conn, &addr); @@ -2223,7 +2223,7 @@ static CURLcode ftp_state_retr(struct connectdata *conn, if(ftp->downloadsize == 0) { /* no data to transfer */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); infof(data, "File already completely downloaded\n"); /* Set ->transfer so that we won't get any error in ftp_done() @@ -3060,7 +3060,7 @@ static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done) { struct ftp_conn *ftpc = &conn->proto.ftpc; - CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE, FALSE); + CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE, FALSE); /* Check for the state outside of the Curl_socket_check() return code checks since at times we are in fact already in this state when this function @@ -3077,7 +3077,7 @@ static CURLcode ftp_block_statemach(struct connectdata *conn) CURLcode result = CURLE_OK; while(ftpc->state != FTP_STOP) { - result = Curl_pp_statemach(pp, TRUE, TRUE /* disconnecting */); + result = Curl_pp_statemach(pp, TRUE, TRUE /* disconnecting */); if(result) break; } @@ -3324,33 +3324,33 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, ; else if(data->set.upload) { if((-1 != data->state.infilesize) && - (data->state.infilesize != data->req.writebytecount) && + (data->state.infilesize != data->req.writebytecount) && !data->set.crlf && (ftp->transfer == FTPTRANSFER_BODY)) { failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes)", - data->req.bytecount, data->state.infilesize); + data->req.bytecount, data->state.infilesize); result = CURLE_PARTIAL_FILE; } } else { if((-1 != data->req.size) && - (data->req.size != data->req.bytecount) && + (data->req.size != data->req.bytecount) && #ifdef CURL_DO_LINEEND_CONV /* Most FTP servers don't adjust their file SIZE response for CRLFs, so * we'll check to see if the discrepancy can be explained by the number * of CRLFs we've changed to LFs. */ ((data->req.size + data->state.crlf_conversions) != - data->req.bytecount) && + data->req.bytecount) && #endif /* CURL_DO_LINEEND_CONV */ - (data->req.maxdownload != data->req.bytecount)) { + (data->req.maxdownload != data->req.bytecount)) { failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T - " bytes", data->req.bytecount); + " bytes", data->req.bytecount); result = CURLE_PARTIAL_FILE; } else if(!ftpc->dont_check && - !data->req.bytecount && + !data->req.bytecount && (data->req.size>0)) { failf(data, "No data was received!"); result = CURLE_FTP_COULDNT_RETR_FILE; @@ -3514,7 +3514,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep) if(!conn->bits.tcpconnect[SECONDARYSOCKET]) { if(Curl_connect_ongoing(conn)) { /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port - aren't used so we blank their arguments. */ + aren't used so we blank their arguments. */ result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0); return result; @@ -4211,7 +4211,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn, if(ftp->transfer != FTPTRANSFER_BODY) /* no data to transfer */ - Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); else if(!connected) /* since we didn't connect now, we want do_more to get called */ conn->bits.do_more = TRUE; diff --git a/contrib/libs/curl/lib/ftplistparser.c b/contrib/libs/curl/lib/ftplistparser.c index cef3efc713..85b8a78d4f 100644 --- a/contrib/libs/curl/lib/ftplistparser.c +++ b/contrib/libs/curl/lib/ftplistparser.c @@ -914,7 +914,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, case PL_WINNT_DIRORSIZE: switch(parser->state.NT.sub.dirorsize) { case PL_WINNT_DIRORSIZE_PRESPACE: - if(c != ' ') { + if(c != ' ') { parser->item_offset = finfo->b_used - 1; parser->item_length = 1; parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT; diff --git a/contrib/libs/curl/lib/getinfo.c b/contrib/libs/curl/lib/getinfo.c index de5fe3f8c3..fd8f4e8430 100644 --- a/contrib/libs/curl/lib/getinfo.c +++ b/contrib/libs/curl/lib/getinfo.c @@ -219,10 +219,10 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, *param_longp = (long)data->info.filetime; break; case CURLINFO_HEADER_SIZE: - *param_longp = (long)data->info.header_size; + *param_longp = (long)data->info.header_size; break; case CURLINFO_REQUEST_SIZE: - *param_longp = (long)data->info.request_size; + *param_longp = (long)data->info.request_size; break; case CURLINFO_SSL_VERIFYRESULT: *param_longp = data->set.ssl.certverifyresult; @@ -299,9 +299,9 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, case 20: *param_longp = CURL_HTTP_VERSION_2_0; break; - case 30: - *param_longp = CURL_HTTP_VERSION_3; - break; + case 30: + *param_longp = CURL_HTTP_VERSION_3; + break; default: *param_longp = CURL_HTTP_VERSION_NONE; break; @@ -388,9 +388,9 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info, case CURLINFO_REDIRECT_TIME_T: *param_offt = data->progress.t_redirect; break; - case CURLINFO_RETRY_AFTER: - *param_offt = data->info.retry_after; - break; + case CURLINFO_RETRY_AFTER: + *param_offt = data->info.retry_after; + break; default: return CURLE_UNKNOWN_OPTION; } @@ -500,7 +500,7 @@ static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info, param_slistp; struct curl_tlssessioninfo *tsi = &data->tsi; #ifdef USE_SSL - struct connectdata *conn = data->conn; + struct connectdata *conn = data->conn; #endif *tsip = tsi; diff --git a/contrib/libs/curl/lib/gopher.c b/contrib/libs/curl/lib/gopher.c index 5b8d1c7764..b101c0ab68 100644 --- a/contrib/libs/curl/lib/gopher.c +++ b/contrib/libs/curl/lib/gopher.c @@ -32,11 +32,11 @@ #include "progress.h" #include "gopher.h" #include "select.h" -#include "strdup.h" +#include "strdup.h" #include "url.h" #include "escape.h" #include "warnless.h" -#include "curl_printf.h" +#include "curl_printf.h" #include "curl_memory.h" /* The last #include file should be: */ #include "memdebug.h" @@ -80,9 +80,9 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - char *gopherpath; + char *gopherpath; char *path = data->state.up.path; - char *query = data->state.up.query; + char *query = data->state.up.query; char *sel = NULL; char *sel_org = NULL; timediff_t timeout_ms; @@ -92,33 +92,33 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) *done = TRUE; /* unconditionally */ - /* path is guaranteed non-NULL */ - DEBUGASSERT(path); - - if(query) - gopherpath = aprintf("%s?%s", path, query); - else - gopherpath = strdup(path); - - if(!gopherpath) - return CURLE_OUT_OF_MEMORY; - + /* path is guaranteed non-NULL */ + DEBUGASSERT(path); + + if(query) + gopherpath = aprintf("%s?%s", path, query); + else + gopherpath = strdup(path); + + if(!gopherpath) + return CURLE_OUT_OF_MEMORY; + /* Create selector. Degenerate cases: / and /1 => convert to "" */ - if(strlen(gopherpath) <= 2) { + if(strlen(gopherpath) <= 2) { sel = (char *)""; len = strlen(sel); - free(gopherpath); + free(gopherpath); } else { char *newp; /* Otherwise, drop / and the first character (i.e., item type) ... */ - newp = gopherpath; + newp = gopherpath; newp += 2; /* ... and finally unescape */ result = Curl_urldecode(data, newp, 0, &sel, &len, REJECT_ZERO); - free(gopherpath); + free(gopherpath); if(result) return result; sel_org = sel; @@ -178,7 +178,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done) if(result) return result; - Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); return CURLE_OK; } #endif /*CURL_DISABLE_GOPHER*/ diff --git a/contrib/libs/curl/lib/hash.h b/contrib/libs/curl/lib/hash.h index 530300a280..b7f828e071 100644 --- a/contrib/libs/curl/lib/hash.h +++ b/contrib/libs/curl/lib/hash.h @@ -80,7 +80,7 @@ int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len); void *Curl_hash_pick(struct Curl_hash *, void *key, size_t key_len); void Curl_hash_apply(struct Curl_hash *h, void *user, void (*cb)(void *user, void *ptr)); -#define Curl_hash_count(h) ((h)->size) +#define Curl_hash_count(h) ((h)->size) void Curl_hash_destroy(struct Curl_hash *h); void Curl_hash_clean(struct Curl_hash *h); void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, diff --git a/contrib/libs/curl/lib/hostasyn.c b/contrib/libs/curl/lib/hostasyn.c index c557bc07d0..56a6fc2b72 100644 --- a/contrib/libs/curl/lib/hostasyn.c +++ b/contrib/libs/curl/lib/hostasyn.c @@ -85,9 +85,9 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn, dns = Curl_cache_addr(data, ai, conn->async.hostname, conn->async.port); - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + if(!dns) { /* failed to store, cleanup and return error */ Curl_freeaddrinfo(ai); diff --git a/contrib/libs/curl/lib/hostcheck.c b/contrib/libs/curl/lib/hostcheck.c index 395909ee04..4d0614aeab 100644 --- a/contrib/libs/curl/lib/hostcheck.c +++ b/contrib/libs/curl/lib/hostcheck.c @@ -132,9 +132,9 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname) !hostname || !*hostname) /* sanity check */ ; else { - char *matchp = strdup(match_pattern); + char *matchp = strdup(match_pattern); if(matchp) { - char *hostp = strdup(hostname); + char *hostp = strdup(hostname); if(hostp) { if(hostmatch(hostp, matchp) == CURL_HOST_MATCH) res = 1; diff --git a/contrib/libs/curl/lib/hostip.c b/contrib/libs/curl/lib/hostip.c index 06d3b7b1a8..c6435f1f97 100644 --- a/contrib/libs/curl/lib/hostip.c +++ b/contrib/libs/curl/lib/hostip.c @@ -74,8 +74,8 @@ #define USE_ALARM_TIMEOUT #endif -#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */ - +#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */ + /* * hostip.c explained * ================== @@ -164,19 +164,19 @@ void Curl_printable_address(const struct Curl_addrinfo *ai, char *buf, } /* - * Create a hostcache id string for the provided host + port, to be used by - * the DNS caching. Without alloc. + * Create a hostcache id string for the provided host + port, to be used by + * the DNS caching. Without alloc. */ -static void -create_hostcache_id(const char *name, int port, char *ptr, size_t buflen) +static void +create_hostcache_id(const char *name, int port, char *ptr, size_t buflen) { - size_t len = strlen(name); - if(len > (buflen - 7)) - len = buflen - 7; - /* store and lower case the name */ - while(len--) - *ptr++ = (char)TOLOWER(*name++); - msnprintf(ptr, 7, ":%u", port); + size_t len = strlen(name); + if(len > (buflen - 7)) + len = buflen - 7; + /* store and lower case the name */ + while(len--) + *ptr++ = (char)TOLOWER(*name++); + msnprintf(ptr, 7, ":%u", port); } struct hostcache_prune_data { @@ -261,24 +261,24 @@ fetch_addr(struct connectdata *conn, struct Curl_dns_entry *dns = NULL; size_t entry_len; struct Curl_easy *data = conn->data; - char entry_id[MAX_HOSTCACHE_LEN]; + char entry_id[MAX_HOSTCACHE_LEN]; /* Create an entry id, based upon the hostname and port */ - create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); /* See if its already in our dns cache */ dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1); - /* No entry found in cache, check if we might have a wildcard entry */ - if(!dns && data->change.wildcard_resolve) { - create_hostcache_id("*", port, entry_id, sizeof(entry_id)); - entry_len = strlen(entry_id); - - /* See if it's already in our dns cache */ - dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1); - } - + /* No entry found in cache, check if we might have a wildcard entry */ + if(!dns && data->change.wildcard_resolve) { + create_hostcache_id("*", port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + + /* See if it's already in our dns cache */ + dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1); + } + if(dns && (data->set.dns_cache_timeout != -1)) { /* See whether the returned entry is stale. Done before we release lock */ struct hostcache_prune_data user; @@ -332,8 +332,8 @@ Curl_fetch_addr(struct connectdata *conn, return dns; } -#ifndef CURL_DISABLE_SHUFFLE_DNS -UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, +#ifndef CURL_DISABLE_SHUFFLE_DNS +UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, struct Curl_addrinfo **addr); /* * Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo' @@ -347,7 +347,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, * * @unittest: 1608 */ -UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, +UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, struct Curl_addrinfo **addr) { CURLcode result = CURLE_OK; @@ -399,7 +399,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, } return result; } -#endif +#endif /* * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. @@ -416,19 +416,19 @@ Curl_cache_addr(struct Curl_easy *data, const char *hostname, int port) { - char entry_id[MAX_HOSTCACHE_LEN]; + char entry_id[MAX_HOSTCACHE_LEN]; size_t entry_len; struct Curl_dns_entry *dns; struct Curl_dns_entry *dns2; -#ifndef CURL_DISABLE_SHUFFLE_DNS +#ifndef CURL_DISABLE_SHUFFLE_DNS /* shuffle addresses if requested */ if(data->set.dns_shuffle_addresses) { CURLcode result = Curl_shuffle_addr(data, &addr); if(result) return NULL; } -#endif +#endif /* Create a new cache entry */ dns = calloc(1, sizeof(struct Curl_dns_entry)); @@ -436,10 +436,10 @@ Curl_cache_addr(struct Curl_easy *data, return NULL; } - /* Create an entry id, based upon the hostname and port */ - create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); - entry_len = strlen(entry_id); - + /* Create an entry id, based upon the hostname and port */ + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + dns->inuse = 1; /* the cache has the first reference */ dns->addr = addr; /* this is the address(es) */ time(&dns->timestamp); @@ -512,7 +512,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn, /* The entry was not in the cache. Resolve it to IP address */ struct Curl_addrinfo *addr = NULL; - int respwait = 0; + int respwait = 0; struct in_addr in; #ifndef USE_RESOLVE_ON_IPS const @@ -695,7 +695,7 @@ enum resolve_t Curl_resolv_timeout(struct connectdata *conn, if(!timeout) /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */ - return Curl_resolv(conn, hostname, port, TRUE, entry); + return Curl_resolv(conn, hostname, port, TRUE, entry); if(timeout < 1000) { /* The alarm() function only provides integer second resolution, so if @@ -757,7 +757,7 @@ enum resolve_t Curl_resolv_timeout(struct connectdata *conn, /* Perform the actual name resolution. This might be interrupted by an * alarm if it takes too long. */ - rc = Curl_resolv(conn, hostname, port, TRUE, entry); + rc = Curl_resolv(conn, hostname, port, TRUE, entry); #ifdef USE_ALARM_TIMEOUT clean_up: @@ -875,11 +875,11 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) char hostname[256]; int port = 0; - /* Default is no wildcard found */ - data->change.wildcard_resolve = false; - + /* Default is no wildcard found */ + data->change.wildcard_resolve = false; + for(hostp = data->change.resolve; hostp; hostp = hostp->next) { - char entry_id[MAX_HOSTCACHE_LEN]; + char entry_id[MAX_HOSTCACHE_LEN]; if(!hostp->data) continue; if(hostp->data[0] == '-') { @@ -892,7 +892,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } /* Create an entry id, based upon the hostname and port */ - create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); if(data->share) @@ -1002,7 +1002,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } /* Create an entry id, based upon the hostname and port */ - create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); if(data->share) @@ -1042,13 +1042,13 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } infof(data, "Added %s:%d:%s to DNS cache\n", hostname, port, addresses); - - /* Wildcard hostname */ - if(hostname[0] == '*' && hostname[1] == '\0') { - infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n", - hostname, port); - data->change.wildcard_resolve = true; - } + + /* Wildcard hostname */ + if(hostname[0] == '*' && hostname[1] == '\0') { + infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n", + hostname, port); + data->change.wildcard_resolve = true; + } } } data->change.resolve = NULL; /* dealt with now */ @@ -1069,14 +1069,14 @@ CURLcode Curl_resolv_check(struct connectdata *conn, } int Curl_resolv_getsock(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { #ifdef CURLRES_ASYNCH if(conn->bits.doh) /* nothing to wait for during DOH resolve, those handles have their own sockets */ return GETSOCK_BLANK; - return Curl_resolver_getsock(conn, socks); + return Curl_resolver_getsock(conn, socks); #else (void)conn; (void)socks; diff --git a/contrib/libs/curl/lib/hostip.h b/contrib/libs/curl/lib/hostip.h index 2314e10050..724a03d7fb 100644 --- a/contrib/libs/curl/lib/hostip.h +++ b/contrib/libs/curl/lib/hostip.h @@ -25,7 +25,7 @@ #include "curl_setup.h" #include "hash.h" #include "curl_addrinfo.h" -#include "timeval.h" /* for timediff_t */ +#include "timeval.h" /* for timediff_t */ #include "asyn.h" #ifdef HAVE_SETJMP_H @@ -244,6 +244,6 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data); CURLcode Curl_resolv_check(struct connectdata *conn, struct Curl_dns_entry **dns); int Curl_resolv_getsock(struct connectdata *conn, - curl_socket_t *socks); + curl_socket_t *socks); #endif /* HEADER_CURL_HOSTIP_H */ diff --git a/contrib/libs/curl/lib/hostip6.c b/contrib/libs/curl/lib/hostip6.c index 12fe4dd24e..02b0ca298b 100644 --- a/contrib/libs/curl/lib/hostip6.c +++ b/contrib/libs/curl/lib/hostip6.c @@ -108,7 +108,7 @@ static void dump_addrinfo(struct connectdata *conn, { printf("dump_addrinfo:\n"); for(; ai; ai = ai->ai_next) { - char buf[INET6_ADDRSTRLEN]; + char buf[INET6_ADDRSTRLEN]; printf(" fam %2d, CNAME %s, ", ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>"); Curl_printable_address(ai, buf, sizeof(buf)); @@ -167,8 +167,8 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, memset(&hints, 0, sizeof(hints)); hints.ai_family = pf; - hints.ai_socktype = (conn->transport == TRNSPRT_TCP) ? - SOCK_STREAM : SOCK_DGRAM; + hints.ai_socktype = (conn->transport == TRNSPRT_TCP) ? + SOCK_STREAM : SOCK_DGRAM; #ifndef USE_RESOLVE_ON_IPS /* diff --git a/contrib/libs/curl/lib/http.c b/contrib/libs/curl/lib/http.c index 34e2b3457c..c232ed4134 100644 --- a/contrib/libs/curl/lib/http.c +++ b/contrib/libs/curl/lib/http.c @@ -76,7 +76,7 @@ #include "http2.h" #include "connect.h" #include "strdup.h" -#include "altsvc.h" +#include "altsvc.h" #include "hsts.h" /* The last 3 #include files should be in this order */ @@ -89,28 +89,28 @@ */ static int http_getsock_do(struct connectdata *conn, - curl_socket_t *socks); + curl_socket_t *socks); static int http_should_fail(struct connectdata *conn); -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY static CURLcode add_haproxy_protocol_header(struct connectdata *conn); -#endif +#endif #ifdef USE_SSL static CURLcode https_connecting(struct connectdata *conn, bool *done); static int https_getsock(struct connectdata *conn, - curl_socket_t *socks); + curl_socket_t *socks); #else #define https_connecting(x,y) CURLE_COULDNT_CONNECT #endif -static CURLcode http_setup_conn(struct connectdata *conn); +static CURLcode http_setup_conn(struct connectdata *conn); /* * HTTP handler interface. */ const struct Curl_handler Curl_handler_http = { "HTTP", /* scheme */ - http_setup_conn, /* setup_connection */ + http_setup_conn, /* setup_connection */ Curl_http, /* do_it */ Curl_http_done, /* done */ ZERO_NULL, /* do_more */ @@ -137,7 +137,7 @@ const struct Curl_handler Curl_handler_http = { */ const struct Curl_handler Curl_handler_https = { "HTTPS", /* scheme */ - http_setup_conn, /* setup_connection */ + http_setup_conn, /* setup_connection */ Curl_http, /* do_it */ Curl_http_done, /* done */ ZERO_NULL, /* do_more */ @@ -159,7 +159,7 @@ const struct Curl_handler Curl_handler_https = { }; #endif -static CURLcode http_setup_conn(struct connectdata *conn) +static CURLcode http_setup_conn(struct connectdata *conn) { /* allocate the HTTP-specific struct for the Curl_easy, only to survive during this request */ @@ -174,26 +174,26 @@ static CURLcode http_setup_conn(struct connectdata *conn) Curl_mime_initpart(&http->form, conn->data); data->req.p.http = http; - if(data->set.httpversion == CURL_HTTP_VERSION_3) { - if(conn->handler->flags & PROTOPT_SSL) - /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does - the QUIC dance. */ - conn->transport = TRNSPRT_QUIC; - else { - failf(data, "HTTP/3 requested for non-HTTPS URL"); - return CURLE_URL_MALFORMAT; - } - } - else { - if(!CONN_INUSE(conn)) - /* if not already multi-using, setup connection details */ - Curl_http2_setup_conn(conn); - Curl_http2_setup_req(data); - } + if(data->set.httpversion == CURL_HTTP_VERSION_3) { + if(conn->handler->flags & PROTOPT_SSL) + /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does + the QUIC dance. */ + conn->transport = TRNSPRT_QUIC; + else { + failf(data, "HTTP/3 requested for non-HTTPS URL"); + return CURLE_URL_MALFORMAT; + } + } + else { + if(!CONN_INUSE(conn)) + /* if not already multi-using, setup connection details */ + Curl_http2_setup_conn(conn); + Curl_http2_setup_req(data); + } return CURLE_OK; } -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY /* * checkProxyHeaders() checks the linked list of custom proxy headers * if proxy headers are not available, then it will lookup into http header @@ -220,10 +220,10 @@ char *Curl_checkProxyheaders(const struct connectdata *conn, return NULL; } -#else -/* disabled */ -#define Curl_checkProxyheaders(x,y) NULL -#endif +#else +/* disabled */ +#define Curl_checkProxyheaders(x,y) NULL +#endif /* * Strip off leading and trailing whitespace from the value in the @@ -278,7 +278,7 @@ char *Curl_copy_header_value(const char *header) return value; } -#ifndef CURL_DISABLE_HTTP_AUTH +#ifndef CURL_DISABLE_HTTP_AUTH /* * http_output_basic() sets up an Authorization: header (or the proxy version) * for HTTP Basic authentication. @@ -365,8 +365,8 @@ static CURLcode http_output_bearer(struct connectdata *conn) return result; } -#endif - +#endif + /* pickoneauth() selects the most favourable authentication method from the * ones available and the ones we want. * @@ -403,7 +403,7 @@ static bool pickoneauth(struct auth *pick, unsigned long mask) } /* - * http_perhapsrewind() + * http_perhapsrewind() * * If we are doing POST or PUT { * If we have more data to send { @@ -445,7 +445,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) break; } - bytessent = data->req.writebytecount; + bytessent = data->req.writebytecount; if(conn->bits.authneg) { /* This is a state where we are known to be negotiating and we don't send @@ -483,8 +483,8 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) (data->state.authproxy.picked == CURLAUTH_NTLM_WB) || (data->state.authhost.picked == CURLAUTH_NTLM_WB)) { if(((expectsend - bytessent) < 2000) || - (conn->http_ntlm_state != NTLMSTATE_NONE) || - (conn->proxy_ntlm_state != NTLMSTATE_NONE)) { + (conn->http_ntlm_state != NTLMSTATE_NONE) || + (conn->proxy_ntlm_state != NTLMSTATE_NONE)) { /* The NTLM-negotiation has started *OR* there is just a little (<2K) data left to send, keep on sending. */ @@ -506,36 +506,36 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) (curl_off_t)(expectsend - bytessent)); } #endif -#if defined(USE_SPNEGO) - /* There is still data left to send */ - if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) || - (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) { - if(((expectsend - bytessent) < 2000) || - (conn->http_negotiate_state != GSS_AUTHNONE) || - (conn->proxy_negotiate_state != GSS_AUTHNONE)) { - /* The NEGOTIATE-negotiation has started *OR* - there is just a little (<2K) data left to send, keep on sending. */ - - /* rewind data when completely done sending! */ - if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) { - conn->bits.rewindaftersend = TRUE; - infof(data, "Rewind stream after send\n"); - } - - return CURLE_OK; - } - - if(conn->bits.close) - /* this is already marked to get closed */ - return CURLE_OK; - - infof(data, "NEGOTIATE send, close instead of sending %" - CURL_FORMAT_CURL_OFF_T " bytes\n", - (curl_off_t)(expectsend - bytessent)); - } -#endif - - /* This is not NEGOTIATE/NTLM or many bytes left to send: close */ +#if defined(USE_SPNEGO) + /* There is still data left to send */ + if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) || + (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) { + if(((expectsend - bytessent) < 2000) || + (conn->http_negotiate_state != GSS_AUTHNONE) || + (conn->proxy_negotiate_state != GSS_AUTHNONE)) { + /* The NEGOTIATE-negotiation has started *OR* + there is just a little (<2K) data left to send, keep on sending. */ + + /* rewind data when completely done sending! */ + if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) { + conn->bits.rewindaftersend = TRUE; + infof(data, "Rewind stream after send\n"); + } + + return CURLE_OK; + } + + if(conn->bits.close) + /* this is already marked to get closed */ + return CURLE_OK; + + infof(data, "NEGOTIATE send, close instead of sending %" + CURL_FORMAT_CURL_OFF_T " bytes\n", + (curl_off_t)(expectsend - bytessent)); + } +#endif + + /* This is not NEGOTIATE/NTLM or many bytes left to send: close */ streamclose(conn, "Mid-auth HTTP and much data left to send"); data->req.size = 0; /* don't download any more than 0 bytes */ @@ -639,7 +639,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn) return result; } -#ifndef CURL_DISABLE_HTTP_AUTH +#ifndef CURL_DISABLE_HTTP_AUTH /* * Output the correct authentication header depending on the auth type * and whether or not it is to a proxy. @@ -661,7 +661,7 @@ output_auth_headers(struct connectdata *conn, #endif #ifdef USE_SPNEGO - if(authstatus->picked == CURLAUTH_NEGOTIATE) { + if(authstatus->picked == CURLAUTH_NEGOTIATE) { auth = "Negotiate"; result = Curl_output_negotiate(conn, proxy); if(result) @@ -809,7 +809,7 @@ Curl_http_output_auth(struct connectdata *conn, #ifndef CURL_DISABLE_PROXY /* Send proxy authentication header if needed */ if(conn->bits.httpproxy && - (conn->bits.tunnel_proxy == (bit)proxytunnel)) { + (conn->bits.tunnel_proxy == (bit)proxytunnel)) { result = output_auth_headers(conn, authproxy, request, path, TRUE); if(result) return result; @@ -837,22 +837,22 @@ Curl_http_output_auth(struct connectdata *conn, return result; } -#else -/* when disabled */ -CURLcode -Curl_http_output_auth(struct connectdata *conn, - const char *request, - const char *path, - bool proxytunnel) -{ - (void)conn; - (void)request; - (void)path; - (void)proxytunnel; - return CURLE_OK; -} -#endif - +#else +/* when disabled */ +CURLcode +Curl_http_output_auth(struct connectdata *conn, + const char *request, + const char *path, + bool proxytunnel) +{ + (void)conn; + (void)request; + (void)path; + (void)proxytunnel; + return CURLE_OK; +} +#endif + /* * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate: * headers. They are dealt with both in the transfer.c main loop and in the @@ -868,8 +868,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, struct Curl_easy *data = conn->data; #ifdef USE_SPNEGO - curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state : - &conn->http_negotiate_state; + curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state : + &conn->http_negotiate_state; #endif unsigned long *availp; struct auth *authp; @@ -908,18 +908,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, authp->avail |= CURLAUTH_NEGOTIATE; if(authp->picked == CURLAUTH_NEGOTIATE) { - CURLcode result = Curl_input_negotiate(conn, proxy, auth); - if(!result) { - DEBUGASSERT(!data->req.newurl); - data->req.newurl = strdup(data->change.url); - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - data->state.authproblem = FALSE; - /* we received a GSS auth token and we dealt with it fine */ - *negstate = GSS_AUTHRECV; + CURLcode result = Curl_input_negotiate(conn, proxy, auth); + if(!result) { + DEBUGASSERT(!data->req.newurl); + data->req.newurl = strdup(data->change.url); + if(!data->req.newurl) + return CURLE_OUT_OF_MEMORY; + data->state.authproblem = FALSE; + /* we received a GSS auth token and we dealt with it fine */ + *negstate = GSS_AUTHRECV; } - else - data->state.authproblem = TRUE; + else + data->state.authproblem = TRUE; } } } @@ -947,10 +947,10 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, *availp |= CURLAUTH_NTLM_WB; authp->avail |= CURLAUTH_NTLM_WB; - result = Curl_input_ntlm_wb(conn, proxy, auth); - if(result) { - infof(data, "Authentication problem. Ignoring this.\n"); - data->state.authproblem = TRUE; + result = Curl_input_ntlm_wb(conn, proxy, auth); + if(result) { + infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; } } #endif @@ -1270,8 +1270,8 @@ CURLcode Curl_buffer_send(struct dynbuf *in, if(http) { /* if we sent a piece of the body here, up the byte counter for it accordingly */ - data->req.writebytecount += bodylen; - Curl_pgrsSetUploadCounter(data, data->req.writebytecount); + data->req.writebytecount += bodylen; + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); if((size_t)amount != size) { /* The whole request could not be sent in one system call. We must @@ -1414,7 +1414,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done) if(result) return result; } -#endif +#endif if(conn->given->protocol & CURLPROTO_HTTPS) { /* perform SSL initialization */ @@ -1432,14 +1432,14 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done) interface and then we're always _sending_ a request and thus we wait for the single socket to become writable only */ static int http_getsock_do(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { /* write mode */ socks[0] = conn->sock[FIRSTSOCKET]; return GETSOCK_WRITESOCK(0); } -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY static CURLcode add_haproxy_protocol_header(struct connectdata *conn) { char proxy_header[128]; @@ -1475,7 +1475,7 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn) return result; } -#endif +#endif #ifdef USE_SSL static CURLcode https_connecting(struct connectdata *conn, bool *done) @@ -1483,13 +1483,13 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done) CURLcode result; DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL)); -#ifdef ENABLE_QUIC - if(conn->transport == TRNSPRT_QUIC) { - *done = TRUE; - return CURLE_OK; - } -#endif - +#ifdef ENABLE_QUIC + if(conn->transport == TRNSPRT_QUIC) { + *done = TRUE; + return CURLE_OK; + } +#endif + /* perform SSL initialization for this socket */ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done); if(result) @@ -1499,10 +1499,10 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done) } static int https_getsock(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { if(conn->handler->flags & PROTOPT_SSL) - return Curl_ssl_getsock(conn, socks); + return Curl_ssl_getsock(conn, socks); return GETSOCK_BLANK; } #endif /* USE_SSL */ @@ -1545,7 +1545,7 @@ CURLcode Curl_http_done(struct connectdata *conn, entire operation is complete */ !conn->bits.retry && !data->set.connect_only && - (data->req.bytecount + + (data->req.bytecount + data->req.headerbytecount - data->req.deductheadercount) <= 0) { /* If this connection isn't simply closed to be retried, AND nothing was @@ -1582,12 +1582,12 @@ static bool use_http_1_1plus(const struct Curl_easy *data, static const char *get_http_string(const struct Curl_easy *data, const struct connectdata *conn) { -#ifdef ENABLE_QUIC - if((data->set.httpversion == CURL_HTTP_VERSION_3) || - (conn->httpversion == 30)) - return "3"; -#endif - +#ifdef ENABLE_QUIC + if((data->set.httpversion == CURL_HTTP_VERSION_3) || + (conn->httpversion == 30)) + return "3"; +#endif + #ifdef USE_NGHTTP2 if(conn->proto.httpc.h2) return "2"; @@ -1608,7 +1608,7 @@ static CURLcode expect100(struct Curl_easy *data, data->state.expect100header = FALSE; /* default to false unless it is set to TRUE below */ if(!data->state.disableexpect && use_http_1_1plus(data, conn) && - (conn->httpversion < 20)) { + (conn->httpversion < 20)) { /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an Expect: 100-continue to the headers which actually speeds up post operations (as there is one packet coming back from the web server) */ @@ -1633,51 +1633,51 @@ enum proxy_use { HEADER_CONNECT /* sending CONNECT to a proxy */ }; -/* used to compile the provided trailers into one buffer - will return an error code if one of the headers is - not formatted correctly */ -CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, +/* used to compile the provided trailers into one buffer + will return an error code if one of the headers is + not formatted correctly */ +CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, struct dynbuf *b, - struct Curl_easy *handle) -{ - char *ptr = NULL; - CURLcode result = CURLE_OK; - const char *endofline_native = NULL; - const char *endofline_network = NULL; - - if( -#ifdef CURL_DO_LINEEND_CONV - (handle->set.prefer_ascii) || -#endif - (handle->set.crlf)) { - /* \n will become \r\n later on */ - endofline_native = "\n"; - endofline_network = "\x0a"; - } - else { - endofline_native = "\r\n"; - endofline_network = "\x0d\x0a"; - } - - while(trailers) { - /* only add correctly formatted trailers */ - ptr = strchr(trailers->data, ':'); - if(ptr && *(ptr + 1) == ' ') { + struct Curl_easy *handle) +{ + char *ptr = NULL; + CURLcode result = CURLE_OK; + const char *endofline_native = NULL; + const char *endofline_network = NULL; + + if( +#ifdef CURL_DO_LINEEND_CONV + (handle->set.prefer_ascii) || +#endif + (handle->set.crlf)) { + /* \n will become \r\n later on */ + endofline_native = "\n"; + endofline_network = "\x0a"; + } + else { + endofline_native = "\r\n"; + endofline_network = "\x0d\x0a"; + } + + while(trailers) { + /* only add correctly formatted trailers */ + ptr = strchr(trailers->data, ':'); + if(ptr && *(ptr + 1) == ' ') { result = Curl_dyn_add(b, trailers->data); - if(result) - return result; + if(result) + return result; result = Curl_dyn_add(b, endofline_native); if(result) return result; - } - else - infof(handle, "Malformatted trailing header ! Skipping trailer."); - trailers = trailers->next; - } + } + else + infof(handle, "Malformatted trailing header ! Skipping trailer."); + trailers = trailers->next; + } result = Curl_dyn_add(b, endofline_network); - return result; -} - + return result; +} + CURLcode Curl_add_custom_headers(struct connectdata *conn, bool is_connect, struct dynbuf *req) @@ -1744,16 +1744,16 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, } else { if(*(--ptr) == ';') { - /* copy the source */ - semicolonp = strdup(headers->data); - if(!semicolonp) { + /* copy the source */ + semicolonp = strdup(headers->data); + if(!semicolonp) { Curl_dyn_free(req); - return CURLE_OUT_OF_MEMORY; - } - /* put a colon where the semicolon is */ - semicolonp[ptr - headers->data] = ':'; - /* point at the colon */ - optr = &semicolonp [ptr - headers->data]; + return CURLE_OUT_OF_MEMORY; + } + /* put a colon where the semicolon is */ + semicolonp[ptr - headers->data] = ':'; + /* point at the colon */ + optr = &semicolonp [ptr - headers->data]; } } ptr = optr; @@ -1769,37 +1769,37 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, if(*ptr || semicolonp) { /* only send this if the contents was non-blank or done special */ CURLcode result = CURLE_OK; - char *compare = semicolonp ? semicolonp : headers->data; + char *compare = semicolonp ? semicolonp : headers->data; if(data->state.aptr.host && /* a Host: header was sent already, don't pass on any custom Host: header as that will produce *two* in the same request! */ - checkprefix("Host:", compare)) + checkprefix("Host:", compare)) ; else if(data->state.httpreq == HTTPREQ_POST_FORM && /* this header (extended by formdata.c) is sent later */ - checkprefix("Content-Type:", compare)) + checkprefix("Content-Type:", compare)) ; else if(data->state.httpreq == HTTPREQ_POST_MIME && /* this header is sent later */ - checkprefix("Content-Type:", compare)) + checkprefix("Content-Type:", compare)) ; else if(conn->bits.authneg && /* while doing auth neg, don't allow the custom length since we will force length zero then */ - checkprefix("Content-Length:", compare)) + checkprefix("Content-Length:", compare)) ; else if(data->state.aptr.te && /* when asking for Transfer-Encoding, don't pass on a custom Connection: */ - checkprefix("Connection:", compare)) + checkprefix("Connection:", compare)) ; - else if((conn->httpversion >= 20) && - checkprefix("Transfer-Encoding:", compare)) + else if((conn->httpversion >= 20) && + checkprefix("Transfer-Encoding:", compare)) /* HTTP/2 doesn't support chunked requests */ ; - else if((checkprefix("Authorization:", compare) || - checkprefix("Cookie:", compare)) && + else if((checkprefix("Authorization:", compare) || + checkprefix("Cookie:", compare)) && /* be careful of sending this potentially sensitive header to other hosts */ (data->state.this_is_a_follow && @@ -1811,7 +1811,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, result = Curl_dyn_addf(req, "%s\r\n", compare); } if(semicolonp) - free(semicolonp); + free(semicolonp); if(result) return result; } @@ -1823,11 +1823,11 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, return CURLE_OK; } -#ifndef CURL_DISABLE_PARSEDATE -CURLcode Curl_add_timecondition(const struct connectdata *conn, +#ifndef CURL_DISABLE_PARSEDATE +CURLcode Curl_add_timecondition(const struct connectdata *conn, struct dynbuf *req) { - struct Curl_easy *data = conn->data; + struct Curl_easy *data = conn->data; const struct tm *tm; struct tm keeptime; CURLcode result; @@ -1860,11 +1860,11 @@ CURLcode Curl_add_timecondition(const struct connectdata *conn, break; } - if(Curl_checkheaders(conn, condp)) { - /* A custom header was specified; it will be sent instead. */ - return CURLE_OK; - } - + if(Curl_checkheaders(conn, condp)) { + /* A custom header was specified; it will be sent instead. */ + return CURLE_OK; + } + /* The If-Modified-Since header family should have their times set in * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be * represented in Greenwich Mean Time (GMT), without exception. For the @@ -1888,16 +1888,16 @@ CURLcode Curl_add_timecondition(const struct connectdata *conn, return result; } -#else -/* disabled */ -CURLcode Curl_add_timecondition(const struct connectdata *conn, +#else +/* disabled */ +CURLcode Curl_add_timecondition(const struct connectdata *conn, struct dynbuf *req) -{ - (void)conn; +{ + (void)conn; (void)req; - return CURLE_OK; -} -#endif + return CURLE_OK; +} +#endif /* * Curl_http() gets called from the generic multi_do() function when a HTTP @@ -1925,57 +1925,57 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) const char *httpstring; struct dynbuf req; curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */ - char *altused = NULL; + char *altused = NULL; /* Always consider the DO phase done after this function call, even if there may be parts of the request that is not yet sent, since we can deal with the rest of the request in the PERFORM phase. */ *done = TRUE; - if(conn->transport != TRNSPRT_QUIC) { - if(conn->httpversion < 20) { /* unless the connection is re-used and - already http2 */ - switch(conn->negnpn) { - case CURL_HTTP_VERSION_2: - conn->httpversion = 20; /* we know we're on HTTP/2 now */ + if(conn->transport != TRNSPRT_QUIC) { + if(conn->httpversion < 20) { /* unless the connection is re-used and + already http2 */ + switch(conn->negnpn) { + case CURL_HTTP_VERSION_2: + conn->httpversion = 20; /* we know we're on HTTP/2 now */ result = Curl_http2_switched(conn, NULL, 0); if(result) return result; - break; - case CURL_HTTP_VERSION_1_1: - /* continue with HTTP/1.1 when explicitly requested */ - break; - default: - /* Check if user wants to use HTTP/2 with clear TCP*/ -#ifdef USE_NGHTTP2 - if(conn->data->set.httpversion == - CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) { + break; + case CURL_HTTP_VERSION_1_1: + /* continue with HTTP/1.1 when explicitly requested */ + break; + default: + /* Check if user wants to use HTTP/2 with clear TCP*/ +#ifdef USE_NGHTTP2 + if(conn->data->set.httpversion == + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) { #ifndef CURL_DISABLE_PROXY - if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { - /* We don't support HTTP/2 proxies yet. Also it's debatable - whether or not this setting should apply to HTTP/2 proxies. */ - infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n"); - break; - } -#endif - DEBUGF(infof(data, "HTTP/2 over clean TCP\n")); - conn->httpversion = 20; - - result = Curl_http2_switched(conn, NULL, 0); - if(result) - return result; - } -#endif - break; + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { + /* We don't support HTTP/2 proxies yet. Also it's debatable + whether or not this setting should apply to HTTP/2 proxies. */ + infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n"); + break; + } +#endif + DEBUGF(infof(data, "HTTP/2 over clean TCP\n")); + conn->httpversion = 20; + + result = Curl_http2_switched(conn, NULL, 0); + if(result) + return result; + } +#endif + break; } } - else { - /* prepare for a http2 request */ - result = Curl_http2_setup(conn); - if(result) - return result; - } + else { + /* prepare for a http2 request */ + result = Curl_http2_setup(conn); + if(result) + return result; + } } http = data->req.p.http; DEBUGASSERT(http); @@ -2047,8 +2047,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; } - if(((data->state.authhost.multipass && !data->state.authhost.done) - || (data->state.authproxy.multipass && !data->state.authproxy.done)) && + if(((data->state.authhost.multipass && !data->state.authhost.done) + || (data->state.authproxy.multipass && !data->state.authproxy.done)) && (httpreq != HTTPREQ_GET) && (httpreq != HTTPREQ_HEAD)) { /* Auth is required and we are not authenticated yet. Make a PUT or POST @@ -2133,7 +2133,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) http->sendit = NULL; } -#ifndef CURL_DISABLE_MIME +#ifndef CURL_DISABLE_MIME if(http->sendit) { const char *cthdr = Curl_checkheaders(conn, "Content-Type"); @@ -2158,7 +2158,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; http->postsize = Curl_mime_size(http->sendit); } -#endif +#endif ptr = Curl_checkheaders(conn, "Transfer-Encoding"); if(ptr) { @@ -2169,16 +2169,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) else { if((conn->handler->protocol & PROTO_FAMILY_HTTP) && (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) && - http->postsize < 0) || - ((data->set.upload || httpreq == HTTPREQ_POST) && - data->state.infilesize == -1))) { + http->postsize < 0) || + ((data->set.upload || httpreq == HTTPREQ_POST) && + data->state.infilesize == -1))) { if(conn->bits.authneg) /* don't enable chunked during auth neg */ ; else if(use_http_1_1plus(data, conn)) { - if(conn->httpversion < 20) - /* HTTP, upload, unknown file size and not HTTP 1.0 */ - data->req.upload_chunky = TRUE; + if(conn->httpversion < 20) + /* HTTP, upload, unknown file size and not HTTP 1.0 */ + data->req.upload_chunky = TRUE; } else { failf(data, "Chunky upload is not supported by HTTP 1.0"); @@ -2310,9 +2310,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } } /* Extract the URL to use in the request. Store in STRING_TEMP_URL for - clean-up reasons if the function returns before the free() further - down. */ - uc = curl_url_get(h, CURLUPART_URL, &data->set.str[STRING_TEMP_URL], 0); + clean-up reasons if the function returns before the free() further + down. */ + uc = curl_url_get(h, CURLUPART_URL, &data->set.str[STRING_TEMP_URL], 0); if(uc) { curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; @@ -2493,16 +2493,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) query = NULL; } -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY /* url */ if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { - char *url = data->set.str[STRING_TEMP_URL]; + char *url = data->set.str[STRING_TEMP_URL]; result = Curl_dyn_add(&req, url); - Curl_safefree(data->set.str[STRING_TEMP_URL]); + Curl_safefree(data->set.str[STRING_TEMP_URL]); } - else -#endif - if(paste_ftp_userpwd) + else +#endif + if(paste_ftp_userpwd) result = Curl_dyn_addf(&req, "ftp://%s:%s@%s", conn->user, conn->passwd, path + sizeof("ftp://") - 1); else { @@ -2516,15 +2516,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; #ifndef CURL_DISABLE_ALTSVC - if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) { - altused = aprintf("Alt-Used: %s:%d\r\n", - conn->conn_to_host.name, conn->conn_to_port); + if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) { + altused = aprintf("Alt-Used: %s:%d\r\n", + conn->conn_to_host.name, conn->conn_to_port); if(!altused) { Curl_dyn_free(&req); - return CURLE_OUT_OF_MEMORY; + return CURLE_OUT_OF_MEMORY; } - } -#endif + } +#endif result = Curl_dyn_addf(&req, "%s" /* ftp typecode (;type=x) */ @@ -2578,7 +2578,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) * from re-used connections */ Curl_safefree(data->state.aptr.userpwd); Curl_safefree(data->state.aptr.proxyuserpwd); - free(altused); + free(altused); if(result) return result; @@ -2698,8 +2698,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) failf(data, "Failed sending PUT request"); else /* prepare for transfer */ - Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, - postsize?FIRSTSOCKET:-1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + postsize?FIRSTSOCKET:-1); if(result) return result; break; @@ -2719,11 +2719,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) failf(data, "Failed sending POST request"); else /* setup variables for the upcoming transfer */ - Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); break; } - data->state.infilesize = postsize = http->postsize; + data->state.infilesize = postsize = http->postsize; /* We only set Content-Length and allow a custom Content-Length if we don't upload data chunked, as RFC2616 forbids us to set both @@ -2739,7 +2739,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; } -#ifndef CURL_DISABLE_MIME +#ifndef CURL_DISABLE_MIME /* Output mime-generated headers. */ { struct curl_slist *hdr; @@ -2750,7 +2750,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; } } -#endif +#endif /* For really small posts we don't use Expect: headers at all, and for the somewhat bigger ones we allow the app to disable it. Just make @@ -2789,8 +2789,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) failf(data, "Failed sending POST request"); else /* prepare for transfer */ - Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, - postsize?FIRSTSOCKET:-1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + postsize?FIRSTSOCKET:-1); if(result) return result; @@ -2948,8 +2948,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if(result) failf(data, "Failed sending HTTP POST request"); else - Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, - http->postdata?FIRSTSOCKET:-1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + http->postdata?FIRSTSOCKET:-1); break; default: @@ -2972,19 +2972,19 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if(!postsize && (http->sending != HTTPSEND_REQUEST)) data->req.upload_done = TRUE; - if(data->req.writebytecount) { + if(data->req.writebytecount) { /* if a request-body has been sent off, we make sure this progress is noted properly */ - Curl_pgrsSetUploadCounter(data, data->req.writebytecount); + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); if(Curl_pgrsUpdate(conn)) result = CURLE_ABORTED_BY_CALLBACK; - if(data->req.writebytecount >= postsize) { + if(data->req.writebytecount >= postsize) { /* already sent the entire request body, mark the "upload" as complete */ infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n", - data->req.writebytecount, postsize); + data->req.writebytecount, postsize); data->req.upload_done = TRUE; data->req.keepon &= ~KEEP_SEND; /* we're done writing */ data->req.exp100 = EXP100_SEND_DATA; /* already sent */ @@ -3188,10 +3188,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, k->header = FALSE; k->badheader = HEADER_ALLBAD; streamclose(conn, "bad HTTP: No end-of-message indicator"); - if(!data->set.http09_allowed) { - failf(data, "Received HTTP/0.9 when not allowed\n"); - return CURLE_UNSUPPORTED_PROTOCOL; - } + if(!data->set.http09_allowed) { + failf(data, "Received HTTP/0.9 when not allowed\n"); + return CURLE_UNSUPPORTED_PROTOCOL; + } break; } } @@ -3223,10 +3223,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(st == STATUS_BAD) { streamclose(conn, "bad HTTP: No end-of-message indicator"); /* this is not the beginning of a protocol first header line */ - if(!data->set.http09_allowed) { - failf(data, "Received HTTP/0.9 when not allowed\n"); - return CURLE_UNSUPPORTED_PROTOCOL; - } + if(!data->set.http09_allowed) { + failf(data, "Received HTTP/0.9 when not allowed\n"); + return CURLE_UNSUPPORTED_PROTOCOL; + } k->header = FALSE; if(*nread) /* since there's more, this is a partial bad header */ @@ -3340,31 +3340,31 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, #if defined(USE_NTLM) if(conn->bits.close && (((data->req.httpcode == 401) && - (conn->http_ntlm_state == NTLMSTATE_TYPE2)) || + (conn->http_ntlm_state == NTLMSTATE_TYPE2)) || ((data->req.httpcode == 407) && - (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) { + (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) { infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); data->state.authproblem = TRUE; } #endif -#if defined(USE_SPNEGO) - if(conn->bits.close && - (((data->req.httpcode == 401) && - (conn->http_negotiate_state == GSS_AUTHRECV)) || - ((data->req.httpcode == 407) && - (conn->proxy_negotiate_state == GSS_AUTHRECV)))) { - infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); - data->state.authproblem = TRUE; - } - if((conn->http_negotiate_state == GSS_AUTHDONE) && - (data->req.httpcode != 401)) { - conn->http_negotiate_state = GSS_AUTHSUCC; - } - if((conn->proxy_negotiate_state == GSS_AUTHDONE) && - (data->req.httpcode != 407)) { - conn->proxy_negotiate_state = GSS_AUTHSUCC; - } -#endif +#if defined(USE_SPNEGO) + if(conn->bits.close && + (((data->req.httpcode == 401) && + (conn->http_negotiate_state == GSS_AUTHRECV)) || + ((data->req.httpcode == 407) && + (conn->proxy_negotiate_state == GSS_AUTHRECV)))) { + infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); + data->state.authproblem = TRUE; + } + if((conn->http_negotiate_state == GSS_AUTHDONE) && + (data->req.httpcode != 401)) { + conn->http_negotiate_state = GSS_AUTHSUCC; + } + if((conn->proxy_negotiate_state == GSS_AUTHDONE) && + (data->req.httpcode != 407)) { + conn->proxy_negotiate_state = GSS_AUTHSUCC; + } +#endif /* * When all the headers have been parsed, see if we should give * up and return an error. @@ -3448,9 +3448,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, else { infof(data, "HTTP error before end of send, stop sending\n"); streamclose(conn, "Stop sending data before everything sent"); - result = Curl_done_sending(conn, k); - if(result) - return result; + result = Curl_done_sending(conn, k); + if(result) + return result; k->upload_done = TRUE; if(data->state.expect100header) k->exp100 = EXP100_FAILED; @@ -3583,7 +3583,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, * guarantees on future behaviors since it isn't within the protocol. */ char separator; - char twoorthree[2]; + char twoorthree[2]; nc = sscanf(HEADER1, " HTTP/%1d.%1d%c%3d", &httpversion_major, @@ -3591,8 +3591,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, &separator, &k->httpcode); - if(nc == 1 && httpversion_major >= 2 && - 2 == sscanf(HEADER1, " HTTP/%1[23] %d", twoorthree, &k->httpcode)) { + if(nc == 1 && httpversion_major >= 2 && + 2 == sscanf(HEADER1, " HTTP/%1[23] %d", twoorthree, &k->httpcode)) { conn->httpversion = 0; nc = 4; separator = ' '; @@ -3606,10 +3606,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(conn->httpversion != 20) infof(data, "Lying server, not serving HTTP/2\n"); } - if(conn->httpversion < 20) { - conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; - infof(data, "Mark bundle as not supporting multiuse\n"); - } + if(conn->httpversion < 20) { + conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; + infof(data, "Mark bundle as not supporting multiuse\n"); + } } else if(!nc) { /* this is the real world, not a Nirvana @@ -3634,7 +3634,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, } } else { - failf(data, "Unsupported HTTP version in response"); + failf(data, "Unsupported HTTP version in response"); return CURLE_UNSUPPORTED_PROTOCOL; } } @@ -3705,12 +3705,12 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, } else if(conn->httpversion >= 11 && !conn->bits.close) { - /* If HTTP version is >= 1.1 and connection is persistent */ + /* If HTTP version is >= 1.1 and connection is persistent */ DEBUGF(infof(data, - "HTTP 1.1 or later with persistent connection\n")); + "HTTP 1.1 or later with persistent connection\n")); } - k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200; + k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200; switch(k->httpcode) { case 304: /* (quote from RFC2616, section 10.3.5): The 304 response @@ -3728,7 +3728,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, * empty line after the header fields. */ k->size = 0; k->maxdownload = 0; - k->http_bodyless = TRUE; + k->http_bodyless = TRUE; break; default: break; @@ -3746,7 +3746,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, return result; /* Check for Content-Length: header lines to get size */ - if(!k->http_bodyless && + if(!k->http_bodyless && !data->set.ignorecl && checkprefix("Content-Length:", headp)) { curl_off_t contentlength; CURLofft offt = curlx_strtoofft(headp + 15, NULL, 10, &contentlength); @@ -3866,18 +3866,18 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, return result; } else if(checkprefix("Retry-After:", headp)) { - /* Retry-After = HTTP-date / delay-seconds */ - curl_off_t retry_after = 0; /* zero for unknown or "now" */ + /* Retry-After = HTTP-date / delay-seconds */ + curl_off_t retry_after = 0; /* zero for unknown or "now" */ time_t date = Curl_getdate_capped(&headp[12]); - if(-1 == date) { - /* not a date, try it as a decimal number */ + if(-1 == date) { + /* not a date, try it as a decimal number */ (void)curlx_strtoofft(&headp[12], NULL, 10, &retry_after); - } - else - /* convert date to number of seconds into the future */ - retry_after = date - time(NULL); - data->info.retry_after = retry_after; /* store it */ - } + } + else + /* convert date to number of seconds into the future */ + retry_after = date - time(NULL); + data->info.retry_after = retry_after; /* store it */ + } else if(!k->http_bodyless && checkprefix("Content-Range:", headp)) { /* Content-Range: bytes [num]- Content-Range: bytes: [num]- @@ -3918,9 +3918,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, here, or else use real peer host name. */ data->state.aptr.cookiehost? data->state.aptr.cookiehost:conn->host.name, - data->state.up.path, - (conn->handler->protocol&CURLPROTO_HTTPS)? - TRUE:FALSE); + data->state.up.path, + (conn->handler->protocol&CURLPROTO_HTTPS)? + TRUE:FALSE); Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } #endif @@ -3949,20 +3949,20 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, } #ifdef USE_SPNEGO else if(checkprefix("Persistent-Auth", headp)) { - struct negotiatedata *negdata = &conn->negotiate; - struct auth *authp = &data->state.authhost; - if(authp->picked == CURLAUTH_NEGOTIATE) { + struct negotiatedata *negdata = &conn->negotiate; + struct auth *authp = &data->state.authhost; + if(authp->picked == CURLAUTH_NEGOTIATE) { char *persistentauth = Curl_copy_header_value(headp); - if(!persistentauth) - return CURLE_OUT_OF_MEMORY; + if(!persistentauth) + return CURLE_OUT_OF_MEMORY; negdata->noauthpersist = checkprefix("false", persistentauth)? TRUE:FALSE; - negdata->havenoauthpersist = TRUE; - infof(data, "Negotiate: noauthpersist -> %d, header part: %s", - negdata->noauthpersist, persistentauth); - free(persistentauth); - } - } + negdata->havenoauthpersist = TRUE; + infof(data, "Negotiate: noauthpersist -> %d, header part: %s", + negdata->noauthpersist, persistentauth); + free(persistentauth); + } + } #endif else if((k->httpcode >= 300 && k->httpcode < 400) && checkprefix("Location:", headp) && @@ -3993,7 +3993,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, } #ifdef USE_HSTS - /* If enabled, the header is incoming and this is over HTTPS */ + /* If enabled, the header is incoming and this is over HTTPS */ else if(data->hsts && checkprefix("Strict-Transport-Security:", headp) && (conn->handler->flags & PROTOPT_SSL)) { CURLcode check = @@ -4011,24 +4011,24 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, #ifndef CURL_DISABLE_ALTSVC /* If enabled, the header is incoming and this is over HTTPS */ else if(data->asi && checkprefix("Alt-Svc:", headp) && - ((conn->handler->flags & PROTOPT_SSL) || -#ifdef CURLDEBUG - /* allow debug builds to circumvent the HTTPS restriction */ - getenv("CURL_ALTSVC_HTTP") -#else - 0 -#endif - )) { - /* the ALPN of the current request */ - enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1; - result = Curl_altsvc_parse(data, data->asi, + ((conn->handler->flags & PROTOPT_SSL) || +#ifdef CURLDEBUG + /* allow debug builds to circumvent the HTTPS restriction */ + getenv("CURL_ALTSVC_HTTP") +#else + 0 +#endif + )) { + /* the ALPN of the current request */ + enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1; + result = Curl_altsvc_parse(data, data->asi, &headp[ strlen("Alt-Svc:") ], - id, conn->host.name, - curlx_uitous(conn->remote_port)); - if(result) - return result; - } -#endif + id, conn->host.name, + curlx_uitous(conn->remote_port)); + if(result) + return result; + } +#endif else if(conn->handler->protocol & CURLPROTO_RTSP) { result = Curl_rtsp_parseheader(conn, headp); if(result) diff --git a/contrib/libs/curl/lib/http.h b/contrib/libs/curl/lib/http.h index 11524595b0..1aaec225e2 100644 --- a/contrib/libs/curl/lib/http.h +++ b/contrib/libs/curl/lib/http.h @@ -50,14 +50,14 @@ CURLcode Curl_buffer_send(struct dynbuf *in, size_t included_body_bytes, int socketindex); -CURLcode Curl_add_timecondition(const struct connectdata *conn, +CURLcode Curl_add_timecondition(const struct connectdata *conn, struct dynbuf *buf); CURLcode Curl_add_custom_headers(struct connectdata *conn, bool is_connect, struct dynbuf *req_buffer); -CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, +CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, struct dynbuf *buf, - struct Curl_easy *handle); + struct Curl_easy *handle); /* protocol-specific functions set up to be called by the main engine */ CURLcode Curl_http(struct connectdata *conn, bool *done); @@ -102,10 +102,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn); #endif /* CURL_DISABLE_HTTP */ -#ifdef USE_NGHTTP3 -struct h3out; /* see ngtcp2 */ -#endif - +#ifdef USE_NGHTTP3 +struct h3out; /* see ngtcp2 */ +#endif + /**************************************************************************** * HTTP unique setup ***************************************************************************/ @@ -152,38 +152,38 @@ struct HTTP { int status_code; /* HTTP status code */ const uint8_t *pausedata; /* pointer to data received in on_data_chunk */ size_t pauselen; /* the number of bytes left in data */ - bool close_handled; /* TRUE if stream closure is handled by libcurl */ - - char **push_headers; /* allocated array */ - size_t push_headers_used; /* number of entries filled in */ - size_t push_headers_alloc; /* number of entries allocated */ -#endif -#if defined(USE_NGHTTP2) || defined(USE_NGHTTP3) + bool close_handled; /* TRUE if stream closure is handled by libcurl */ + + char **push_headers; /* allocated array */ + size_t push_headers_used; /* number of entries filled in */ + size_t push_headers_alloc; /* number of entries allocated */ +#endif +#if defined(USE_NGHTTP2) || defined(USE_NGHTTP3) bool closed; /* TRUE on HTTP2 stream close */ char *mem; /* points to a buffer in memory to store received data */ size_t len; /* size of the buffer 'mem' points to */ size_t memlen; /* size of data copied to mem */ -#endif -#if defined(USE_NGHTTP2) || defined(ENABLE_QUIC) - /* fields used by both HTTP/2 and HTTP/3 */ +#endif +#if defined(USE_NGHTTP2) || defined(ENABLE_QUIC) + /* fields used by both HTTP/2 and HTTP/3 */ const uint8_t *upload_mem; /* points to a buffer to read from */ size_t upload_len; /* size of the buffer 'upload_mem' points to */ curl_off_t upload_left; /* number of bytes left to upload */ -#endif +#endif -#ifdef ENABLE_QUIC - /*********** for HTTP/3 we store stream-local data here *************/ - int64_t stream3_id; /* stream we are interested in */ +#ifdef ENABLE_QUIC + /*********** for HTTP/3 we store stream-local data here *************/ + int64_t stream3_id; /* stream we are interested in */ bool firstheader; /* FALSE until headers arrive */ - bool firstbody; /* FALSE until body arrives */ - bool h3req; /* FALSE until request is issued */ - bool upload_done; + bool firstbody; /* FALSE until body arrives */ + bool h3req; /* FALSE until request is issued */ + bool upload_done; #endif -#ifdef USE_NGHTTP3 +#ifdef USE_NGHTTP3 size_t unacked_window; - struct h3out *h3out; /* per-stream buffers for upload */ + struct h3out *h3out; /* per-stream buffers for upload */ struct dynbuf overflow; /* excess data received during a single Curl_read */ -#endif +#endif }; #ifdef USE_NGHTTP2 diff --git a/contrib/libs/curl/lib/http2.c b/contrib/libs/curl/lib/http2.c index 89bd874a6b..b138fb4b0f 100644 --- a/contrib/libs/curl/lib/http2.c +++ b/contrib/libs/curl/lib/http2.c @@ -93,7 +93,7 @@ void Curl_http2_init_userset(struct UserDefined *set) } static int http2_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock) + curl_socket_t *sock) { const struct http_conn *c = &conn->proto.httpc; struct SingleRequest *k = &conn->data->req; @@ -114,9 +114,9 @@ static int http2_perform_getsock(const struct connectdata *conn, } static int http2_getsock(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { - return http2_perform_getsock(conn, socks); + return http2_perform_getsock(conn, socks); } /* @@ -225,7 +225,7 @@ static unsigned int http2_conncheck(struct connectdata *check, if(checks_to_perform & CONNCHECK_KEEPALIVE) { struct curltime now = Curl_now(); - timediff_t elapsed = Curl_timediff(now, check->keepalive); + timediff_t elapsed = Curl_timediff(now, check->keepalive); if(elapsed > check->upkeep_interval_ms) { /* Perform an HTTP/2 PING */ @@ -254,7 +254,7 @@ static unsigned int http2_conncheck(struct connectdata *check, return ret_val; } -/* called from http_setup_conn */ +/* called from http_setup_conn */ void Curl_http2_setup_req(struct Curl_easy *data) { struct HTTP *http = data->req.p.http; @@ -269,7 +269,7 @@ void Curl_http2_setup_req(struct Curl_easy *data) http->memlen = 0; } -/* called from http_setup_conn */ +/* called from http_setup_conn */ void Curl_http2_setup_conn(struct connectdata *conn) { conn->proto.httpc.settings.max_concurrent_streams = @@ -612,18 +612,18 @@ static int push_promise(struct Curl_easy *data, return rv; } -/* - * multi_connchanged() is called to tell that there is a connection in - * this multi handle that has changed state (multiplexing become possible, the - * number of allowed streams changed or similar), and a subsequent use of this - * multi handle should move CONNECT_PEND handles back to CONNECT to have them - * retry. - */ -static void multi_connchanged(struct Curl_multi *multi) -{ - multi->recheckstate = TRUE; -} - +/* + * multi_connchanged() is called to tell that there is a connection in + * this multi handle that has changed state (multiplexing become possible, the + * number of allowed streams changed or similar), and a subsequent use of this + * multi handle should move CONNECT_PEND handles back to CONNECT to have them + * retry. + */ +static void multi_connchanged(struct Curl_multi *multi) +{ + multi->recheckstate = TRUE; +} + static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, void *userp) { @@ -656,7 +656,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, infof(conn->data, "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n", httpc->settings.max_concurrent_streams); - multi_connchanged(conn->data->multi); + multi_connchanged(conn->data->multi); } } return 0; @@ -813,7 +813,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer" ", stream %u\n", len - nread, stream_id)); - data_s->conn->proto.httpc.pause_stream_id = stream_id; + data_s->conn->proto.httpc.pause_stream_id = stream_id; return NGHTTP2_ERR_PAUSE; } @@ -821,7 +821,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, /* pause execution of nghttp2 if we received data for another handle in order to process them first. */ if(conn->data != data_s) { - data_s->conn->proto.httpc.pause_stream_id = stream_id; + data_s->conn->proto.httpc.pause_stream_id = stream_id; return NGHTTP2_ERR_PAUSE; } @@ -868,10 +868,10 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, stream_id); DEBUGASSERT(0); } - if(stream_id == httpc->pause_stream_id) { - H2BUGF(infof(data_s, "Stopped the pause stream!\n")); - httpc->pause_stream_id = 0; - } + if(stream_id == httpc->pause_stream_id) { + H2BUGF(infof(data_s, "Stopped the pause stream!\n")); + httpc->pause_stream_id = 0; + } H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id)); stream->stream_id = 0; /* cleared */ } @@ -965,30 +965,30 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(frame->hd.type == NGHTTP2_PUSH_PROMISE) { char *h; - if(!strcmp(":authority", (const char *)name)) { - /* pseudo headers are lower case */ - int rc = 0; - char *check = aprintf("%s:%d", conn->host.name, conn->remote_port); - if(!check) - /* no memory */ - return NGHTTP2_ERR_CALLBACK_FAILURE; + if(!strcmp(":authority", (const char *)name)) { + /* pseudo headers are lower case */ + int rc = 0; + char *check = aprintf("%s:%d", conn->host.name, conn->remote_port); + if(!check) + /* no memory */ + return NGHTTP2_ERR_CALLBACK_FAILURE; if(!Curl_strcasecompare(check, (const char *)value) && ((conn->remote_port != conn->given->defport) || !Curl_strcasecompare(conn->host.name, (const char *)value))) { - /* This is push is not for the same authority that was asked for in - * the URL. RFC 7540 section 8.2 says: "A client MUST treat a - * PUSH_PROMISE for which the server is not authoritative as a stream - * error of type PROTOCOL_ERROR." - */ - (void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, - stream_id, NGHTTP2_PROTOCOL_ERROR); - rc = NGHTTP2_ERR_CALLBACK_FAILURE; - } - free(check); - if(rc) - return rc; - } - + /* This is push is not for the same authority that was asked for in + * the URL. RFC 7540 section 8.2 says: "A client MUST treat a + * PUSH_PROMISE for which the server is not authoritative as a stream + * error of type PROTOCOL_ERROR." + */ + (void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, + stream_id, NGHTTP2_PROTOCOL_ERROR); + rc = NGHTTP2_ERR_CALLBACK_FAILURE; + } + free(check); + if(rc) + return rc; + } + if(!stream->push_headers) { stream->push_headers_alloc = 10; stream->push_headers = malloc(stream->push_headers_alloc * @@ -1194,10 +1194,10 @@ void Curl_http2_done(struct Curl_easy *data, bool premature) httpc->pause_stream_id = 0; } } - - if(data->state.drain) - drained_transfer(data, httpc); - + + if(data->state.drain) + drained_transfer(data, httpc); + /* -1 means unassigned and 0 means cleared */ if(http->stream_id > 0) { int rv = nghttp2_session_set_stream_user_data(httpc->h2, @@ -1214,7 +1214,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature) /* * Initialize nghttp2 for a Curl connection */ -static CURLcode http2_init(struct connectdata *conn) +static CURLcode http2_init(struct connectdata *conn) { if(!conn->proto.httpc.h2) { int rc; @@ -1575,11 +1575,11 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, if(should_close_session(httpc)) { H2BUGF(infof(data, "http2_recv: nothing to do in this session\n")); - if(conn->bits.close) { - /* already marked for closure, return OK and we're done */ - *err = CURLE_OK; - return 0; - } + if(conn->bits.close) { + /* already marked for closure, return OK and we're done */ + *err = CURLE_OK; + return 0; + } *err = CURLE_HTTP2; return -1; } @@ -1742,14 +1742,14 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, else if(!stream->closed) { drained_transfer(data, httpc); } - else - /* this stream is closed, trigger a another read ASAP to detect that */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); + else + /* this stream is closed, trigger a another read ASAP to detect that */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); return retlen; } - if(stream->closed) - return 0; + if(stream->closed) + return 0; *err = CURLE_AGAIN; H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n", stream->stream_id)); @@ -1834,9 +1834,9 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, const void *mem, size_t len, CURLcode *err) { /* - * Currently, we send request in this function, but this function is also - * used to send request body. It would be nice to add dedicated function for - * request. + * Currently, we send request in this function, but this function is also + * used to send request body. It would be nice to add dedicated function for + * request. */ int rv; struct http_conn *httpc = &conn->proto.httpc; @@ -1869,11 +1869,11 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, are going to send or sending request body in DATA frame */ stream->upload_mem = mem; stream->upload_len = len; - rv = nghttp2_session_resume_data(h2, stream->stream_id); - if(nghttp2_is_fatal(rv)) { - *err = CURLE_SEND_ERROR; - return -1; - } + rv = nghttp2_session_resume_data(h2, stream->stream_id); + if(nghttp2_is_fatal(rv)) { + *err = CURLE_SEND_ERROR; + return -1; + } rv = h2_session_send(conn->data, h2); if(nghttp2_is_fatal(rv)) { *err = CURLE_SEND_ERROR; @@ -2172,7 +2172,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn) else conn->handler = &Curl_handler_http2; - result = http2_init(conn); + result = http2_init(conn); if(result) { Curl_dyn_free(&stream->header_recvbuf); return result; @@ -2196,7 +2196,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn) conn->bundle->multiuse = BUNDLE_MULTIPLEX; infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n"); - multi_connchanged(conn->data->multi); + multi_connchanged(conn->data->multi); return CURLE_OK; } diff --git a/contrib/libs/curl/lib/http2.h b/contrib/libs/curl/lib/http2.h index 7ae025d109..43a6863abe 100644 --- a/contrib/libs/curl/lib/http2.h +++ b/contrib/libs/curl/lib/http2.h @@ -47,7 +47,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req, CURLcode Curl_http2_setup(struct connectdata *conn); CURLcode Curl_http2_switched(struct connectdata *conn, const char *data, size_t nread); -/* called from http_setup_conn */ +/* called from http_setup_conn */ void Curl_http2_setup_conn(struct connectdata *conn); void Curl_http2_setup_req(struct Curl_easy *data); void Curl_http2_done(struct Curl_easy *data, bool premature); diff --git a/contrib/libs/curl/lib/http_digest.c b/contrib/libs/curl/lib/http_digest.c index 0467847586..dfa40dcb61 100644 --- a/contrib/libs/curl/lib/http_digest.c +++ b/contrib/libs/curl/lib/http_digest.c @@ -28,7 +28,7 @@ #include "strcase.h" #include "vauth/vauth.h" #include "http_digest.h" - + /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -176,7 +176,7 @@ CURLcode Curl_output_digest(struct connectdata *conn, return CURLE_OK; } -void Curl_http_auth_cleanup_digest(struct Curl_easy *data) +void Curl_http_auth_cleanup_digest(struct Curl_easy *data) { Curl_auth_digest_cleanup(&data->state.digest); Curl_auth_digest_cleanup(&data->state.proxydigest); diff --git a/contrib/libs/curl/lib/http_digest.h b/contrib/libs/curl/lib/http_digest.h index a02443424c..f7001edec1 100644 --- a/contrib/libs/curl/lib/http_digest.h +++ b/contrib/libs/curl/lib/http_digest.h @@ -23,8 +23,8 @@ ***************************************************************************/ #include "curl_setup.h" -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) - +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) + /* this is for digest header input */ CURLcode Curl_input_digest(struct connectdata *conn, bool proxy, const char *header); @@ -35,8 +35,8 @@ CURLcode Curl_output_digest(struct connectdata *conn, const unsigned char *request, const unsigned char *uripath); -void Curl_http_auth_cleanup_digest(struct Curl_easy *data); +void Curl_http_auth_cleanup_digest(struct Curl_easy *data); + +#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_CRYPTO_AUTH */ -#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_CRYPTO_AUTH */ - #endif /* HEADER_CURL_HTTP_DIGEST_H */ diff --git a/contrib/libs/curl/lib/http_negotiate.c b/contrib/libs/curl/lib/http_negotiate.c index 5737132ce8..872d172fc6 100644 --- a/contrib/libs/curl/lib/http_negotiate.c +++ b/contrib/libs/curl/lib/http_negotiate.c @@ -49,7 +49,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, /* Point to the correct struct with this */ struct negotiatedata *neg_ctx; - curlnegotiate state; + curlnegotiate state; if(proxy) { #ifndef CURL_DISABLE_PROXY @@ -58,8 +58,8 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, service = data->set.str[STRING_PROXY_SERVICE_NAME] ? data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; host = conn->http_proxy.host.name; - neg_ctx = &conn->proxyneg; - state = conn->proxy_negotiate_state; + neg_ctx = &conn->proxyneg; + state = conn->proxy_negotiate_state; #else return CURLE_NOT_BUILT_IN; #endif @@ -70,8 +70,8 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : "HTTP"; host = conn->host.name; - neg_ctx = &conn->negotiate; - state = conn->http_negotiate_state; + neg_ctx = &conn->negotiate; + state = conn->http_negotiate_state; } /* Not set means empty */ @@ -87,42 +87,42 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, header++; len = strlen(header); - neg_ctx->havenegdata = len != 0; + neg_ctx->havenegdata = len != 0; if(!len) { - if(state == GSS_AUTHSUCC) { - infof(conn->data, "Negotiate auth restarted\n"); - Curl_http_auth_cleanup_negotiate(conn); - } - else if(state != GSS_AUTHNONE) { - /* The server rejected our authentication and hasn't supplied any more + if(state == GSS_AUTHSUCC) { + infof(conn->data, "Negotiate auth restarted\n"); + Curl_http_auth_cleanup_negotiate(conn); + } + else if(state != GSS_AUTHNONE) { + /* The server rejected our authentication and hasn't supplied any more negotiation mechanisms */ - Curl_http_auth_cleanup_negotiate(conn); + Curl_http_auth_cleanup_negotiate(conn); return CURLE_LOGIN_DENIED; } } - /* Supports SSL channel binding for Windows ISS extended protection */ -#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) - neg_ctx->sslContext = conn->sslContext; -#endif - + /* Supports SSL channel binding for Windows ISS extended protection */ +#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) + neg_ctx->sslContext = conn->sslContext; +#endif + /* Initialize the security context and decode our challenge */ result = Curl_auth_decode_spnego_message(data, userp, passwdp, service, host, header, neg_ctx); if(result) - Curl_http_auth_cleanup_negotiate(conn); + Curl_http_auth_cleanup_negotiate(conn); return result; } CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) { - struct negotiatedata *neg_ctx = proxy ? &conn->proxyneg : - &conn->negotiate; - struct auth *authp = proxy ? &conn->data->state.authproxy : - &conn->data->state.authhost; - curlnegotiate *state = proxy ? &conn->proxy_negotiate_state : + struct negotiatedata *neg_ctx = proxy ? &conn->proxyneg : + &conn->negotiate; + struct auth *authp = proxy ? &conn->data->state.authproxy : + &conn->data->state.authhost; + curlnegotiate *state = proxy ? &conn->proxy_negotiate_state : &conn->http_negotiate_state; struct Curl_easy *data = conn->data; char *base64 = NULL; @@ -130,96 +130,96 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) char *userp; CURLcode result; - authp->done = FALSE; - - if(*state == GSS_AUTHRECV) { - if(neg_ctx->havenegdata) { - neg_ctx->havemultiplerequests = TRUE; - } - } - else if(*state == GSS_AUTHSUCC) { - if(!neg_ctx->havenoauthpersist) { - neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests; - } - } - - if(neg_ctx->noauthpersist || - (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) { - - if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) { - infof(conn->data, "Curl_output_negotiate, " - "no persistent authentication: cleanup existing context"); - Curl_http_auth_cleanup_negotiate(conn); - } - if(!neg_ctx->context) { - result = Curl_input_negotiate(conn, proxy, "Negotiate"); - if(result == CURLE_AUTH_ERROR) { - /* negotiate auth failed, let's continue unauthenticated to stay - * compatible with the behavior before curl-7_64_0-158-g6c6035532 */ - authp->done = TRUE; - return CURLE_OK; - } - else if(result) - return result; - } - - result = Curl_auth_create_spnego_message(conn->data, - neg_ctx, &base64, &len); - if(result) - return result; - - userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "", + authp->done = FALSE; + + if(*state == GSS_AUTHRECV) { + if(neg_ctx->havenegdata) { + neg_ctx->havemultiplerequests = TRUE; + } + } + else if(*state == GSS_AUTHSUCC) { + if(!neg_ctx->havenoauthpersist) { + neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests; + } + } + + if(neg_ctx->noauthpersist || + (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) { + + if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) { + infof(conn->data, "Curl_output_negotiate, " + "no persistent authentication: cleanup existing context"); + Curl_http_auth_cleanup_negotiate(conn); + } + if(!neg_ctx->context) { + result = Curl_input_negotiate(conn, proxy, "Negotiate"); + if(result == CURLE_AUTH_ERROR) { + /* negotiate auth failed, let's continue unauthenticated to stay + * compatible with the behavior before curl-7_64_0-158-g6c6035532 */ + authp->done = TRUE; + return CURLE_OK; + } + else if(result) + return result; + } + + result = Curl_auth_create_spnego_message(conn->data, + neg_ctx, &base64, &len); + if(result) + return result; + + userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "", base64); - - if(proxy) { + + if(proxy) { Curl_safefree(data->state.aptr.proxyuserpwd); data->state.aptr.proxyuserpwd = userp; - } - else { + } + else { Curl_safefree(data->state.aptr.userpwd); data->state.aptr.userpwd = userp; - } - - free(base64); - - if(userp == NULL) { - return CURLE_OUT_OF_MEMORY; - } - - *state = GSS_AUTHSENT; - #ifdef HAVE_GSSAPI - if(neg_ctx->status == GSS_S_COMPLETE || - neg_ctx->status == GSS_S_CONTINUE_NEEDED) { - *state = GSS_AUTHDONE; - } - #else - #ifdef USE_WINDOWS_SSPI - if(neg_ctx->status == SEC_E_OK || - neg_ctx->status == SEC_I_CONTINUE_NEEDED) { - *state = GSS_AUTHDONE; - } - #endif - #endif + } + + free(base64); + + if(userp == NULL) { + return CURLE_OUT_OF_MEMORY; + } + + *state = GSS_AUTHSENT; + #ifdef HAVE_GSSAPI + if(neg_ctx->status == GSS_S_COMPLETE || + neg_ctx->status == GSS_S_CONTINUE_NEEDED) { + *state = GSS_AUTHDONE; + } + #else + #ifdef USE_WINDOWS_SSPI + if(neg_ctx->status == SEC_E_OK || + neg_ctx->status == SEC_I_CONTINUE_NEEDED) { + *state = GSS_AUTHDONE; + } + #endif + #endif } - - if(*state == GSS_AUTHDONE || *state == GSS_AUTHSUCC) { - /* connection is already authenticated, - * don't send a header in future requests */ - authp->done = TRUE; + + if(*state == GSS_AUTHDONE || *state == GSS_AUTHSUCC) { + /* connection is already authenticated, + * don't send a header in future requests */ + authp->done = TRUE; } - neg_ctx->havenegdata = FALSE; + neg_ctx->havenegdata = FALSE; - return CURLE_OK; + return CURLE_OK; } -void Curl_http_auth_cleanup_negotiate(struct connectdata *conn) +void Curl_http_auth_cleanup_negotiate(struct connectdata *conn) { - conn->http_negotiate_state = GSS_AUTHNONE; - conn->proxy_negotiate_state = GSS_AUTHNONE; - - Curl_auth_cleanup_spnego(&conn->negotiate); - Curl_auth_cleanup_spnego(&conn->proxyneg); + conn->http_negotiate_state = GSS_AUTHNONE; + conn->proxy_negotiate_state = GSS_AUTHNONE; + + Curl_auth_cleanup_spnego(&conn->negotiate); + Curl_auth_cleanup_spnego(&conn->proxyneg); } #endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */ diff --git a/contrib/libs/curl/lib/http_negotiate.h b/contrib/libs/curl/lib/http_negotiate.h index ae6ae6e594..cf1d007dce 100644 --- a/contrib/libs/curl/lib/http_negotiate.h +++ b/contrib/libs/curl/lib/http_negotiate.h @@ -22,7 +22,7 @@ * ***************************************************************************/ -#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) +#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) /* this is for Negotiate header input */ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, @@ -31,7 +31,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, /* this is for creating Negotiate header output */ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy); -void Curl_http_auth_cleanup_negotiate(struct connectdata *conn); +void Curl_http_auth_cleanup_negotiate(struct connectdata *conn); #else /* !CURL_DISABLE_HTTP && USE_SPNEGO */ #define Curl_http_auth_cleanup_negotiate(x) diff --git a/contrib/libs/curl/lib/http_ntlm.c b/contrib/libs/curl/lib/http_ntlm.c index 127f278711..91e1d1f714 100644 --- a/contrib/libs/curl/lib/http_ntlm.c +++ b/contrib/libs/curl/lib/http_ntlm.c @@ -66,11 +66,11 @@ CURLcode Curl_input_ntlm(struct connectdata *conn, { /* point to the correct struct with this */ struct ntlmdata *ntlm; - curlntlm *state; + curlntlm *state; CURLcode result = CURLE_OK; ntlm = proxy ? &conn->proxyntlm : &conn->ntlm; - state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state; + state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state; if(checkprefix("NTLM", header)) { header += strlen("NTLM"); @@ -83,25 +83,25 @@ CURLcode Curl_input_ntlm(struct connectdata *conn, if(result) return result; - *state = NTLMSTATE_TYPE2; /* We got a type-2 message */ + *state = NTLMSTATE_TYPE2; /* We got a type-2 message */ } else { - if(*state == NTLMSTATE_LAST) { + if(*state == NTLMSTATE_LAST) { infof(conn->data, "NTLM auth restarted\n"); - Curl_http_auth_cleanup_ntlm(conn); + Curl_http_auth_cleanup_ntlm(conn); } - else if(*state == NTLMSTATE_TYPE3) { + else if(*state == NTLMSTATE_TYPE3) { infof(conn->data, "NTLM handshake rejected\n"); - Curl_http_auth_cleanup_ntlm(conn); - *state = NTLMSTATE_NONE; + Curl_http_auth_cleanup_ntlm(conn); + *state = NTLMSTATE_NONE; return CURLE_REMOTE_ACCESS_DENIED; } - else if(*state >= NTLMSTATE_TYPE1) { + else if(*state >= NTLMSTATE_TYPE1) { infof(conn->data, "NTLM handshake failure (internal error)\n"); return CURLE_REMOTE_ACCESS_DENIED; } - *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */ + *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */ } } @@ -129,7 +129,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) /* point to the correct struct with this */ struct ntlmdata *ntlm; - curlntlm *state; + curlntlm *state; struct auth *authp; struct Curl_easy *data = conn->data; @@ -146,7 +146,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) conn->data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; hostname = conn->http_proxy.host.name; ntlm = &conn->proxyntlm; - state = &conn->proxy_ntlm_state; + state = &conn->proxy_ntlm_state; authp = &conn->data->state.authproxy; #else return CURLE_NOT_BUILT_IN; @@ -160,7 +160,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) conn->data->set.str[STRING_SERVICE_NAME] : "HTTP"; hostname = conn->host.name; ntlm = &conn->ntlm; - state = &conn->http_ntlm_state; + state = &conn->http_ntlm_state; authp = &conn->data->state.authhost; } authp->done = FALSE; @@ -179,12 +179,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) if(s_hSecDll == NULL) return err; } -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - ntlm->sslContext = conn->sslContext; +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + ntlm->sslContext = conn->sslContext; +#endif #endif -#endif - switch(*state) { + switch(*state) { case NTLMSTATE_TYPE1: default: /* for the weird cases we (re)start here */ /* Create a type-1 message */ @@ -226,7 +226,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); - *state = NTLMSTATE_TYPE3; /* we send a type-3 */ + *state = NTLMSTATE_TYPE3; /* we send a type-3 */ authp->done = TRUE; } break; @@ -234,7 +234,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) case NTLMSTATE_TYPE3: /* connection is already authenticated, * don't send a header in future requests */ - *state = NTLMSTATE_LAST; + *state = NTLMSTATE_LAST; /* FALLTHROUGH */ case NTLMSTATE_LAST: Curl_safefree(*allocuserpwd); @@ -245,13 +245,13 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) return CURLE_OK; } -void Curl_http_auth_cleanup_ntlm(struct connectdata *conn) +void Curl_http_auth_cleanup_ntlm(struct connectdata *conn) { - Curl_auth_cleanup_ntlm(&conn->ntlm); - Curl_auth_cleanup_ntlm(&conn->proxyntlm); + Curl_auth_cleanup_ntlm(&conn->ntlm); + Curl_auth_cleanup_ntlm(&conn->proxyntlm); #if defined(NTLM_WB_ENABLED) - Curl_http_auth_cleanup_ntlm_wb(conn); + Curl_http_auth_cleanup_ntlm_wb(conn); #endif } diff --git a/contrib/libs/curl/lib/http_ntlm.h b/contrib/libs/curl/lib/http_ntlm.h index 64eae0e033..5ddf538727 100644 --- a/contrib/libs/curl/lib/http_ntlm.h +++ b/contrib/libs/curl/lib/http_ntlm.h @@ -1,5 +1,5 @@ -#ifndef HEADER_CURL_HTTP_NTLM_H -#define HEADER_CURL_HTTP_NTLM_H +#ifndef HEADER_CURL_HTTP_NTLM_H +#define HEADER_CURL_HTTP_NTLM_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -33,10 +33,10 @@ CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy, /* this is for creating ntlm header output */ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy); -void Curl_http_auth_cleanup_ntlm(struct connectdata *conn); +void Curl_http_auth_cleanup_ntlm(struct connectdata *conn); #else /* !CURL_DISABLE_HTTP && USE_NTLM */ #define Curl_http_auth_cleanup_ntlm(x) #endif -#endif /* HEADER_CURL_HTTP_NTLM_H */ +#endif /* HEADER_CURL_HTTP_NTLM_H */ diff --git a/contrib/libs/curl/lib/http_proxy.c b/contrib/libs/curl/lib/http_proxy.c index 8a86e1b8cf..4242251219 100644 --- a/contrib/libs/curl/lib/http_proxy.c +++ b/contrib/libs/curl/lib/http_proxy.c @@ -618,7 +618,7 @@ static CURLcode CONNECT(struct connectdata *conn, data->state.aptr.proxyuserpwd = NULL; data->state.authproxy.done = TRUE; - data->state.authproxy.multipass = FALSE; + data->state.authproxy.multipass = FALSE; infof(data, "Proxy replied %d to CONNECT request\n", data->info.httpproxycode); @@ -631,7 +631,7 @@ static CURLcode CONNECT(struct connectdata *conn, void Curl_connect_free(struct Curl_easy *data) { - struct connectdata *conn = data->conn; + struct connectdata *conn = data->conn; struct http_connect_state *s = conn->connect_state; if(s) { free(s); diff --git a/contrib/libs/curl/lib/if2ip.c b/contrib/libs/curl/lib/if2ip.c index 7f3adabc59..bf397aad45 100644 --- a/contrib/libs/curl/lib/if2ip.c +++ b/contrib/libs/curl/lib/if2ip.c @@ -94,7 +94,7 @@ unsigned int Curl_ipv6_scope(const struct sockaddr *sa) #if defined(HAVE_GETIFADDRS) if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - unsigned int local_scope_id, const char *interf, + unsigned int local_scope_id, const char *interf, char *buf, int buf_size) { struct ifaddrs *iface, *head; @@ -106,7 +106,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, #if !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) || \ !defined(ENABLE_IPV6) - (void) local_scope_id; + (void) local_scope_id; #endif if(getifaddrs(&head) >= 0) { @@ -120,9 +120,9 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, char ipstr[64]; #ifdef ENABLE_IPV6 if(af == AF_INET6) { -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID unsigned int scopeid = 0; -#endif +#endif unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr); if(ifscope != remote_scope) { @@ -142,14 +142,14 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, ->sin6_scope_id; /* If given, scope id should match. */ - if(local_scope_id && scopeid != local_scope_id) { + if(local_scope_id && scopeid != local_scope_id) { if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED; continue; } - - if(scopeid) + + if(scopeid) msnprintf(scope, sizeof(scope), "%%%u", scopeid); #endif } @@ -179,7 +179,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, #elif defined(HAVE_IOCTL_SIOCGIFADDR) if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - unsigned int local_scope_id, const char *interf, + unsigned int local_scope_id, const char *interf, char *buf, int buf_size) { struct ifreq req; @@ -190,7 +190,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, const char *r; (void)remote_scope; - (void)local_scope_id; + (void)local_scope_id; if(!interf || (af != AF_INET)) return IF2IP_NOT_FOUND; @@ -228,12 +228,12 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, #else if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - unsigned int local_scope_id, const char *interf, + unsigned int local_scope_id, const char *interf, char *buf, int buf_size) { (void) af; (void) remote_scope; - (void) local_scope_id; + (void) local_scope_id; (void) interf; (void) buf; (void) buf_size; diff --git a/contrib/libs/curl/lib/if2ip.h b/contrib/libs/curl/lib/if2ip.h index 5de5c1e497..e074e476dc 100644 --- a/contrib/libs/curl/lib/if2ip.h +++ b/contrib/libs/curl/lib/if2ip.h @@ -39,7 +39,7 @@ typedef enum { } if2ip_result_t; if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - unsigned int local_scope_id, const char *interf, + unsigned int local_scope_id, const char *interf, char *buf, int buf_size); #ifdef __INTERIX diff --git a/contrib/libs/curl/lib/imap.c b/contrib/libs/curl/lib/imap.c index 283ea34e36..c6dd7a2323 100644 --- a/contrib/libs/curl/lib/imap.c +++ b/contrib/libs/curl/lib/imap.c @@ -28,7 +28,7 @@ * RFC4959 IMAP Extension for SASL Initial Client Response * RFC5092 IMAP URL Scheme * RFC6749 OAuth 2.0 Authorization Framework - * RFC8314 Use of TLS for Email Submission and Access + * RFC8314 Use of TLS for Email Submission and Access * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt> * ***************************************************************************/ @@ -95,7 +95,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, static CURLcode imap_connect(struct connectdata *conn, bool *done); static CURLcode imap_disconnect(struct connectdata *conn, bool dead); static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done); -static int imap_getsock(struct connectdata *conn, curl_socket_t *socks); +static int imap_getsock(struct connectdata *conn, curl_socket_t *socks); static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done); static CURLcode imap_setup_connection(struct connectdata *conn); static char *imap_atom(const char *str, bool escape_only); @@ -318,7 +318,7 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len, a space and optionally some text as per RFC-3501 for the AUTHENTICATE and APPEND commands and as outlined in Section 4. Examples of RFC-4959 but some e-mail servers ignore this and only send a single + instead. */ - if(imap && !imap->custom && ((len == 3 && line[0] == '+') || + if(imap && !imap->custom && ((len == 3 && line[0] == '+') || (len >= 2 && !memcmp("+ ", line, 2)))) { switch(imapc->state) { /* States which are interested in continuation responses */ @@ -446,7 +446,7 @@ static CURLcode imap_perform_capability(struct connectdata *conn) static CURLcode imap_perform_starttls(struct connectdata *conn) { /* Send the STARTTLS command */ - CURLcode result = imap_sendf(conn, "STARTTLS"); + CURLcode result = imap_sendf(conn, "STARTTLS"); if(!result) state(conn, IMAP_STARTTLS); @@ -462,10 +462,10 @@ static CURLcode imap_perform_starttls(struct connectdata *conn) */ static CURLcode imap_perform_upgrade_tls(struct connectdata *conn) { - /* Start the SSL connection */ + /* Start the SSL connection */ struct imap_conn *imapc = &conn->proto.imapc; - CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, - &imapc->ssldone); + CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, + &imapc->ssldone); if(!result) { if(imapc->state != IMAP_UPGRADETLS) @@ -825,7 +825,7 @@ static CURLcode imap_perform_search(struct connectdata *conn) static CURLcode imap_perform_logout(struct connectdata *conn) { /* Send the LOGOUT command */ - CURLcode result = imap_sendf(conn, "LOGOUT"); + CURLcode result = imap_sendf(conn, "LOGOUT"); if(!result) state(conn, IMAP_LOGOUT); @@ -1039,7 +1039,7 @@ static CURLcode imap_state_listsearch_resp(struct connectdata *conn, line[len] = '\0'; } else if(imapcode != IMAP_RESP_OK) - result = CURLE_QUOTE_ERROR; + result = CURLE_QUOTE_ERROR; else /* End of DO phase */ state(conn, IMAP_STOP); @@ -1111,7 +1111,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, if(imapcode != '*') { Curl_pgrsSetDownloadSize(data, -1); state(conn, IMAP_STOP); - return CURLE_REMOTE_FILE_NOT_FOUND; + return CURLE_REMOTE_FILE_NOT_FOUND; } /* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse @@ -1174,14 +1174,14 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, if(data->req.bytecount == size) /* The entire data is already transferred! */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); else { /* IMAP download */ data->req.maxdownload = size; /* force a recv/send check of this connection, as the data might've been read off the socket already */ data->conn->cselect_bits = CURL_CSELECT_IN; - Curl_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1); } } else { @@ -1231,7 +1231,7 @@ static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode, Curl_pgrsSetUploadSize(data, data->state.infilesize); /* IMAP upload */ - Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); /* End of DO phase */ state(conn, IMAP_STOP); @@ -1359,20 +1359,20 @@ static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done) return result; } - result = Curl_pp_statemach(&imapc->pp, FALSE, FALSE); + result = Curl_pp_statemach(&imapc->pp, FALSE, FALSE); *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE; return result; } -static CURLcode imap_block_statemach(struct connectdata *conn, - bool disconnecting) +static CURLcode imap_block_statemach(struct connectdata *conn, + bool disconnecting) { CURLcode result = CURLE_OK; struct imap_conn *imapc = &conn->proto.imapc; while(imapc->state != IMAP_STOP && !result) - result = Curl_pp_statemach(&imapc->pp, TRUE, disconnecting); + result = Curl_pp_statemach(&imapc->pp, TRUE, disconnecting); return result; } @@ -1393,9 +1393,9 @@ static CURLcode imap_init(struct connectdata *conn) } /* For the IMAP "protocol connect" and "doing" phases only */ -static int imap_getsock(struct connectdata *conn, curl_socket_t *socks) +static int imap_getsock(struct connectdata *conn, curl_socket_t *socks) { - return Curl_pp_getsock(&conn->proto.imapc.pp, socks); + return Curl_pp_getsock(&conn->proto.imapc.pp, socks); } /*********************************************************************** @@ -1489,9 +1489,9 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, state(conn, IMAP_APPEND_FINAL); } - /* Run the state-machine */ + /* Run the state-machine */ if(!result) - result = imap_block_statemach(conn, FALSE); + result = imap_block_statemach(conn, FALSE); } /* Cleanup our per-request based variables */ @@ -1629,7 +1629,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection) point! */ if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart) if(!imap_perform_logout(conn)) - (void)imap_block_statemach(conn, TRUE); /* ignore errors on LOGOUT */ + (void)imap_block_statemach(conn, TRUE); /* ignore errors on LOGOUT */ /* Disconnect from the server */ Curl_pp_disconnect(&imapc->pp); @@ -1654,7 +1654,7 @@ static CURLcode imap_dophase_done(struct connectdata *conn, bool connected) if(imap->transfer != FTPTRANSFER_BODY) /* no data to transfer */ - Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); return CURLE_OK; } @@ -1783,7 +1783,7 @@ static char *imap_atom(const char *str, bool escape_only) return NULL; /* Look for "atom-specials", counting the backslash and quote characters as - these will need escaping */ + these will need escaping */ p1 = str; while(*p1) { if(*p1 == '\\') diff --git a/contrib/libs/curl/lib/inet_pton.c b/contrib/libs/curl/lib/inet_pton.c index e5d441d445..4923cae245 100644 --- a/contrib/libs/curl/lib/inet_pton.c +++ b/contrib/libs/curl/lib/inet_pton.c @@ -153,7 +153,7 @@ inet_pton6(const char *src, unsigned char *dst) static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; - const char *curtok; + const char *curtok; int ch, saw_xdigit; size_t val; @@ -168,7 +168,7 @@ inet_pton6(const char *src, unsigned char *dst) saw_xdigit = 0; val = 0; while((ch = *src++) != '\0') { - const char *xdigits; + const char *xdigits; const char *pch; pch = strchr((xdigits = xdigits_l), ch); diff --git a/contrib/libs/curl/lib/krb5.c b/contrib/libs/curl/lib/krb5.c index 9ee9aaae33..66394f4f30 100644 --- a/contrib/libs/curl/lib/krb5.c +++ b/contrib/libs/curl/lib/krb5.c @@ -1,6 +1,6 @@ /* GSSAPI/krb5 support for FTP - loosely based on old krb4.c * - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * Copyright (c) 2004 - 2020 Daniel Stenberg * All rights reserved. @@ -379,8 +379,8 @@ static void krb5_end(void *app_data) OM_uint32 min; gss_ctx_id_t *context = app_data; if(*context != GSS_C_NO_CONTEXT) { - OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER); - (void)maj; + OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER); + (void)maj; DEBUGASSERT(maj == GSS_S_COMPLETE); } } diff --git a/contrib/libs/curl/lib/ldap.c b/contrib/libs/curl/lib/ldap.c index 2df0e18389..ab60704225 100644 --- a/contrib/libs/curl/lib/ldap.c +++ b/contrib/libs/curl/lib/ldap.c @@ -46,9 +46,9 @@ #else # define LDAP_DEPRECATED 1 /* Be sure ldap_init() is defined. */ # ifdef HAVE_LBER_H -# error #include <lber.h> +# error #include <lber.h> # endif -# error #include <ldap.h> +# error #include <ldap.h> # if (defined(HAVE_LDAP_SSL) && defined(HAVE_LDAP_SSL_H)) # include <ldap_ssl.h> # endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */ @@ -728,7 +728,7 @@ quit: FREE_ON_WINLDAP(host); /* no data to transfer */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); connclose(conn, "LDAP connection always disable re-use"); return result; @@ -1063,7 +1063,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp) free(ludp->lud_filter); if(ludp->lud_attrs) { - size_t i; + size_t i; for(i = 0; i < ludp->lud_attrs_dups; i++) free(ludp->lud_attrs[i]); free(ludp->lud_attrs); diff --git a/contrib/libs/curl/lib/md4.c b/contrib/libs/curl/lib/md4.c index c5b2acca89..d3355ad929 100644 --- a/contrib/libs/curl/lib/md4.c +++ b/contrib/libs/curl/lib/md4.c @@ -1,233 +1,233 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_CRYPTO_AUTH) - -#include "curl_md4.h" -#include "warnless.h" - -#ifdef USE_OPENSSL -#include <openssl/opensslconf.h> + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_CRYPTO_AUTH) + +#include "curl_md4.h" +#include "warnless.h" + +#ifdef USE_OPENSSL +#include <openssl/opensslconf.h> #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) /* OpenSSL 3.0.0 marks the MD4 functions as deprecated */ #define OPENSSL_NO_MD4 -#endif +#endif #endif /* USE_OPENSSL */ -#ifdef USE_MBEDTLS -#error #include <mbedtls/config.h> +#ifdef USE_MBEDTLS +#error #include <mbedtls/config.h> #error #include <mbedtls/version.h> #if(MBEDTLS_VERSION_NUMBER >= 0x02070000) #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS -#endif +#endif #endif /* USE_MBEDTLS */ - -#if defined(USE_GNUTLS_NETTLE) - -#include <nettle/md4.h> - -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -typedef struct md4_ctx MD4_CTX; - -static void MD4_Init(MD4_CTX *ctx) -{ - md4_init(ctx); -} - -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) -{ - md4_update(ctx, size, data); -} - -static void MD4_Final(unsigned char *result, MD4_CTX *ctx) -{ - md4_digest(ctx, MD4_DIGEST_SIZE, result); -} - -#elif defined(USE_GNUTLS) - -#include <gcrypt.h> - -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - + +#if defined(USE_GNUTLS_NETTLE) + +#include <nettle/md4.h> + +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +typedef struct md4_ctx MD4_CTX; + +static void MD4_Init(MD4_CTX *ctx) +{ + md4_init(ctx); +} + +static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) +{ + md4_update(ctx, size, data); +} + +static void MD4_Final(unsigned char *result, MD4_CTX *ctx) +{ + md4_digest(ctx, MD4_DIGEST_SIZE, result); +} + +#elif defined(USE_GNUTLS) + +#include <gcrypt.h> + +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + typedef gcry_md_hd_t MD4_CTX; - -static void MD4_Init(MD4_CTX *ctx) -{ - gcry_md_open(ctx, GCRY_MD_MD4, 0); -} - -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) -{ - gcry_md_write(*ctx, data, size); -} - -static void MD4_Final(unsigned char *result, MD4_CTX *ctx) -{ + +static void MD4_Init(MD4_CTX *ctx) +{ + gcry_md_open(ctx, GCRY_MD_MD4, 0); +} + +static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) +{ + gcry_md_write(*ctx, data, size); +} + +static void MD4_Final(unsigned char *result, MD4_CTX *ctx) +{ memcpy(result, gcry_md_read(*ctx, 0), MD4_DIGEST_LENGTH); gcry_md_close(*ctx); -} - -#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4) -/* When OpenSSL is available we use the MD4-functions from OpenSSL */ -#include <openssl/md4.h> - +} + +#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4) +/* When OpenSSL is available we use the MD4-functions from OpenSSL */ +#include <openssl/md4.h> + #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \ defined(__MAC_OS_X_VERSION_MIN_ALLOWED) && \ (__MAC_OS_X_VERSION_MIN_ALLOWED < 101500)) || \ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000)) - -#include <CommonCrypto/CommonDigest.h> - -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - + +#include <CommonCrypto/CommonDigest.h> + +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + typedef CC_MD4_CTX MD4_CTX; - -static void MD4_Init(MD4_CTX *ctx) -{ + +static void MD4_Init(MD4_CTX *ctx) +{ (void)CC_MD4_Init(ctx); -} - -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) -{ +} + +static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) +{ (void)CC_MD4_Update(ctx, data, (CC_LONG)size); -} - -static void MD4_Final(unsigned char *result, MD4_CTX *ctx) -{ +} + +static void MD4_Final(unsigned char *result, MD4_CTX *ctx) +{ (void)CC_MD4_Final(result, ctx); -} - -#elif defined(USE_WIN32_CRYPTO) - -#include <wincrypt.h> - -#include "curl_memory.h" +} + +#elif defined(USE_WIN32_CRYPTO) + +#include <wincrypt.h> + +#include "curl_memory.h" /* The last #include file should be: */ -#include "memdebug.h" - +#include "memdebug.h" + struct md4_ctx { - HCRYPTPROV hCryptProv; - HCRYPTHASH hHash; + HCRYPTPROV hCryptProv; + HCRYPTHASH hHash; }; typedef struct md4_ctx MD4_CTX; - -static void MD4_Init(MD4_CTX *ctx) -{ - ctx->hCryptProv = 0; - ctx->hHash = 0; - - if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL, + +static void MD4_Init(MD4_CTX *ctx) +{ + ctx->hCryptProv = 0; + ctx->hHash = 0; + + if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { - CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash); - } -} - -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) -{ + CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash); + } +} + +static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) +{ CryptHashData(ctx->hHash, (BYTE *)data, (unsigned int) size, 0); -} - -static void MD4_Final(unsigned char *result, MD4_CTX *ctx) -{ - unsigned long length = 0; - - CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); - if(length == MD4_DIGEST_LENGTH) - CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0); - - if(ctx->hHash) - CryptDestroyHash(ctx->hHash); - - if(ctx->hCryptProv) - CryptReleaseContext(ctx->hCryptProv, 0); -} - -#elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C)) - -#error #include <mbedtls/md4.h> - -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - +} + +static void MD4_Final(unsigned char *result, MD4_CTX *ctx) +{ + unsigned long length = 0; + + CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); + if(length == MD4_DIGEST_LENGTH) + CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0); + + if(ctx->hHash) + CryptDestroyHash(ctx->hHash); + + if(ctx->hCryptProv) + CryptReleaseContext(ctx->hCryptProv, 0); +} + +#elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C)) + +#error #include <mbedtls/md4.h> + +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + struct md4_ctx { - void *data; - unsigned long size; + void *data; + unsigned long size; }; typedef struct md4_ctx MD4_CTX; - -static void MD4_Init(MD4_CTX *ctx) -{ - ctx->data = NULL; - ctx->size = 0; -} - -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) -{ - if(ctx->data == NULL) { - ctx->data = malloc(size); - if(ctx->data != NULL) { - memcpy(ctx->data, data, size); - ctx->size = size; - } - } -} - -static void MD4_Final(unsigned char *result, MD4_CTX *ctx) -{ - if(ctx->data != NULL) { + +static void MD4_Init(MD4_CTX *ctx) +{ + ctx->data = NULL; + ctx->size = 0; +} + +static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) +{ + if(ctx->data == NULL) { + ctx->data = malloc(size); + if(ctx->data != NULL) { + memcpy(ctx->data, data, size); + ctx->size = size; + } + } +} + +static void MD4_Final(unsigned char *result, MD4_CTX *ctx) +{ + if(ctx->data != NULL) { #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) - mbedtls_md4(ctx->data, ctx->size, result); + mbedtls_md4(ctx->data, ctx->size, result); #else (void) mbedtls_md4_ret(ctx->data, ctx->size, result); #endif - - Curl_safefree(ctx->data); - ctx->size = 0; - } -} - -#else -/* When no other crypto library is available, or the crypto library doesn't - * support MD4, we use this code segment this implementation of it - * + + Curl_safefree(ctx->data); + ctx->size = 0; + } +} + +#else +/* When no other crypto library is available, or the crypto library doesn't + * support MD4, we use this code segment this implementation of it + * * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. * MD4 Message-Digest Algorithm (RFC 1320). * @@ -340,8 +340,8 @@ static const void *body(MD4_CTX *ctx, const void *data, unsigned long size) d = ctx->d; do { - MD4_u32plus saved_a, saved_b, saved_c, saved_d; - + MD4_u32plus saved_a, saved_b, saved_c, saved_d; + saved_a = a; saved_b = b; saved_c = c; @@ -349,59 +349,59 @@ static const void *body(MD4_CTX *ctx, const void *data, unsigned long size) /* Round 1 */ STEP(F, a, b, c, d, SET(0), 3) - STEP(F, d, a, b, c, SET(1), 7) - STEP(F, c, d, a, b, SET(2), 11) - STEP(F, b, c, d, a, SET(3), 19) - STEP(F, a, b, c, d, SET(4), 3) - STEP(F, d, a, b, c, SET(5), 7) - STEP(F, c, d, a, b, SET(6), 11) - STEP(F, b, c, d, a, SET(7), 19) - STEP(F, a, b, c, d, SET(8), 3) - STEP(F, d, a, b, c, SET(9), 7) - STEP(F, c, d, a, b, SET(10), 11) - STEP(F, b, c, d, a, SET(11), 19) - STEP(F, a, b, c, d, SET(12), 3) - STEP(F, d, a, b, c, SET(13), 7) - STEP(F, c, d, a, b, SET(14), 11) - STEP(F, b, c, d, a, SET(15), 19) + STEP(F, d, a, b, c, SET(1), 7) + STEP(F, c, d, a, b, SET(2), 11) + STEP(F, b, c, d, a, SET(3), 19) + STEP(F, a, b, c, d, SET(4), 3) + STEP(F, d, a, b, c, SET(5), 7) + STEP(F, c, d, a, b, SET(6), 11) + STEP(F, b, c, d, a, SET(7), 19) + STEP(F, a, b, c, d, SET(8), 3) + STEP(F, d, a, b, c, SET(9), 7) + STEP(F, c, d, a, b, SET(10), 11) + STEP(F, b, c, d, a, SET(11), 19) + STEP(F, a, b, c, d, SET(12), 3) + STEP(F, d, a, b, c, SET(13), 7) + STEP(F, c, d, a, b, SET(14), 11) + STEP(F, b, c, d, a, SET(15), 19) /* Round 2 */ - STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3) - STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5) - STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9) - STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13) - STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3) - STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5) - STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9) - STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13) - STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3) - STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5) - STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9) - STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13) - STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3) - STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5) - STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9) - STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13) /* Round 3 */ - STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3) - STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9) - STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11) - STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15) - STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3) - STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9) - STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11) - STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15) - STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3) - STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9) - STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11) - STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15) - STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3) - STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9) - STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11) - STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15) - - a += saved_a; + STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15) + + a += saved_a; b += saved_b; c += saved_c; d += saved_d; @@ -431,7 +431,7 @@ static void MD4_Init(MD4_CTX *ctx) static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) { MD4_u32plus saved_lo; - unsigned long used; + unsigned long used; saved_lo = ctx->lo; ctx->lo = (saved_lo + size) & 0x1fffffff; @@ -442,7 +442,7 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) used = saved_lo & 0x3f; if(used) { - unsigned long available = 64 - used; + unsigned long available = 64 - used; if(size < available) { memcpy(&ctx->buffer[used], data, size); @@ -514,7 +514,7 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx) memset(ctx, 0, sizeof(*ctx)); } -#endif /* CRYPTO LIBS */ +#endif /* CRYPTO LIBS */ void Curl_md4it(unsigned char *output, const unsigned char *input, const size_t len) @@ -525,5 +525,5 @@ void Curl_md4it(unsigned char *output, const unsigned char *input, MD4_Update(&ctx, input, curlx_uztoui(len)); MD4_Final(output, &ctx); } - -#endif /* CURL_DISABLE_CRYPTO_AUTH */ + +#endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/contrib/libs/curl/lib/md5.c b/contrib/libs/curl/lib/md5.c index 1decfdf95e..ff0b369f02 100644 --- a/contrib/libs/curl/lib/md5.c +++ b/contrib/libs/curl/lib/md5.c @@ -47,12 +47,12 @@ typedef struct md5_ctx MD5_CTX; -static void MD5_Init(MD5_CTX *ctx) +static void MD5_Init(MD5_CTX *ctx) { md5_init(ctx); } -static void MD5_Update(MD5_CTX *ctx, +static void MD5_Update(MD5_CTX *ctx, const unsigned char *input, unsigned int inputLen) { @@ -73,12 +73,12 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx) typedef gcry_md_hd_t MD5_CTX; -static void MD5_Init(MD5_CTX *ctx) +static void MD5_Init(MD5_CTX *ctx) { gcry_md_open(ctx, GCRY_MD_MD5, 0); } -static void MD5_Update(MD5_CTX *ctx, +static void MD5_Update(MD5_CTX *ctx, const unsigned char *input, unsigned int inputLen) { @@ -91,7 +91,7 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx) gcry_md_close(*ctx); } -#elif defined(USE_OPENSSL) && !defined(USE_AMISSL) +#elif defined(USE_OPENSSL) && !defined(USE_AMISSL) /* When OpenSSL is available we use the MD5-function from OpenSSL */ #include <openssl/md5.h> #include "curl_memory.h" @@ -338,8 +338,8 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) d = ctx->d; do { - MD5_u32plus saved_a, saved_b, saved_c, saved_d; - + MD5_u32plus saved_a, saved_b, saved_c, saved_d; + saved_a = a; saved_b = b; saved_c = c; @@ -347,77 +347,77 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) /* Round 1 */ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) - STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) - STEP(F, c, d, a, b, SET(2), 0x242070db, 17) - STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) - STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) - STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) - STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) - STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) - STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) - STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) - STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) - STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) - STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) - STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) - STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) - STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) /* Round 2 */ - STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) - STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) - STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) - STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) - STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) - STEP(G, d, a, b, c, GET(10), 0x02441453, 9) - STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) - STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) - STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) - STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) - STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) - STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) - STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) - STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) - STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) - STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) /* Round 3 */ - STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) - STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) - STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) - STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) - STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) - STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) - STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) - STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) - STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) - STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) - STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) - STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) - STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) - STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) - STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) - STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) /* Round 4 */ - STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) - STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) - STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) - STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) - STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) - STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) - STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) - STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) - STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) - STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) - STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) - STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) - STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) - STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) - STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) - STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) - - a += saved_a; + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; b += saved_b; c += saved_c; d += saved_d; @@ -447,7 +447,7 @@ static void MD5_Init(MD5_CTX *ctx) static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) { MD5_u32plus saved_lo; - unsigned long used; + unsigned long used; saved_lo = ctx->lo; ctx->lo = (saved_lo + size) & 0x1fffffff; @@ -458,7 +458,7 @@ static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) used = saved_lo & 0x3f; if(used) { - unsigned long available = 64 - used; + unsigned long available = 64 - used; if(size < available) { memcpy(&ctx->buffer[used], data, size); @@ -602,12 +602,12 @@ struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params) } CURLcode Curl_MD5_update(struct MD5_context *context, - const unsigned char *data, - unsigned int len) + const unsigned char *data, + unsigned int len) { (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len); - return CURLE_OK; + return CURLE_OK; } CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result) @@ -617,7 +617,7 @@ CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result) free(context->md5_hashctx); free(context); - return CURLE_OK; + return CURLE_OK; } #endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/contrib/libs/curl/lib/memdebug.c b/contrib/libs/curl/lib/memdebug.c index 53c5e2706d..881ee85c32 100644 --- a/contrib/libs/curl/lib/memdebug.c +++ b/contrib/libs/curl/lib/memdebug.c @@ -54,29 +54,29 @@ struct memdebug { * Don't use these with multithreaded test programs! */ -FILE *curl_dbg_logfile = NULL; +FILE *curl_dbg_logfile = NULL; static bool memlimit = FALSE; /* enable memory limit */ static long memsize = 0; /* set number of mallocs allowed */ /* this sets the log file name */ -void curl_dbg_memdebug(const char *logname) +void curl_dbg_memdebug(const char *logname) { - if(!curl_dbg_logfile) { + if(!curl_dbg_logfile) { if(logname && *logname) - curl_dbg_logfile = fopen(logname, FOPEN_WRITETEXT); + curl_dbg_logfile = fopen(logname, FOPEN_WRITETEXT); else - curl_dbg_logfile = stderr; + curl_dbg_logfile = stderr; #ifdef MEMDEBUG_LOG_SYNC /* Flush the log file after every line so the log isn't lost in a crash */ - if(curl_dbg_logfile) - setbuf(curl_dbg_logfile, (char *)NULL); + if(curl_dbg_logfile) + setbuf(curl_dbg_logfile, (char *)NULL); #endif } } /* This function sets the number of malloc() calls that should return successfully! */ -void curl_dbg_memlimit(long limit) +void curl_dbg_memlimit(long limit) { if(!memlimit) { memlimit = TRUE; @@ -93,12 +93,12 @@ static bool countcheck(const char *func, int line, const char *source) if(!memsize) { if(source) { /* log to file */ - curl_dbg_log("LIMIT %s:%d %s reached memlimit\n", - source, line, func); + curl_dbg_log("LIMIT %s:%d %s reached memlimit\n", + source, line, func); /* log to stderr also */ fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", source, line, func); - fflush(curl_dbg_logfile); /* because it might crash now */ + fflush(curl_dbg_logfile); /* because it might crash now */ } errno = ENOMEM; return TRUE; /* RETURN ERROR! */ @@ -112,7 +112,7 @@ static bool countcheck(const char *func, int line, const char *source) return FALSE; /* allow this */ } -void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) +void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) { struct memdebug *mem; size_t size; @@ -131,15 +131,15 @@ void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) } if(source) - curl_dbg_log("MEM %s:%d malloc(%zu) = %p\n", - source, line, wantedsize, - mem ? (void *)mem->mem : (void *)0); + curl_dbg_log("MEM %s:%d malloc(%zu) = %p\n", + source, line, wantedsize, + mem ? (void *)mem->mem : (void *)0); return (mem ? mem->mem : NULL); } -void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, - int line, const char *source) +void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, + int line, const char *source) { struct memdebug *mem; size_t size, user_size; @@ -159,14 +159,14 @@ void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, mem->size = user_size; if(source) - curl_dbg_log("MEM %s:%d calloc(%zu,%zu) = %p\n", - source, line, wanted_elements, wanted_size, - mem ? (void *)mem->mem : (void *)0); + curl_dbg_log("MEM %s:%d calloc(%zu,%zu) = %p\n", + source, line, wanted_elements, wanted_size, + mem ? (void *)mem->mem : (void *)0); return (mem ? mem->mem : NULL); } -char *curl_dbg_strdup(const char *str, int line, const char *source) +char *curl_dbg_strdup(const char *str, int line, const char *source) { char *mem; size_t len; @@ -178,19 +178,19 @@ char *curl_dbg_strdup(const char *str, int line, const char *source) len = strlen(str) + 1; - mem = curl_dbg_malloc(len, 0, NULL); /* NULL prevents logging */ + mem = curl_dbg_malloc(len, 0, NULL); /* NULL prevents logging */ if(mem) memcpy(mem, str, len); if(source) - curl_dbg_log("MEM %s:%d strdup(%p) (%zu) = %p\n", - source, line, (const void *)str, len, (const void *)mem); + curl_dbg_log("MEM %s:%d strdup(%p) (%zu) = %p\n", + source, line, (const void *)str, len, (const void *)mem); return mem; } #if defined(WIN32) && defined(UNICODE) -wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) +wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) { wchar_t *mem; size_t wsiz, bsiz; @@ -203,12 +203,12 @@ wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) wsiz = wcslen(str) + 1; bsiz = wsiz * sizeof(wchar_t); - mem = curl_dbg_malloc(bsiz, 0, NULL); /* NULL prevents logging */ + mem = curl_dbg_malloc(bsiz, 0, NULL); /* NULL prevents logging */ if(mem) memcpy(mem, str, bsiz); if(source) - curl_dbg_log("MEM %s:%d wcsdup(%p) (%zu) = %p\n", + curl_dbg_log("MEM %s:%d wcsdup(%p) (%zu) = %p\n", source, line, (void *)str, bsiz, (void *)mem); return mem; @@ -217,8 +217,8 @@ wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) /* We provide a realloc() that accepts a NULL as pointer, which then performs a malloc(). In order to work with ares. */ -void *curl_dbg_realloc(void *ptr, size_t wantedsize, - int line, const char *source) +void *curl_dbg_realloc(void *ptr, size_t wantedsize, + int line, const char *source) { struct memdebug *mem = NULL; @@ -244,7 +244,7 @@ void *curl_dbg_realloc(void *ptr, size_t wantedsize, mem = (Curl_crealloc)(mem, size); if(source) - curl_dbg_log("MEM %s:%d realloc(%p, %zu) = %p\n", + curl_dbg_log("MEM %s:%d realloc(%p, %zu) = %p\n", source, line, (void *)ptr, wantedsize, mem ? (void *)mem->mem : (void *)0); @@ -256,10 +256,10 @@ void *curl_dbg_realloc(void *ptr, size_t wantedsize, return NULL; } -void curl_dbg_free(void *ptr, int line, const char *source) +void curl_dbg_free(void *ptr, int line, const char *source) { if(ptr) { - struct memdebug *mem; + struct memdebug *mem; #ifdef __INTEL_COMPILER # pragma warning(push) @@ -278,11 +278,11 @@ void curl_dbg_free(void *ptr, int line, const char *source) } if(source && ptr) - curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr); + curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr); } -curl_socket_t curl_dbg_socket(int domain, int type, int protocol, - int line, const char *source) +curl_socket_t curl_dbg_socket(int domain, int type, int protocol, + int line, const char *source) { const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? "FD %s:%d socket() = %d\n" : @@ -298,44 +298,44 @@ curl_socket_t curl_dbg_socket(int domain, int type, int protocol, sockfd = socket(domain, type, protocol); if(source && (sockfd != CURL_SOCKET_BAD)) - curl_dbg_log(fmt, source, line, sockfd); + curl_dbg_log(fmt, source, line, sockfd); return sockfd; } -SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, - SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, - SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line, - const char *source) +SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, + SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, + SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line, + const char *source) { SEND_TYPE_RETV rc; if(countcheck("send", line, source)) return -1; rc = send(sockfd, buf, len, flags); if(source) - curl_dbg_log("SEND %s:%d send(%lu) = %ld\n", + curl_dbg_log("SEND %s:%d send(%lu) = %ld\n", source, line, (unsigned long)len, (long)rc); return rc; } -RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf, - RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line, - const char *source) +RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf, + RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line, + const char *source) { RECV_TYPE_RETV rc; if(countcheck("recv", line, source)) return -1; rc = recv(sockfd, buf, len, flags); if(source) - curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n", + curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n", source, line, (unsigned long)len, (long)rc); return rc; } #ifdef HAVE_SOCKETPAIR -int curl_dbg_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source) +int curl_dbg_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line, const char *source) { const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? "FD %s:%d socketpair() = %d %d\n" : @@ -346,14 +346,14 @@ int curl_dbg_socketpair(int domain, int type, int protocol, int res = socketpair(domain, type, protocol, socket_vector); if(source && (0 == res)) - curl_dbg_log(fmt, source, line, socket_vector[0], socket_vector[1]); + curl_dbg_log(fmt, source, line, socket_vector[0], socket_vector[1]); return res; } #endif -curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, - int line, const char *source) +curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, + int line, const char *source) { const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? "FD %s:%d accept() = %d\n" : @@ -367,13 +367,13 @@ curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, curl_socket_t sockfd = accept(s, addr, addrlen); if(source && (sockfd != CURL_SOCKET_BAD)) - curl_dbg_log(fmt, source, line, sockfd); + curl_dbg_log(fmt, source, line, sockfd); return sockfd; } /* separate function to allow libcurl to mark a "faked" close */ -void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) +void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) { const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? "FD %s:%d sclose(%d)\n": @@ -382,24 +382,24 @@ void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) "FD %s:%d sclose(%zd)\n"; if(source) - curl_dbg_log(fmt, source, line, sockfd); + curl_dbg_log(fmt, source, line, sockfd); } /* this is our own defined way to close sockets on *ALL* platforms */ -int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source) +int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source) { int res = sclose(sockfd); - curl_dbg_mark_sclose(sockfd, line, source); + curl_dbg_mark_sclose(sockfd, line, source); return res; } -FILE *curl_dbg_fopen(const char *file, const char *mode, - int line, const char *source) +FILE *curl_dbg_fopen(const char *file, const char *mode, + int line, const char *source) { FILE *res = fopen(file, mode); if(source) - curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", + curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", source, line, file, mode, (void *)res); return res; @@ -415,16 +415,16 @@ FILE *curl_dbg_fdopen(int filedes, const char *mode, return res; } -int curl_dbg_fclose(FILE *file, int line, const char *source) +int curl_dbg_fclose(FILE *file, int line, const char *source) { int res; DEBUGASSERT(file != NULL); - if(source) - curl_dbg_log("FILE %s:%d fclose(%p)\n", - source, line, (void *)file); - + if(source) + curl_dbg_log("FILE %s:%d fclose(%p)\n", + source, line, (void *)file); + res = fclose(file); return res; @@ -433,13 +433,13 @@ int curl_dbg_fclose(FILE *file, int line, const char *source) #define LOGLINE_BUFSIZE 1024 /* this does the writing to the memory tracking log file */ -void curl_dbg_log(const char *format, ...) +void curl_dbg_log(const char *format, ...) { char *buf; int nchars; va_list ap; - if(!curl_dbg_logfile) + if(!curl_dbg_logfile) return; buf = (Curl_cmalloc)(LOGLINE_BUFSIZE); @@ -454,7 +454,7 @@ void curl_dbg_log(const char *format, ...) nchars = LOGLINE_BUFSIZE - 1; if(nchars > 0) - fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile); + fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile); (Curl_cfree)(buf); } diff --git a/contrib/libs/curl/lib/memdebug.h b/contrib/libs/curl/lib/memdebug.h index c108872915..8e88cea580 100644 --- a/contrib/libs/curl/lib/memdebug.h +++ b/contrib/libs/curl/lib/memdebug.h @@ -30,95 +30,95 @@ #define CURL_MT_LOGFNAME_BUFSIZE 512 -extern FILE *curl_dbg_logfile; +extern FILE *curl_dbg_logfile; /* memory functions */ -CURL_EXTERN void *curl_dbg_malloc(size_t size, int line, const char *source); -CURL_EXTERN void *curl_dbg_calloc(size_t elements, size_t size, int line, - const char *source); -CURL_EXTERN void *curl_dbg_realloc(void *ptr, size_t size, int line, - const char *source); -CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source); -CURL_EXTERN char *curl_dbg_strdup(const char *str, int line, const char *src); +CURL_EXTERN void *curl_dbg_malloc(size_t size, int line, const char *source); +CURL_EXTERN void *curl_dbg_calloc(size_t elements, size_t size, int line, + const char *source); +CURL_EXTERN void *curl_dbg_realloc(void *ptr, size_t size, int line, + const char *source); +CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source); +CURL_EXTERN char *curl_dbg_strdup(const char *str, int line, const char *src); #if defined(WIN32) && defined(UNICODE) -CURL_EXTERN wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, - const char *source); +CURL_EXTERN wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, + const char *source); #endif -CURL_EXTERN void curl_dbg_memdebug(const char *logname); -CURL_EXTERN void curl_dbg_memlimit(long limit); -CURL_EXTERN void curl_dbg_log(const char *format, ...); +CURL_EXTERN void curl_dbg_memdebug(const char *logname); +CURL_EXTERN void curl_dbg_memlimit(long limit); +CURL_EXTERN void curl_dbg_log(const char *format, ...); /* file descriptor manipulators */ -CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol, - int line, const char *source); -CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd, +CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol, + int line, const char *source); +CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source); -CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen, - int line, const char *source); +CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd, + int line, const char *source); +CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen, + int line, const char *source); #ifdef HAVE_SOCKETPAIR -CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source); +CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line, const char *source); #endif /* send/receive sockets */ -CURL_EXTERN SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, - SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, - SEND_TYPE_ARG3 len, - SEND_TYPE_ARG4 flags, int line, - const char *source); -CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, - RECV_TYPE_ARG2 buf, - RECV_TYPE_ARG3 len, - RECV_TYPE_ARG4 flags, int line, - const char *source); +CURL_EXTERN SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, + SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, + SEND_TYPE_ARG3 len, + SEND_TYPE_ARG4 flags, int line, + const char *source); +CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, + RECV_TYPE_ARG2 buf, + RECV_TYPE_ARG3 len, + RECV_TYPE_ARG4 flags, int line, + const char *source); /* FILE functions */ -CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line, - const char *source); +CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line, + const char *source); CURL_EXTERN FILE *curl_dbg_fdopen(int filedes, const char *mode, int line, const char *source); -CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); +CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); #ifndef MEMDEBUG_NODEFINES /* Set this symbol on the command-line, recompile all lib-sources */ #undef strdup -#define strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) -#define malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__) -#define calloc(nbelem,size) curl_dbg_calloc(nbelem, size, __LINE__, __FILE__) -#define realloc(ptr,size) curl_dbg_realloc(ptr, size, __LINE__, __FILE__) -#define free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__) -#define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__) -#define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__) +#define strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) +#define malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__) +#define calloc(nbelem,size) curl_dbg_calloc(nbelem, size, __LINE__, __FILE__) +#define realloc(ptr,size) curl_dbg_realloc(ptr, size, __LINE__, __FILE__) +#define free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__) +#define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__) +#define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__) #ifdef WIN32 # ifdef UNICODE # undef wcsdup -# define wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) +# define wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) # undef _wcsdup -# define _wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) +# define _wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) # undef _tcsdup -# define _tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) +# define _tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) # else # undef _tcsdup -# define _tcsdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) +# define _tcsdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) # endif #endif #undef socket #define socket(domain,type,protocol)\ - curl_dbg_socket(domain, type, protocol, __LINE__, __FILE__) + curl_dbg_socket(domain, type, protocol, __LINE__, __FILE__) #undef accept /* for those with accept as a macro */ #define accept(sock,addr,len)\ - curl_dbg_accept(sock, addr, len, __LINE__, __FILE__) + curl_dbg_accept(sock, addr, len, __LINE__, __FILE__) #ifdef HAVE_SOCKETPAIR #define socketpair(domain,type,protocol,socket_vector)\ - curl_dbg_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__) + curl_dbg_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__) #endif #ifdef HAVE_GETADDRINFO @@ -127,31 +127,31 @@ CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); our macro as for other platforms. Instead, we redefine the new name they define getaddrinfo to become! */ #define ogetaddrinfo(host,serv,hint,res) \ - curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) + curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) #else #undef getaddrinfo #define getaddrinfo(host,serv,hint,res) \ - curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) + curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) #endif #endif /* HAVE_GETADDRINFO */ #ifdef HAVE_FREEADDRINFO #undef freeaddrinfo #define freeaddrinfo(data) \ - curl_dbg_freeaddrinfo(data, __LINE__, __FILE__) + curl_dbg_freeaddrinfo(data, __LINE__, __FILE__) #endif /* HAVE_FREEADDRINFO */ /* sclose is probably already defined, redefine it! */ #undef sclose -#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__) +#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__) -#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__) +#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__) #undef fopen -#define fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__) +#define fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__) #undef fdopen -#define fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__) -#define fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__) +#define fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__) +#define fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__) #endif /* MEMDEBUG_NODEFINES */ diff --git a/contrib/libs/curl/lib/mime.c b/contrib/libs/curl/lib/mime.c index 6cea5aa47d..2ddd9b8b98 100644 --- a/contrib/libs/curl/lib/mime.c +++ b/contrib/libs/curl/lib/mime.c @@ -30,8 +30,8 @@ #include "urldata.h" #include "sendf.h" -#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ - !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) +#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ + !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include <libgen.h> @@ -911,10 +911,10 @@ static size_t readback_part(curl_mimepart *part, struct curl_slist *hdr = (struct curl_slist *) part->state.ptr; switch(part->state.state) { case MIMESTATE_BEGIN: - mimesetstate(&part->state, - (part->flags & MIME_BODY_ONLY)? - MIMESTATE_BODY: MIMESTATE_CURLHEADERS, - part->curlheaders); + mimesetstate(&part->state, + (part->flags & MIME_BODY_ONLY)? + MIMESTATE_BODY: MIMESTATE_CURLHEADERS, + part->curlheaders); break; case MIMESTATE_USERHEADERS: if(!hdr) { @@ -1316,7 +1316,7 @@ curl_mime *curl_mime_init(struct Curl_easy *easy) mime->lastpart = NULL; memset(mime->boundary, '-', 24); - if(Curl_rand_hex(easy, (unsigned char *) &mime->boundary[24], + if(Curl_rand_hex(easy, (unsigned char *) &mime->boundary[24], MIME_RAND_BOUNDARY_CHARS + 1)) { /* failed to get random separator, bail out */ free(mime); @@ -2056,4 +2056,4 @@ CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) return CURLE_NOT_BUILT_IN; } -#endif /* if disabled */ +#endif /* if disabled */ diff --git a/contrib/libs/curl/lib/mime.h b/contrib/libs/curl/lib/mime.h index 90a14e615a..ab89d52517 100644 --- a/contrib/libs/curl/lib/mime.h +++ b/contrib/libs/curl/lib/mime.h @@ -22,8 +22,8 @@ * ***************************************************************************/ -#include "curl_setup.h" - +#include "curl_setup.h" + #define MIME_RAND_BOUNDARY_CHARS 16 /* Nb. of random boundary chars. */ #define MAX_ENCODED_LINE_LENGTH 76 /* Maximum encoded line length. */ #define ENCODING_BUFFER_SIZE 256 /* Encoding temp buffers size. */ @@ -72,7 +72,7 @@ enum mimestrategy { struct mime_encoder { const char * name; /* Encoding name. */ size_t (*encodefunc)(char *buffer, size_t size, bool ateof, - curl_mimepart *part); /* Encoded read. */ + curl_mimepart *part); /* Encoded read. */ curl_off_t (*sizefunc)(curl_mimepart *part); /* Encoded size. */ }; @@ -91,16 +91,16 @@ struct mime_state { curl_off_t offset; /* State-dependent offset. */ }; -/* minimum buffer size for the boundary string */ -#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1) - +/* minimum buffer size for the boundary string */ +#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1) + /* A mime multipart. */ struct curl_mime { struct Curl_easy *easy; /* The associated easy handle. */ curl_mimepart *parent; /* Parent part. */ curl_mimepart *firstpart; /* First part. */ curl_mimepart *lastpart; /* Last part. */ - char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */ + char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */ struct mime_state state; /* Current readback state. */ }; @@ -132,7 +132,7 @@ struct curl_mimepart { CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...); #if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ - !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) + !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) /* Prototypes. */ void Curl_mime_initpart(struct curl_mimepart *part, struct Curl_easy *easy); @@ -153,18 +153,18 @@ CURLcode Curl_mime_rewind(struct curl_mimepart *part); const char *Curl_mime_contenttype(const char *filename); void Curl_mime_unpause(struct curl_mimepart *part); -#else -/* if disabled */ -#define Curl_mime_initpart(x,y) -#define Curl_mime_cleanpart(x) -#define Curl_mime_duppart(x,y) CURLE_OK /* Nothing to duplicate. Succeed */ -#define Curl_mime_set_subparts(a,b,c) CURLE_NOT_BUILT_IN -#define Curl_mime_prepare_headers(a,b,c,d) CURLE_NOT_BUILT_IN -#define Curl_mime_size(x) (curl_off_t) -1 -#define Curl_mime_read NULL -#define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN) +#else +/* if disabled */ +#define Curl_mime_initpart(x,y) +#define Curl_mime_cleanpart(x) +#define Curl_mime_duppart(x,y) CURLE_OK /* Nothing to duplicate. Succeed */ +#define Curl_mime_set_subparts(a,b,c) CURLE_NOT_BUILT_IN +#define Curl_mime_prepare_headers(a,b,c,d) CURLE_NOT_BUILT_IN +#define Curl_mime_size(x) (curl_off_t) -1 +#define Curl_mime_read NULL +#define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN) #define Curl_mime_unpause(x) -#endif - - +#endif + + #endif /* HEADER_CURL_MIME_H */ diff --git a/contrib/libs/curl/lib/multi.c b/contrib/libs/curl/lib/multi.c index e01e18b33f..f1c9e4dbfb 100644 --- a/contrib/libs/curl/lib/multi.c +++ b/contrib/libs/curl/lib/multi.c @@ -158,8 +158,8 @@ static void mstate(struct Curl_easy *data, CURLMstate state data->mstate < CURLM_STATE_COMPLETED) { long connection_id = -5000; - if(data->conn) - connection_id = data->conn->connection_id; + if(data->conn) + connection_id = data->conn->connection_id; infof(data, "STATE: %s => %s handle %p; line %d (connection #%ld)\n", @@ -186,17 +186,17 @@ static void mstate(struct Curl_easy *data, CURLMstate state #endif /* - * We add one of these structs to the sockhash for each socket + * We add one of these structs to the sockhash for each socket */ struct Curl_sh_entry { struct Curl_hash transfers; /* hash of transfers using this socket */ - unsigned int action; /* what combined action READ/WRITE this socket waits - for */ + unsigned int action; /* what combined action READ/WRITE this socket waits + for */ void *socketp; /* settable by users with curl_multi_assign() */ - unsigned int users; /* number of transfers using this */ - unsigned int readers; /* this many transfers want to read */ - unsigned int writers; /* this many transfers want to write */ + unsigned int users; /* number of transfers using this */ + unsigned int readers; /* this many transfers want to read */ + unsigned int writers; /* this many transfers want to write */ }; /* bits for 'action' having no bits means this socket is not expecting any action */ @@ -207,58 +207,58 @@ struct Curl_sh_entry { static struct Curl_sh_entry *sh_getentry(struct Curl_hash *sh, curl_socket_t s) { - if(s != CURL_SOCKET_BAD) { + if(s != CURL_SOCKET_BAD) { /* only look for proper sockets */ return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t)); - } + } return NULL; } -#define TRHASH_SIZE 13 -static size_t trhash(void *key, size_t key_length, size_t slots_num) -{ - size_t keyval = (size_t)*(struct Curl_easy **)key; - (void) key_length; - - return (keyval % slots_num); -} - -static size_t trhash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) -{ - (void)k1_len; - (void)k2_len; - - return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2; -} - -static void trhash_dtor(void *nada) -{ - (void)nada; -} - - +#define TRHASH_SIZE 13 +static size_t trhash(void *key, size_t key_length, size_t slots_num) +{ + size_t keyval = (size_t)*(struct Curl_easy **)key; + (void) key_length; + + return (keyval % slots_num); +} + +static size_t trhash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) +{ + (void)k1_len; + (void)k2_len; + + return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2; +} + +static void trhash_dtor(void *nada) +{ + (void)nada; +} + + /* make sure this socket is present in the hash for this handle */ static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh, - curl_socket_t s) + curl_socket_t s) { struct Curl_sh_entry *there = sh_getentry(sh, s); struct Curl_sh_entry *check; - if(there) { + if(there) { /* it is present, return fine */ return there; - } + } /* not present, add it */ check = calloc(1, sizeof(struct Curl_sh_entry)); if(!check) return NULL; /* major failure */ - if(Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash, - trhash_compare, trhash_dtor)) { - free(check); - return NULL; - } + if(Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash, + trhash_compare, trhash_dtor)) { + free(check); + return NULL; + } /* make/add new hash entry */ if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) { @@ -272,11 +272,11 @@ static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh, /* delete the given socket + handle from the hash */ -static void sh_delentry(struct Curl_sh_entry *entry, +static void sh_delentry(struct Curl_sh_entry *entry, struct Curl_hash *sh, curl_socket_t s) { - Curl_hash_destroy(&entry->transfers); - + Curl_hash_destroy(&entry->transfers); + /* We remove the hash entry. This will end up in a call to sh_freeentry(). */ Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t)); @@ -364,8 +364,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ if(Curl_conncache_init(&multi->conn_cache, chashsize)) goto error; - Curl_llist_init(&multi->msglist, NULL); - Curl_llist_init(&multi->pending, NULL); + Curl_llist_init(&multi->msglist, NULL); + Curl_llist_init(&multi->pending, NULL); multi->multiplexing = TRUE; @@ -444,7 +444,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, /* for multi interface connections, we share DNS cache automatically if the easy handle's one is currently not set. */ - if(!data->dns.hostcache || + if(!data->dns.hostcache || (data->dns.hostcachetype == HCACHE_NONE)) { data->dns.hostcache = &multi->hostcache; data->dns.hostcachetype = HCACHE_MULTI; @@ -465,7 +465,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, data->psl = &multi->psl; #endif - /* We add the new entry last in the list. */ + /* We add the new entry last in the list. */ data->next = NULL; /* end of the line */ if(multi->easyp) { struct Curl_easy *last = multi->easylp; @@ -496,16 +496,16 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, /* increase the alive-counter */ multi->num_alive++; - /* A somewhat crude work-around for a little glitch in Curl_update_timer() - that happens if the lastcall time is set to the same time when the handle - is removed as when the next handle is added, as then the check in - Curl_update_timer() that prevents calling the application multiple times - with the same timer info will not trigger and then the new handle's - timeout will not be notified to the app. + /* A somewhat crude work-around for a little glitch in Curl_update_timer() + that happens if the lastcall time is set to the same time when the handle + is removed as when the next handle is added, as then the check in + Curl_update_timer() that prevents calling the application multiple times + with the same timer info will not trigger and then the new handle's + timeout will not be notified to the app. The work-around is thus simply to clear the 'lastcall' variable to force - Curl_update_timer() to always trigger a callback to the app when a new - easy handle is added */ + Curl_update_timer() to always trigger a callback to the app when a new + easy handle is added */ memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); CONNCACHE_LOCK(data); @@ -520,7 +520,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, data->set.no_signal; CONNCACHE_UNLOCK(data); - Curl_update_timer(multi); + Curl_update_timer(multi); return CURLM_OK; } @@ -540,13 +540,13 @@ static void debug_print_sock_hash(void *p) } #endif -static CURLcode multi_done(struct Curl_easy *data, - CURLcode status, /* an error if this is called - after an error was detected */ - bool premature) +static CURLcode multi_done(struct Curl_easy *data, + CURLcode status, /* an error if this is called + after an error was detected */ + bool premature) { CURLcode result; - struct connectdata *conn = data->conn; + struct connectdata *conn = data->conn; unsigned int i; DEBUGF(infof(data, "multi_done\n")); @@ -597,15 +597,15 @@ static CURLcode multi_done(struct Curl_easy *data, CONNCACHE_LOCK(data); Curl_detach_connnection(data); - if(CONN_INUSE(conn)) { + if(CONN_INUSE(conn)) { /* Stop if still used. */ /* conn->data must not remain pointing to this transfer since it is going away! Find another to own it! */ conn->data = conn->easyq.head->ptr; CONNCACHE_UNLOCK(data); - DEBUGF(infof(data, "Connection still in use %zu, " + DEBUGF(infof(data, "Connection still in use %zu, " "no more multi_done now!\n", - conn->easyq.size)); + conn->easyq.size)); return CURLE_OK; } conn->data = NULL; /* the connection now has no owner */ @@ -627,7 +627,7 @@ static CURLcode multi_done(struct Curl_easy *data, /* if data->set.reuse_forbid is TRUE, it means the libcurl client has forced us to close this connection. This is ignored for requests taking - place in a NTLM/NEGOTIATE authentication handshake + place in a NTLM/NEGOTIATE authentication handshake if conn->bits.close is TRUE, it means that the connection should be closed in spite of all our efforts to be nice, due to protocol @@ -642,13 +642,13 @@ static CURLcode multi_done(struct Curl_easy *data, if((data->set.reuse_forbid #if defined(USE_NTLM) - && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 || - conn->proxy_ntlm_state == NTLMSTATE_TYPE2) + && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 || + conn->proxy_ntlm_state == NTLMSTATE_TYPE2) +#endif +#if defined(USE_SPNEGO) + && !(conn->http_negotiate_state == GSS_AUTHRECV || + conn->proxy_negotiate_state == GSS_AUTHRECV) #endif -#if defined(USE_SPNEGO) - && !(conn->http_negotiate_state == GSS_AUTHRECV || - conn->proxy_negotiate_state == GSS_AUTHRECV) -#endif ) || conn->bits.close || (premature && !(conn->handler->flags & PROTOPT_STREAM))) { CURLcode res2; @@ -740,7 +740,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, return CURLM_RECURSIVE_API_CALL; premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE; - easy_owns_conn = (data->conn && (data->conn->data == easy)) ? + easy_owns_conn = (data->conn && (data->conn->data == easy)) ? TRUE : FALSE; /* If the 'state' is not INIT or COMPLETED, we might need to do something @@ -751,17 +751,17 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, multi->num_alive--; } - if(data->conn && + if(data->conn && data->mstate > CURLM_STATE_DO && data->mstate < CURLM_STATE_COMPLETED) { /* Set connection owner so that the DONE function closes it. We can safely do this here since connection is killed. */ - data->conn->data = easy; - streamclose(data->conn, "Removed with partial response"); + data->conn->data = easy; + streamclose(data->conn, "Removed with partial response"); easy_owns_conn = TRUE; } - if(data->conn) { + if(data->conn) { /* we must call multi_done() here (if we still own the connection) so that we don't leave a half-baked one around */ @@ -772,7 +772,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, Note that this ignores the return code simply because there's nothing really useful to do with it anyway! */ - (void)multi_done(data, data->result, premature); + (void)multi_done(data, data->result, premature); } } @@ -855,14 +855,14 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, We do not touch the easy handle here! */ multi->num_easy--; /* one less to care about now */ - Curl_update_timer(multi); + Curl_update_timer(multi); return CURLM_OK; } -/* Return TRUE if the application asked for multiplexing */ -bool Curl_multiplex_wanted(const struct Curl_multi *multi) +/* Return TRUE if the application asked for multiplexing */ +bool Curl_multiplex_wanted(const struct Curl_multi *multi) { - return (multi && (multi->multiplexing)); + return (multi && (multi->multiplexing)); } /* @@ -873,10 +873,10 @@ bool Curl_multiplex_wanted(const struct Curl_multi *multi) */ void Curl_detach_connnection(struct Curl_easy *data) { - struct connectdata *conn = data->conn; - if(conn) - Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); - data->conn = NULL; + struct connectdata *conn = data->conn; + if(conn) + Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); + data->conn = NULL; } /* @@ -884,18 +884,18 @@ void Curl_detach_connnection(struct Curl_easy *data) * * This is the only function that should assign data->conn */ -void Curl_attach_connnection(struct Curl_easy *data, - struct connectdata *conn) -{ - DEBUGASSERT(!data->conn); - DEBUGASSERT(conn); - data->conn = conn; - Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data, - &data->conn_queue); -} - +void Curl_attach_connnection(struct Curl_easy *data, + struct connectdata *conn) +{ + DEBUGASSERT(!data->conn); + DEBUGASSERT(conn); + data->conn = conn; + Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data, + &data->conn_queue); +} + static int waitconnect_getsock(struct connectdata *conn, - curl_socket_t *sock) + curl_socket_t *sock) { int i; int s = 0; @@ -904,7 +904,7 @@ static int waitconnect_getsock(struct connectdata *conn, #ifdef USE_SSL #ifndef CURL_DISABLE_PROXY if(CONNECT_FIRSTSOCKET_PROXY_SSL()) - return Curl_ssl_getsock(conn, sock); + return Curl_ssl_getsock(conn, sock); #endif #endif @@ -914,13 +914,13 @@ static int waitconnect_getsock(struct connectdata *conn, for(i = 0; i<2; i++) { if(conn->tempsock[i] != CURL_SOCKET_BAD) { sock[s] = conn->tempsock[i]; - rc |= GETSOCK_WRITESOCK(s); -#ifdef ENABLE_QUIC - if(conn->transport == TRNSPRT_QUIC) - /* when connecting QUIC, we want to read the socket too */ - rc |= GETSOCK_READSOCK(s); -#endif - s++; + rc |= GETSOCK_WRITESOCK(s); +#ifdef ENABLE_QUIC + if(conn->transport == TRNSPRT_QUIC) + /* when connecting QUIC, we want to read the socket too */ + rc |= GETSOCK_READSOCK(s); +#endif + s++; } } @@ -928,7 +928,7 @@ static int waitconnect_getsock(struct connectdata *conn, } static int waitproxyconnect_getsock(struct connectdata *conn, - curl_socket_t *sock) + curl_socket_t *sock) { sock[0] = conn->sock[FIRSTSOCKET]; @@ -941,48 +941,48 @@ static int waitproxyconnect_getsock(struct connectdata *conn, } static int domore_getsock(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { if(conn && conn->handler->domore_getsock) - return conn->handler->domore_getsock(conn, socks); + return conn->handler->domore_getsock(conn, socks); return GETSOCK_BLANK; } -static int doing_getsock(struct connectdata *conn, - curl_socket_t *socks) -{ - if(conn && conn->handler->doing_getsock) - return conn->handler->doing_getsock(conn, socks); - return GETSOCK_BLANK; -} - -static int protocol_getsock(struct connectdata *conn, - curl_socket_t *socks) -{ - if(conn->handler->proto_getsock) - return conn->handler->proto_getsock(conn, socks); - /* Backup getsock logic. Since there is a live socket in use, we must wait - for it or it will be removed from watching when the multi_socket API is - used. */ - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0); -} - -/* returns bitmapped flags for this handle and its sockets. The 'socks[]' - array contains MAX_SOCKSPEREASYHANDLE entries. */ +static int doing_getsock(struct connectdata *conn, + curl_socket_t *socks) +{ + if(conn && conn->handler->doing_getsock) + return conn->handler->doing_getsock(conn, socks); + return GETSOCK_BLANK; +} + +static int protocol_getsock(struct connectdata *conn, + curl_socket_t *socks) +{ + if(conn->handler->proto_getsock) + return conn->handler->proto_getsock(conn, socks); + /* Backup getsock logic. Since there is a live socket in use, we must wait + for it or it will be removed from watching when the multi_socket API is + used. */ + socks[0] = conn->sock[FIRSTSOCKET]; + return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0); +} + +/* returns bitmapped flags for this handle and its sockets. The 'socks[]' + array contains MAX_SOCKSPEREASYHANDLE entries. */ static int multi_getsock(struct Curl_easy *data, - curl_socket_t *socks) + curl_socket_t *socks) { /* The no connection case can happen when this is called from curl_multi_remove_handle() => singlesocket() => multi_getsock(). */ - if(!data->conn) + if(!data->conn) return 0; if(data->mstate > CURLM_STATE_CONNECT && data->mstate < CURLM_STATE_COMPLETED) { /* Set up ownership correctly */ - data->conn->data = data; + data->conn->data = data; } switch(data->mstate) { @@ -990,30 +990,30 @@ static int multi_getsock(struct Curl_easy *data, return 0; case CURLM_STATE_WAITRESOLVE: - return Curl_resolv_getsock(data->conn, socks); + return Curl_resolv_getsock(data->conn, socks); case CURLM_STATE_PROTOCONNECT: case CURLM_STATE_SENDPROTOCONNECT: - return protocol_getsock(data->conn, socks); + return protocol_getsock(data->conn, socks); case CURLM_STATE_DO: case CURLM_STATE_DOING: - return doing_getsock(data->conn, socks); + return doing_getsock(data->conn, socks); case CURLM_STATE_WAITPROXYCONNECT: - return waitproxyconnect_getsock(data->conn, socks); + return waitproxyconnect_getsock(data->conn, socks); case CURLM_STATE_WAITCONNECT: - return waitconnect_getsock(data->conn, socks); + return waitconnect_getsock(data->conn, socks); case CURLM_STATE_DO_MORE: - return domore_getsock(data->conn, socks); + return domore_getsock(data->conn, socks); case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch to waiting for the same as the *PERFORM states */ case CURLM_STATE_PERFORM: - return Curl_single_getsock(data->conn, socks); + return Curl_single_getsock(data->conn, socks); } } @@ -1039,7 +1039,7 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, data = multi->easyp; while(data) { - int bitmap = multi_getsock(data, sockbunch); + int bitmap = multi_getsock(data, sockbunch); for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { curl_socket_t s = CURL_SOCKET_BAD; @@ -1069,11 +1069,11 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, #define NUM_POLLS_ON_STACK 10 -static CURLMcode Curl_multi_wait(struct Curl_multi *multi, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret, +static CURLMcode Curl_multi_wait(struct Curl_multi *multi, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret, bool extrawait, /* when no socket, wait */ bool use_wakeup) { @@ -1086,7 +1086,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, long timeout_internal; int retcode = 0; struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; - struct pollfd *ufds = &a_few_on_stack[0]; + struct pollfd *ufds = &a_few_on_stack[0]; bool ufds_malloc = FALSE; if(!GOOD_MULTI_HANDLE(multi)) @@ -1101,7 +1101,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, /* Count up how many fds we have from the multi handle */ data = multi->easyp; while(data) { - bitmap = multi_getsock(data, sockbunch); + bitmap = multi_getsock(data, sockbunch); for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { curl_socket_t s = CURL_SOCKET_BAD; @@ -1138,15 +1138,15 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, } #endif - if(nfds > NUM_POLLS_ON_STACK) { - /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes - big, so at 2^29 sockets this value might wrap. When a process gets - the capability to actually handle over 500 million sockets this - calculation needs a integer overflow check. */ - ufds = malloc(nfds * sizeof(struct pollfd)); - if(!ufds) - return CURLM_OUT_OF_MEMORY; - ufds_malloc = TRUE; + if(nfds > NUM_POLLS_ON_STACK) { + /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes + big, so at 2^29 sockets this value might wrap. When a process gets + the capability to actually handle over 500 million sockets this + calculation needs a integer overflow check. */ + ufds = malloc(nfds * sizeof(struct pollfd)); + if(!ufds) + return CURLM_OUT_OF_MEMORY; + ufds_malloc = TRUE; } nfds = 0; @@ -1157,7 +1157,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, /* Add the curl handles to our pollfds first */ data = multi->easyp; while(data) { - bitmap = multi_getsock(data, sockbunch); + bitmap = multi_getsock(data, sockbunch); for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) { curl_socket_t s = CURL_SOCKET_BAD; @@ -1258,22 +1258,22 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, *ret = retcode; if(!extrawait || nfds) /* if any socket was checked */ - ; - else { - long sleep_ms = 0; - - /* Avoid busy-looping when there's nothing particular to wait for */ - if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) { - if(sleep_ms > timeout_ms) - sleep_ms = timeout_ms; + ; + else { + long sleep_ms = 0; + + /* Avoid busy-looping when there's nothing particular to wait for */ + if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) { + if(sleep_ms > timeout_ms) + sleep_ms = timeout_ms; /* when there are no easy handles in the multi, this holds a -1 timeout */ else if(sleep_ms < 0) sleep_ms = timeout_ms; Curl_wait_ms(sleep_ms); - } - } - + } + } + return CURLM_OK; } @@ -1286,12 +1286,12 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi, return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE, FALSE); } - -CURLMcode curl_multi_poll(struct Curl_multi *multi, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret) + +CURLMcode curl_multi_poll(struct Curl_multi *multi, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret) { return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE, TRUE); @@ -1379,7 +1379,7 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, /* take this handle to the perform state right away */ multistate(data, CURLM_STATE_PERFORM); - Curl_attach_connnection(data, conn); + Curl_attach_connnection(data, conn); k->keepon |= KEEP_RECV; /* setup to receive! */ } return rc; @@ -1389,7 +1389,7 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, * do_complete is called when the DO actions are complete. * * We init chunking and trailer bits to their default values here immediately - * before receiving any header data for the current request. + * before receiving any header data for the current request. */ static void do_complete(struct connectdata *conn) { @@ -1397,15 +1397,15 @@ static void do_complete(struct connectdata *conn) Curl_pgrsTime(conn->data, TIMER_PRETRANSFER); } -static CURLcode multi_do(struct Curl_easy *data, bool *done) +static CURLcode multi_do(struct Curl_easy *data, bool *done) { CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; + struct connectdata *conn = data->conn; - DEBUGASSERT(conn); - DEBUGASSERT(conn->handler); + DEBUGASSERT(conn); + DEBUGASSERT(conn->handler); DEBUGASSERT(conn->data == data); - + if(conn->handler->do_it) { /* generic protocol-specific function pointer set in curl_connect() */ result = conn->handler->do_it(conn, done); @@ -1442,108 +1442,108 @@ static CURLcode multi_do_more(struct connectdata *conn, int *complete) return result; } -/* - * We are doing protocol-specific connecting and this is being called over and - * over from the multi interface until the connection phase is done on - * protocol layer. - */ - -static CURLcode protocol_connecting(struct connectdata *conn, - bool *done) -{ - CURLcode result = CURLE_OK; - - if(conn && conn->handler->connecting) { - *done = FALSE; - result = conn->handler->connecting(conn, done); - } - else - *done = TRUE; - - return result; -} - -/* - * We are DOING this is being called over and over from the multi interface - * until the DOING phase is done on protocol layer. - */ - -static CURLcode protocol_doing(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - - if(conn && conn->handler->doing) { - *done = FALSE; - result = conn->handler->doing(conn, done); - } - else - *done = TRUE; - - return result; -} - -/* - * We have discovered that the TCP connection has been successful, we can now - * proceed with some action. - * - */ -static CURLcode protocol_connect(struct connectdata *conn, - bool *protocol_done) -{ - CURLcode result = CURLE_OK; - - DEBUGASSERT(conn); - DEBUGASSERT(protocol_done); - - *protocol_done = FALSE; - - if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) { - /* We already are connected, get back. This may happen when the connect - worked fine in the first call, like when we connect to a local server - or proxy. Note that we don't know if the protocol is actually done. - - Unless this protocol doesn't have any protocol-connect callback, as - then we know we're done. */ - if(!conn->handler->connecting) - *protocol_done = TRUE; - - return CURLE_OK; - } - - if(!conn->bits.protoconnstart) { +/* + * We are doing protocol-specific connecting and this is being called over and + * over from the multi interface until the connection phase is done on + * protocol layer. + */ + +static CURLcode protocol_connecting(struct connectdata *conn, + bool *done) +{ + CURLcode result = CURLE_OK; + + if(conn && conn->handler->connecting) { + *done = FALSE; + result = conn->handler->connecting(conn, done); + } + else + *done = TRUE; + + return result; +} + +/* + * We are DOING this is being called over and over from the multi interface + * until the DOING phase is done on protocol layer. + */ + +static CURLcode protocol_doing(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + + if(conn && conn->handler->doing) { + *done = FALSE; + result = conn->handler->doing(conn, done); + } + else + *done = TRUE; + + return result; +} + +/* + * We have discovered that the TCP connection has been successful, we can now + * proceed with some action. + * + */ +static CURLcode protocol_connect(struct connectdata *conn, + bool *protocol_done) +{ + CURLcode result = CURLE_OK; + + DEBUGASSERT(conn); + DEBUGASSERT(protocol_done); + + *protocol_done = FALSE; + + if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) { + /* We already are connected, get back. This may happen when the connect + worked fine in the first call, like when we connect to a local server + or proxy. Note that we don't know if the protocol is actually done. + + Unless this protocol doesn't have any protocol-connect callback, as + then we know we're done. */ + if(!conn->handler->connecting) + *protocol_done = TRUE; + + return CURLE_OK; + } + + if(!conn->bits.protoconnstart) { #ifndef CURL_DISABLE_PROXY - result = Curl_proxy_connect(conn, FIRSTSOCKET); - if(result) - return result; - - if(CONNECT_FIRSTSOCKET_PROXY_SSL()) - /* wait for HTTPS proxy SSL initialization to complete */ - return CURLE_OK; - - if(conn->bits.tunnel_proxy && conn->bits.httpproxy && - Curl_connect_ongoing(conn)) - /* when using an HTTP tunnel proxy, await complete tunnel establishment - before proceeding further. Return CURLE_OK so we'll be called again */ - return CURLE_OK; + result = Curl_proxy_connect(conn, FIRSTSOCKET); + if(result) + return result; + + if(CONNECT_FIRSTSOCKET_PROXY_SSL()) + /* wait for HTTPS proxy SSL initialization to complete */ + return CURLE_OK; + + if(conn->bits.tunnel_proxy && conn->bits.httpproxy && + Curl_connect_ongoing(conn)) + /* when using an HTTP tunnel proxy, await complete tunnel establishment + before proceeding further. Return CURLE_OK so we'll be called again */ + return CURLE_OK; #endif - if(conn->handler->connect_it) { - /* is there a protocol-specific connect() procedure? */ - - /* Call the protocol-specific connect function */ - result = conn->handler->connect_it(conn, protocol_done); - } - else - *protocol_done = TRUE; - - /* it has started, possibly even completed but that knowledge isn't stored - in this bit! */ - if(!result) - conn->bits.protoconnstart = TRUE; - } - - return result; /* pass back status */ -} - + if(conn->handler->connect_it) { + /* is there a protocol-specific connect() procedure? */ + + /* Call the protocol-specific connect function */ + result = conn->handler->connect_it(conn, protocol_done); + } + else + *protocol_done = TRUE; + + /* it has started, possibly even completed but that knowledge isn't stored + in this bit! */ + if(!result) + conn->bits.protoconnstart = TRUE; + } + + return result; /* pass back status */ +} + /* * Curl_preconnect() is called immediately before a connect starts. When a * redirect is followed, this is then called multiple times during a single @@ -1558,7 +1558,7 @@ CURLcode Curl_preconnect(struct Curl_easy *data) } return CURLE_OK; } - + static CURLMcode multi_runsingle(struct Curl_multi *multi, struct curltime *nowp, @@ -1567,7 +1567,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct Curl_message *msg = NULL; bool connected; bool async; - bool protocol_connected = FALSE; + bool protocol_connected = FALSE; bool dophase_done = FALSE; bool done = FALSE; CURLMcode rc; @@ -1588,47 +1588,47 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(multi_ischanged(multi, TRUE)) { DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n")); - process_pending_handles(multi); /* multiplexed */ + process_pending_handles(multi); /* multiplexed */ } - if(data->conn && data->mstate > CURLM_STATE_CONNECT && + if(data->conn && data->mstate > CURLM_STATE_CONNECT && data->mstate < CURLM_STATE_COMPLETED) { /* Make sure we set the connection's current owner */ - data->conn->data = data; + data->conn->data = data; } - if(data->conn && + if(data->conn && (data->mstate >= CURLM_STATE_CONNECT) && (data->mstate < CURLM_STATE_COMPLETED)) { /* we need to wait for the connect state as only then is the start time stored, but we must not check already completed handles */ timeout_ms = Curl_timeleft(data, nowp, - (data->mstate <= CURLM_STATE_DO)? + (data->mstate <= CURLM_STATE_DO)? TRUE:FALSE); if(timeout_ms < 0) { /* Handle timed out */ if(data->mstate == CURLM_STATE_WAITRESOLVE) - failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds", + failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds", Curl_timediff(*nowp, data->progress.t_startsingle)); else if(data->mstate == CURLM_STATE_WAITCONNECT) - failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds", + failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds", Curl_timediff(*nowp, data->progress.t_startsingle)); else { - struct SingleRequest *k = &data->req; + struct SingleRequest *k = &data->req; if(k->size != -1) { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes received", Curl_timediff(*nowp, data->progress.t_startsingle), k->bytecount, k->size); } else { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T - " bytes received", + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T + " bytes received", Curl_timediff(*nowp, data->progress.t_startsingle), k->bytecount); } @@ -1636,11 +1636,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* Force connection closed if the connection has indeed been used */ if(data->mstate > CURLM_STATE_DO) { - streamclose(data->conn, "Disconnected with pending data"); + streamclose(data->conn, "Disconnected with pending data"); stream_error = TRUE; } result = CURLE_OPERATION_TIMEDOUT; - (void)multi_done(data, result, TRUE); + (void)multi_done(data, result, TRUE); /* Skip the statemachine and go directly to error handling section. */ goto statemachine_end; } @@ -1672,13 +1672,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, break; *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE); - if(data->set.timeout) - Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT); - - if(data->set.connecttimeout) - Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT); - - result = Curl_connect(data, &async, &protocol_connected); + if(data->set.timeout) + Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT); + + if(data->set.connecttimeout) + Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT); + + result = Curl_connect(data, &async, &protocol_connected); if(CURLE_NO_CONNECTION_AVAILABLE == result) { /* There was no connection available. We will go to the pending state and wait for an available connection. */ @@ -1690,31 +1690,31 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, result = CURLE_OK; break; } - else if(data->state.previouslypending) { - /* this transfer comes from the pending queue so try move another */ - infof(data, "Transfer was pending, now try another\n"); - process_pending_handles(data->multi); - } + else if(data->state.previouslypending) { + /* this transfer comes from the pending queue so try move another */ + infof(data, "Transfer was pending, now try another\n"); + process_pending_handles(data->multi); + } if(!result) { - if(async) - /* We're now waiting for an asynchronous name lookup */ - multistate(data, CURLM_STATE_WAITRESOLVE); + if(async) + /* We're now waiting for an asynchronous name lookup */ + multistate(data, CURLM_STATE_WAITRESOLVE); else { - /* after the connect has been sent off, go WAITCONNECT unless the - protocol connect is already done and we can go directly to - WAITDO or DO! */ - rc = CURLM_CALL_MULTI_PERFORM; - - if(protocol_connected) - multistate(data, CURLM_STATE_DO); + /* after the connect has been sent off, go WAITCONNECT unless the + protocol connect is already done and we can go directly to + WAITDO or DO! */ + rc = CURLM_CALL_MULTI_PERFORM; + + if(protocol_connected) + multistate(data, CURLM_STATE_DO); else { #ifndef CURL_DISABLE_HTTP - if(Curl_connect_ongoing(data->conn)) - multistate(data, CURLM_STATE_WAITPROXYCONNECT); - else + if(Curl_connect_ongoing(data->conn)) + multistate(data, CURLM_STATE_WAITPROXYCONNECT); + else #endif - multistate(data, CURLM_STATE_WAITCONNECT); + multistate(data, CURLM_STATE_WAITCONNECT); } } } @@ -1724,10 +1724,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* awaiting an asynch name resolve to complete */ { struct Curl_dns_entry *dns = NULL; - struct connectdata *conn = data->conn; + struct connectdata *conn = data->conn; const char *hostname; - DEBUGASSERT(conn); + DEBUGASSERT(conn); #ifndef CURL_DISABLE_PROXY if(conn->bits.httpproxy) hostname = conn->http_proxy.host.name; @@ -1751,7 +1751,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } if(!dns) - result = Curl_resolv_check(data->conn, &dns); + result = Curl_resolv_check(data->conn, &dns); /* Update sockets here, because the socket(s) may have been closed and the application thus needs to be told, even if it @@ -1764,20 +1764,20 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(dns) { /* Perform the next step in the connection phase, and then move on to the WAITCONNECT state */ - result = Curl_once_resolved(data->conn, &protocol_connected); + result = Curl_once_resolved(data->conn, &protocol_connected); if(result) /* if Curl_once_resolved() returns failure, the connection struct is already freed and gone */ - data->conn = NULL; /* no more connection */ + data->conn = NULL; /* no more connection */ else { /* call again please so that we get the next socket setup */ rc = CURLM_CALL_MULTI_PERFORM; - if(protocol_connected) - multistate(data, CURLM_STATE_DO); + if(protocol_connected) + multistate(data, CURLM_STATE_DO); else { #ifndef CURL_DISABLE_HTTP - if(Curl_connect_ongoing(data->conn)) + if(Curl_connect_ongoing(data->conn)) multistate(data, CURLM_STATE_WAITPROXYCONNECT); else #endif @@ -1797,14 +1797,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, #ifndef CURL_DISABLE_HTTP case CURLM_STATE_WAITPROXYCONNECT: /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */ - DEBUGASSERT(data->conn); - result = Curl_http_connect(data->conn, &protocol_connected); + DEBUGASSERT(data->conn); + result = Curl_http_connect(data->conn, &protocol_connected); #ifndef CURL_DISABLE_PROXY - if(data->conn->bits.proxy_connect_closed) { + if(data->conn->bits.proxy_connect_closed) { rc = CURLM_CALL_MULTI_PERFORM; /* connect back to proxy again */ result = CURLE_OK; - multi_done(data, CURLE_OK, FALSE); + multi_done(data, CURLE_OK, FALSE); multistate(data, CURLM_STATE_CONNECT); } else @@ -1828,8 +1828,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case CURLM_STATE_WAITCONNECT: /* awaiting a completion of an asynch TCP connect */ - DEBUGASSERT(data->conn); - result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected); + DEBUGASSERT(data->conn); + result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected); if(connected && !result) { #ifndef CURL_DISABLE_HTTP if( @@ -1854,43 +1854,43 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } else if(result) { /* failure detected */ - Curl_posttransfer(data); - multi_done(data, result, TRUE); + Curl_posttransfer(data); + multi_done(data, result, TRUE); stream_error = TRUE; break; } break; case CURLM_STATE_SENDPROTOCONNECT: - result = protocol_connect(data->conn, &protocol_connected); - if(!result && !protocol_connected) + result = protocol_connect(data->conn, &protocol_connected); + if(!result && !protocol_connected) /* switch to waiting state */ multistate(data, CURLM_STATE_PROTOCONNECT); else if(!result) { /* protocol connect has completed, go WAITDO or DO */ - multistate(data, CURLM_STATE_DO); + multistate(data, CURLM_STATE_DO); rc = CURLM_CALL_MULTI_PERFORM; } else { /* failure detected */ Curl_posttransfer(data); - multi_done(data, result, TRUE); + multi_done(data, result, TRUE); stream_error = TRUE; } break; case CURLM_STATE_PROTOCONNECT: /* protocol-specific connect phase */ - result = protocol_connecting(data->conn, &protocol_connected); - if(!result && protocol_connected) { + result = protocol_connecting(data->conn, &protocol_connected); + if(!result && protocol_connected) { /* after the connect has completed, go WAITDO or DO */ - multistate(data, CURLM_STATE_DO); + multistate(data, CURLM_STATE_DO); rc = CURLM_CALL_MULTI_PERFORM; } else if(result) { /* failure detected */ Curl_posttransfer(data); - multi_done(data, result, TRUE); + multi_done(data, result, TRUE); stream_error = TRUE; } break; @@ -1898,32 +1898,32 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case CURLM_STATE_DO: if(data->set.connect_only) { /* keep connection open for application to use the socket */ - connkeep(data->conn, "CONNECT_ONLY"); + connkeep(data->conn, "CONNECT_ONLY"); multistate(data, CURLM_STATE_DONE); result = CURLE_OK; rc = CURLM_CALL_MULTI_PERFORM; } else { /* Perform the protocol's DO action */ - result = multi_do(data, &dophase_done); + result = multi_do(data, &dophase_done); - /* When multi_do() returns failure, data->conn might be NULL! */ + /* When multi_do() returns failure, data->conn might be NULL! */ if(!result) { if(!dophase_done) { -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP /* some steps needed for wildcard matching */ if(data->state.wildcardmatch) { struct WildcardData *wc = &data->wildcard; if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { /* skip some states if it is important */ - multi_done(data, CURLE_OK, FALSE); + multi_done(data, CURLE_OK, FALSE); multistate(data, CURLM_STATE_DONE); rc = CURLM_CALL_MULTI_PERFORM; break; } } -#endif +#endif /* DO was not completed in one function call, we must continue DOING... */ multistate(data, CURLM_STATE_DOING); @@ -1931,7 +1931,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } /* after DO, go DO_DONE... or DO_MORE */ - else if(data->conn->bits.do_more) { + else if(data->conn->bits.do_more) { /* we're supposed to do more, but we need to sit down, relax and wait a little while first */ multistate(data, CURLM_STATE_DO_MORE); @@ -1944,7 +1944,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } } else if((CURLE_SEND_ERROR == result) && - data->conn->bits.reuse) { + data->conn->bits.reuse) { /* * In this situation, a connection that we were trying to use * may have unexpectedly died. If possible, send the connection @@ -1954,7 +1954,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, followtype follow = FOLLOW_NONE; CURLcode drc; - drc = Curl_retry_request(data->conn, &newurl); + drc = Curl_retry_request(data->conn, &newurl); if(drc) { /* a failure here pretty much implies an out of memory */ result = drc; @@ -1962,7 +1962,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } Curl_posttransfer(data); - drc = multi_done(data, result, FALSE); + drc = multi_done(data, result, FALSE); /* When set to retry the connection, we must to go back to * the CONNECT state */ @@ -1994,8 +1994,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(data); - if(data->conn) - multi_done(data, result, FALSE); + if(data->conn) + multi_done(data, result, FALSE); stream_error = TRUE; } } @@ -2003,12 +2003,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case CURLM_STATE_DOING: /* we continue DOING until the DO phase is complete */ - DEBUGASSERT(data->conn); - result = protocol_doing(data->conn, &dophase_done); + DEBUGASSERT(data->conn); + result = protocol_doing(data->conn, &dophase_done); if(!result) { if(dophase_done) { /* after DO, go DO_DONE or DO_MORE */ - multistate(data, data->conn->bits.do_more? + multistate(data, data->conn->bits.do_more? CURLM_STATE_DO_MORE: CURLM_STATE_DO_DONE); rc = CURLM_CALL_MULTI_PERFORM; @@ -2017,7 +2017,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(data); - multi_done(data, result, FALSE); + multi_done(data, result, FALSE); stream_error = TRUE; } break; @@ -2026,8 +2026,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* * When we are connected, DO MORE and then go DO_DONE */ - DEBUGASSERT(data->conn); - result = multi_do_more(data->conn, &control); + DEBUGASSERT(data->conn); + result = multi_do_more(data->conn, &control); if(!result) { if(control) { @@ -2045,38 +2045,38 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(data); - multi_done(data, result, FALSE); + multi_done(data, result, FALSE); stream_error = TRUE; } break; case CURLM_STATE_DO_DONE: - DEBUGASSERT(data->conn); - if(data->conn->bits.multiplex) + DEBUGASSERT(data->conn); + if(data->conn->bits.multiplex) /* Check if we can move pending requests to send pipe */ - process_pending_handles(multi); /* multiplexed */ + process_pending_handles(multi); /* multiplexed */ /* Only perform the transfer if there's a good socket to work with. Having both BAD is a signal to skip immediately to DONE */ - if((data->conn->sockfd != CURL_SOCKET_BAD) || - (data->conn->writesockfd != CURL_SOCKET_BAD)) - multistate(data, CURLM_STATE_PERFORM); + if((data->conn->sockfd != CURL_SOCKET_BAD) || + (data->conn->writesockfd != CURL_SOCKET_BAD)) + multistate(data, CURLM_STATE_PERFORM); else { -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP if(data->state.wildcardmatch && - ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) { - data->wildcard.state = CURLWC_DONE; + ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) { + data->wildcard.state = CURLWC_DONE; } -#endif +#endif multistate(data, CURLM_STATE_DONE); } rc = CURLM_CALL_MULTI_PERFORM; break; case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */ - DEBUGASSERT(data->conn); + DEBUGASSERT(data->conn); /* if both rates are within spec, resume transfer */ - if(Curl_pgrsUpdate(data->conn)) + if(Curl_pgrsUpdate(data->conn)) result = CURLE_ABORTED_BY_CALLBACK; else result = Curl_speedcheck(data, *nowp); @@ -2146,14 +2146,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } /* read/write data if it is ready to do so */ - result = Curl_readwrite(data->conn, data, &done, &comeback); + result = Curl_readwrite(data->conn, data, &done, &comeback); if(done || (result == CURLE_RECV_ERROR)) { /* If CURLE_RECV_ERROR happens early enough, we assume it was a race * condition and the server closed the re-used connection exactly when * we wanted to use it, so figure out if that is indeed the case. */ - CURLcode ret = Curl_retry_request(data->conn, &newurl); + CURLcode ret = Curl_retry_request(data->conn, &newurl); if(!ret) retry = (newurl)?TRUE:FALSE; else if(!result) @@ -2167,25 +2167,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } } else if((CURLE_HTTP2_STREAM == result) && - Curl_h2_http_1_1_error(data->conn)) { - CURLcode ret = Curl_retry_request(data->conn, &newurl); - - if(!ret) { - infof(data, "Downgrades to HTTP/1.1!\n"); - data->set.httpversion = CURL_HTTP_VERSION_1_1; - /* clear the error message bit too as we ignore the one we got */ - data->state.errorbuf = FALSE; - if(!newurl) - /* typically for HTTP_1_1_REQUIRED error on first flight */ - newurl = strdup(data->change.url); - /* if we are to retry, set the result to OK and consider the request - as done */ - retry = TRUE; + Curl_h2_http_1_1_error(data->conn)) { + CURLcode ret = Curl_retry_request(data->conn, &newurl); + + if(!ret) { + infof(data, "Downgrades to HTTP/1.1!\n"); + data->set.httpversion = CURL_HTTP_VERSION_1_1; + /* clear the error message bit too as we ignore the one we got */ + data->state.errorbuf = FALSE; + if(!newurl) + /* typically for HTTP_1_1_REQUIRED error on first flight */ + newurl = strdup(data->change.url); + /* if we are to retry, set the result to OK and consider the request + as done */ + retry = TRUE; result = CURLE_OK; done = TRUE; } - else - result = ret; + else + result = ret; } if(result) { @@ -2197,12 +2197,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, * happened in the data connection. */ - if(!(data->conn->handler->flags & PROTOPT_DUAL) && + if(!(data->conn->handler->flags & PROTOPT_DUAL) && result != CURLE_HTTP2_STREAM) - streamclose(data->conn, "Transfer returned error"); + streamclose(data->conn, "Transfer returned error"); Curl_posttransfer(data); - multi_done(data, result, TRUE); + multi_done(data, result, TRUE); } else if(done) { followtype follow = FOLLOW_NONE; @@ -2223,12 +2223,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } else follow = FOLLOW_RETRY; - (void)multi_done(data, CURLE_OK, FALSE); - /* multi_done() might return CURLE_GOT_NOTHING */ - result = Curl_follow(data, newurl, follow); + (void)multi_done(data, CURLE_OK, FALSE); + /* multi_done() might return CURLE_GOT_NOTHING */ + result = Curl_follow(data, newurl, follow); if(!result) { - multistate(data, CURLM_STATE_CONNECT); - rc = CURLM_CALL_MULTI_PERFORM; + multistate(data, CURLM_STATE_CONNECT); + rc = CURLM_CALL_MULTI_PERFORM; } free(newurl); } @@ -2245,7 +2245,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, free(newurl); if(result) { stream_error = TRUE; - result = multi_done(data, result, TRUE); + result = multi_done(data, result, TRUE); } } @@ -2269,30 +2269,30 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* this state is highly transient, so run another loop after this */ rc = CURLM_CALL_MULTI_PERFORM; - if(data->conn) { + if(data->conn) { CURLcode res; - if(data->conn->bits.multiplex) + if(data->conn->bits.multiplex) /* Check if we can move pending requests to connection */ - process_pending_handles(multi); /* multiplexing */ + process_pending_handles(multi); /* multiplexing */ /* post-transfer command */ - res = multi_done(data, result, FALSE); + res = multi_done(data, result, FALSE); /* allow a previously set error code take precedence */ if(!result) result = res; /* - * If there are other handles on the connection, multi_done won't set - * conn to NULL. In such a case, curl_multi_remove_handle() can + * If there are other handles on the connection, multi_done won't set + * conn to NULL. In such a case, curl_multi_remove_handle() can * access free'd data, if the connection is free'd and the handle * removed before we perform the processing in CURLM_STATE_COMPLETED */ Curl_detach_connnection(data); } -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP if(data->state.wildcardmatch) { if(data->wildcard.state != CURLWC_DONE) { /* if a wildcard is set and we are not ending -> lets start again @@ -2301,7 +2301,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, break; } } -#endif +#endif /* after we have DONE what we're supposed to do, go COMPLETED, and it doesn't matter what the multi_done() returned! */ multistate(data, CURLM_STATE_COMPLETED); @@ -2332,22 +2332,22 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* Check if we can move pending requests to send pipe */ process_pending_handles(multi); /* connection */ - if(data->conn) { + if(data->conn) { if(stream_error) { /* Don't attempt to send data over a connection that timed out */ bool dead_connection = result == CURLE_OPERATION_TIMEDOUT; - struct connectdata *conn = data->conn; + struct connectdata *conn = data->conn; - /* This is where we make sure that the conn pointer is reset. + /* This is where we make sure that the conn pointer is reset. We don't have to do this in every case block above where a failure is detected */ Curl_detach_connnection(data); - + /* remove connection from cache */ Curl_conncache_remove_conn(data, conn, TRUE); - /* disconnect properly */ - Curl_disconnect(data, conn, dead_connection); + /* disconnect properly */ + Curl_disconnect(data, conn, dead_connection); } } else if(data->mstate == CURLM_STATE_CONNECT) { @@ -2359,11 +2359,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, rc = CURLM_CALL_MULTI_PERFORM; } /* if there's still a connection to use, call the progress function */ - else if(data->conn && Curl_pgrsUpdate(data->conn)) { + else if(data->conn && Curl_pgrsUpdate(data->conn)) { /* aborted due to progress callback return code must close the connection */ result = CURLE_ABORTED_BY_CALLBACK; - streamclose(data->conn, "Aborted by callback"); + streamclose(data->conn, "Aborted by callback"); /* if not yet in DONE state, go there, otherwise COMPLETED */ multistate(data, (data->mstate < CURLM_STATE_DONE)? @@ -2386,7 +2386,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, msg->extmsg.data.result = result; rc = multi_addmsg(multi, msg); - DEBUGASSERT(!data->conn); + DEBUGASSERT(!data->conn); } multistate(data, CURLM_STATE_MSGSENT); } @@ -2446,7 +2446,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) *running_handles = multi->num_alive; if(CURLM_OK >= returncode) - Curl_update_timer(multi); + Curl_update_timer(multi); return returncode; } @@ -2466,9 +2466,9 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) data = multi->easyp; while(data) { nextdata = data->next; - if(!data->state.done && data->conn) + if(!data->state.done && data->conn) /* if DONE was never called for this handle */ - (void)multi_done(data, CURLE_OK, TRUE); + (void)multi_done(data, CURLE_OK, TRUE); if(data->dns.hostcachetype == HCACHE_MULTI) { /* clear out the usage of the shared DNS cache */ Curl_hostcache_clean(data, data->dns.hostcache); @@ -2561,14 +2561,14 @@ static CURLMcode singlesocket(struct Curl_multi *multi, curl_socket_t s; int num; unsigned int curraction; - int actions[MAX_SOCKSPEREASYHANDLE]; + int actions[MAX_SOCKSPEREASYHANDLE]; for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) socks[i] = CURL_SOCKET_BAD; /* Fill in the 'current' struct with the state as it is now: what sockets to supervise and for what actions */ - curraction = multi_getsock(data, socks); + curraction = multi_getsock(data, socks); /* We have 0 .. N sockets already and we get to know about the 0 .. M sockets we should have from now on. Detect the differences, remove no @@ -2578,10 +2578,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi, for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) && (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))); i++) { - unsigned int action = CURL_POLL_NONE; - unsigned int prevaction = 0; - unsigned int comboaction; - bool sincebefore = FALSE; + unsigned int action = CURL_POLL_NONE; + unsigned int prevaction = 0; + unsigned int comboaction; + bool sincebefore = FALSE; s = socks[i]; @@ -2593,63 +2593,63 @@ static CURLMcode singlesocket(struct Curl_multi *multi, if(curraction & GETSOCK_WRITESOCK(i)) action |= CURL_POLL_OUT; - actions[i] = action; + actions[i] = action; if(entry) { - /* check if new for this transfer */ - int j; - for(j = 0; j< data->numsocks; j++) { - if(s == data->sockets[j]) { - prevaction = data->actions[j]; - sincebefore = TRUE; - break; - } - } + /* check if new for this transfer */ + int j; + for(j = 0; j< data->numsocks; j++) { + if(s == data->sockets[j]) { + prevaction = data->actions[j]; + sincebefore = TRUE; + break; + } + } } else { - /* this is a socket we didn't have before, add it to the hash! */ - entry = sh_addentry(&multi->sockhash, s); + /* this is a socket we didn't have before, add it to the hash! */ + entry = sh_addentry(&multi->sockhash, s); if(!entry) /* fatal */ return CURLM_OUT_OF_MEMORY; } - if(sincebefore && (prevaction != action)) { - /* Socket was used already, but different action now */ - if(prevaction & CURL_POLL_IN) - entry->readers--; - if(prevaction & CURL_POLL_OUT) - entry->writers--; - if(action & CURL_POLL_IN) - entry->readers++; - if(action & CURL_POLL_OUT) - entry->writers++; - } - else if(!sincebefore) { - /* a new user */ - entry->users++; - if(action & CURL_POLL_IN) - entry->readers++; - if(action & CURL_POLL_OUT) - entry->writers++; - - /* add 'data' to the transfer hash on this socket! */ - if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */ - sizeof(struct Curl_easy *), data)) - return CURLM_OUT_OF_MEMORY; - } - - comboaction = (entry->writers? CURL_POLL_OUT : 0) | - (entry->readers ? CURL_POLL_IN : 0); - - /* socket existed before and has the same action set as before */ - if(sincebefore && (entry->action == comboaction)) - /* same, continue */ - continue; - + if(sincebefore && (prevaction != action)) { + /* Socket was used already, but different action now */ + if(prevaction & CURL_POLL_IN) + entry->readers--; + if(prevaction & CURL_POLL_OUT) + entry->writers--; + if(action & CURL_POLL_IN) + entry->readers++; + if(action & CURL_POLL_OUT) + entry->writers++; + } + else if(!sincebefore) { + /* a new user */ + entry->users++; + if(action & CURL_POLL_IN) + entry->readers++; + if(action & CURL_POLL_OUT) + entry->writers++; + + /* add 'data' to the transfer hash on this socket! */ + if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */ + sizeof(struct Curl_easy *), data)) + return CURLM_OUT_OF_MEMORY; + } + + comboaction = (entry->writers? CURL_POLL_OUT : 0) | + (entry->readers ? CURL_POLL_IN : 0); + + /* socket existed before and has the same action set as before */ + if(sincebefore && (entry->action == comboaction)) + /* same, continue */ + continue; + if(multi->socket_cb) - multi->socket_cb(data, s, comboaction, multi->socket_userp, + multi->socket_cb(data, s, comboaction, multi->socket_userp, entry->socketp); - entry->action = comboaction; /* store the current action state */ + entry->action = comboaction; /* store the current action state */ } num = i; /* number of sockets */ @@ -2658,48 +2658,48 @@ static CURLMcode singlesocket(struct Curl_multi *multi, make sure to detect sockets that are removed */ for(i = 0; i< data->numsocks; i++) { int j; - bool stillused = FALSE; + bool stillused = FALSE; s = data->sockets[i]; - for(j = 0; j < num; j++) { + for(j = 0; j < num; j++) { if(s == socks[j]) { /* this is still supervised */ - stillused = TRUE; + stillused = TRUE; break; } } - if(stillused) - continue; + if(stillused) + continue; entry = sh_getentry(&multi->sockhash, s); - /* if this is NULL here, the socket has been closed and notified so - already by Curl_multi_closed() */ + /* if this is NULL here, the socket has been closed and notified so + already by Curl_multi_closed() */ if(entry) { - int oldactions = data->actions[i]; - /* this socket has been removed. Decrease user count */ - entry->users--; - if(oldactions & CURL_POLL_OUT) - entry->writers--; - if(oldactions & CURL_POLL_IN) - entry->readers--; - if(!entry->users) { + int oldactions = data->actions[i]; + /* this socket has been removed. Decrease user count */ + entry->users--; + if(oldactions & CURL_POLL_OUT) + entry->writers--; + if(oldactions & CURL_POLL_IN) + entry->readers--; + if(!entry->users) { if(multi->socket_cb) - multi->socket_cb(data, s, CURL_POLL_REMOVE, + multi->socket_cb(data, s, CURL_POLL_REMOVE, multi->socket_userp, entry->socketp); - sh_delentry(entry, &multi->sockhash, s); + sh_delentry(entry, &multi->sockhash, s); + } + else { + /* still users, but remove this handle as a user of this socket */ + if(Curl_hash_delete(&entry->transfers, (char *)&data, + sizeof(struct Curl_easy *))) { + DEBUGASSERT(NULL); + } } - else { - /* still users, but remove this handle as a user of this socket */ - if(Curl_hash_delete(&entry->transfers, (char *)&data, - sizeof(struct Curl_easy *))) { - DEBUGASSERT(NULL); - } - } - } + } } /* for loop over numsocks */ memcpy(data->sockets, socks, num*sizeof(curl_socket_t)); - memcpy(data->actions, actions, num*sizeof(int)); + memcpy(data->actions, actions, num*sizeof(int)); data->numsocks = num; return CURLM_OK; } @@ -2737,7 +2737,7 @@ void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s) entry->socketp); /* now remove it from the socket hash */ - sh_delentry(entry, &multi->sockhash, s); + sh_delentry(entry, &multi->sockhash, s); } } } @@ -2841,19 +2841,19 @@ static CURLMcode multi_socket(struct Curl_multi *multi, struct Curl_hash_iterator iter; struct Curl_hash_element *he; - /* the socket can be shared by many transfers, iterate */ - Curl_hash_start_iterate(&entry->transfers, &iter); - for(he = Curl_hash_next_element(&iter); he; - he = Curl_hash_next_element(&iter)) { - data = (struct Curl_easy *)he->ptr; - DEBUGASSERT(data); - DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER); + /* the socket can be shared by many transfers, iterate */ + Curl_hash_start_iterate(&entry->transfers, &iter); + for(he = Curl_hash_next_element(&iter); he; + he = Curl_hash_next_element(&iter)) { + data = (struct Curl_easy *)he->ptr; + DEBUGASSERT(data); + DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER); - if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK)) - /* set socket event bitmask if they're not locked */ - data->conn->cselect_bits = ev_bitmask; + if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK)) + /* set socket event bitmask if they're not locked */ + data->conn->cselect_bits = ev_bitmask; - Curl_expire(data, 0, EXPIRE_RUN_NOW); + Curl_expire(data, 0, EXPIRE_RUN_NOW); } /* Now we fall-through and do the timer-based stuff, since we don't want @@ -2868,10 +2868,10 @@ static CURLMcode multi_socket(struct Curl_multi *multi, } else { /* Asked to run due to time-out. Clear the 'lastcall' variable to force - Curl_update_timer() to trigger a callback to the app again even if the - same timeout is still the one to run after this call. That handles the - case when the application asks libcurl to run the timeout - prematurely. */ + Curl_update_timer() to trigger a callback to the app again even if the + same timeout is still the one to run after this call. That handles the + case when the application asks libcurl to run the timeout + prematurely. */ memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); } @@ -2942,7 +2942,7 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, multi->push_userp = va_arg(param, void *); break; case CURLMOPT_PIPELINING: - multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX; + multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX; break; case CURLMOPT_TIMERFUNCTION: multi->timer_cb = va_arg(param, curl_multi_timer_callback); @@ -2956,10 +2956,10 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, case CURLMOPT_MAX_HOST_CONNECTIONS: multi->max_host_connections = va_arg(param, long); break; - case CURLMOPT_MAX_TOTAL_CONNECTIONS: - multi->max_total_connections = va_arg(param, long); - break; - /* options formerly used for pipelining */ + case CURLMOPT_MAX_TOTAL_CONNECTIONS: + multi->max_total_connections = va_arg(param, long); + break; + /* options formerly used for pipelining */ case CURLMOPT_MAX_PIPELINE_LENGTH: break; case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE: @@ -2997,7 +2997,7 @@ CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, return CURLM_RECURSIVE_API_CALL; result = multi_socket(multi, FALSE, s, 0, running_handles); if(CURLM_OK >= result) - Curl_update_timer(multi); + Curl_update_timer(multi); return result; } @@ -3009,7 +3009,7 @@ CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, return CURLM_RECURSIVE_API_CALL; result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles); if(CURLM_OK >= result) - Curl_update_timer(multi); + Curl_update_timer(multi); return result; } @@ -3020,7 +3020,7 @@ CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles) return CURLM_RECURSIVE_API_CALL; result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles); if(CURLM_OK >= result) - Curl_update_timer(multi); + Curl_update_timer(multi); return result; } @@ -3080,14 +3080,14 @@ CURLMcode curl_multi_timeout(struct Curl_multi *multi, * Tell the application it should update its timers, if it subscribes to the * update timer callback. */ -void Curl_update_timer(struct Curl_multi *multi) +void Curl_update_timer(struct Curl_multi *multi) { long timeout_ms; if(!multi->timer_cb) - return; + return; if(multi_timeout(multi, &timeout_ms)) { - return; + return; } if(timeout_ms < 0) { static const struct curltime none = {0, 0}; @@ -3095,10 +3095,10 @@ void Curl_update_timer(struct Curl_multi *multi) multi->timer_lastcall = none; /* there's no timeout now but there was one previously, tell the app to disable it */ - multi->timer_cb(multi, -1, multi->timer_userp); - return; + multi->timer_cb(multi, -1, multi->timer_userp); + return; } - return; + return; } /* When multi_timeout() is done, multi->timetree points to the node with the @@ -3106,11 +3106,11 @@ void Curl_update_timer(struct Curl_multi *multi) * if this is the same (fixed) time as we got in a previous call and then * avoid calling the callback again. */ if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0) - return; + return; multi->timer_lastcall = multi->timetree->key; - multi->timer_cb(multi, timeout_ms, multi->timer_userp); + multi->timer_cb(multi, timeout_ms, multi->timer_userp); } /* @@ -3187,7 +3187,7 @@ multi_addtimeout(struct Curl_easy *data, * * Expire replaces a former timeout using the same id if already set. */ -void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) +void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) { struct Curl_multi *multi = data->multi; struct curltime *nowp = &data->state.expiretime; @@ -3201,7 +3201,7 @@ void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) DEBUGASSERT(id < EXPIRE_LAST); set = Curl_now(); - set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bit conversion */ + set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bit conversion */ set.tv_usec += (unsigned int)(milli%1000)*1000; if(set.tv_usec >= 1000000) { @@ -3289,7 +3289,7 @@ void Curl_expire_clear(struct Curl_easy *data) } #ifdef DEBUGBUILD - infof(data, "Expire cleared (transfer %p)\n", data); + infof(data, "Expire cleared (transfer %p)\n", data); #endif nowp->tv_sec = 0; nowp->tv_usec = 0; @@ -3327,20 +3327,20 @@ size_t Curl_multi_max_total_connections(struct Curl_multi *multi) return multi ? multi->max_total_connections : 0; } -/* - * When information about a connection has appeared, call this! - */ +/* + * When information about a connection has appeared, call this! + */ -void Curl_multiuse_state(struct connectdata *conn, - int bundlestate) /* use BUNDLE_* defines */ +void Curl_multiuse_state(struct connectdata *conn, + int bundlestate) /* use BUNDLE_* defines */ { - DEBUGASSERT(conn); - DEBUGASSERT(conn->bundle); - DEBUGASSERT(conn->data); - DEBUGASSERT(conn->data->multi); + DEBUGASSERT(conn); + DEBUGASSERT(conn->bundle); + DEBUGASSERT(conn->data); + DEBUGASSERT(conn->data->multi); - conn->bundle->multiuse = bundlestate; - process_pending_handles(conn->data->multi); + conn->bundle->multiuse = bundlestate; + process_pending_handles(conn->data->multi); } static void process_pending_handles(struct Curl_multi *multi) @@ -3358,9 +3358,9 @@ static void process_pending_handles(struct Curl_multi *multi) /* Make sure that the handle will be processed soonish. */ Curl_expire(data, 0, EXPIRE_RUN_NOW); - - /* mark this as having been in the pending queue */ - data->state.previouslypending = TRUE; + + /* mark this as having been in the pending queue */ + data->state.previouslypending = TRUE; } } @@ -3404,8 +3404,8 @@ void Curl_multi_dump(struct Curl_multi *multi) continue; } fprintf(stderr, "[%s %s] ", - (entry->action&CURL_POLL_IN)?"RECVING":"", - (entry->action&CURL_POLL_OUT)?"SENDING":""); + (entry->action&CURL_POLL_IN)?"RECVING":"", + (entry->action&CURL_POLL_OUT)?"SENDING":""); } if(data->numsocks) fprintf(stderr, "\n"); diff --git a/contrib/libs/curl/lib/multihandle.h b/contrib/libs/curl/lib/multihandle.h index 32bbf21daf..de4f74069e 100644 --- a/contrib/libs/curl/lib/multihandle.h +++ b/contrib/libs/curl/lib/multihandle.h @@ -47,16 +47,16 @@ typedef enum { CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */ CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect phase */ - CURLM_STATE_DO, /* 8 - start send off the request (part 1) */ - CURLM_STATE_DOING, /* 9 - sending off the request (part 1) */ - CURLM_STATE_DO_MORE, /* 10 - send off the request (part 2) */ - CURLM_STATE_DO_DONE, /* 11 - done sending off request */ - CURLM_STATE_PERFORM, /* 12 - transfer data */ - CURLM_STATE_TOOFAST, /* 13 - wait because limit-rate exceeded */ - CURLM_STATE_DONE, /* 14 - post data transfer operation */ - CURLM_STATE_COMPLETED, /* 15 - operation complete */ - CURLM_STATE_MSGSENT, /* 16 - the operation complete message is sent */ - CURLM_STATE_LAST /* 17 - not a true state, never use this */ + CURLM_STATE_DO, /* 8 - start send off the request (part 1) */ + CURLM_STATE_DOING, /* 9 - sending off the request (part 1) */ + CURLM_STATE_DO_MORE, /* 10 - send off the request (part 2) */ + CURLM_STATE_DO_DONE, /* 11 - done sending off request */ + CURLM_STATE_PERFORM, /* 12 - transfer data */ + CURLM_STATE_TOOFAST, /* 13 - wait because limit-rate exceeded */ + CURLM_STATE_DONE, /* 14 - post data transfer operation */ + CURLM_STATE_COMPLETED, /* 15 - operation complete */ + CURLM_STATE_MSGSENT, /* 16 - the operation complete message is sent */ + CURLM_STATE_LAST /* 17 - not a true state, never use this */ } CURLMstate; /* we support N sockets per easy handle. Set the corresponding bit to what @@ -65,7 +65,7 @@ typedef enum { #define GETSOCK_READABLE (0x00ff) #define GETSOCK_WRITABLE (0xff00) -#define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) +#define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) #if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS) && \ !defined(CURL_DISABLE_SOCKETPAIR) diff --git a/contrib/libs/curl/lib/multiif.h b/contrib/libs/curl/lib/multiif.h index 829441fed6..f0a57d9a6c 100644 --- a/contrib/libs/curl/lib/multiif.h +++ b/contrib/libs/curl/lib/multiif.h @@ -27,14 +27,14 @@ */ void Curl_updatesocket(struct Curl_easy *data); -void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id); +void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id); void Curl_expire_clear(struct Curl_easy *data); void Curl_expire_done(struct Curl_easy *data, expire_id id); -void Curl_update_timer(struct Curl_multi *multi); -void Curl_attach_connnection(struct Curl_easy *data, - struct connectdata *conn); +void Curl_update_timer(struct Curl_multi *multi); +void Curl_attach_connnection(struct Curl_easy *data, + struct connectdata *conn); void Curl_detach_connnection(struct Curl_easy *data); -bool Curl_multiplex_wanted(const struct Curl_multi *multi); +bool Curl_multiplex_wanted(const struct Curl_multi *multi); void Curl_set_in_callback(struct Curl_easy *data, bool value); bool Curl_is_in_callback(struct Curl_easy *easy); CURLcode Curl_preconnect(struct Curl_easy *data); @@ -69,8 +69,8 @@ size_t Curl_multi_max_host_connections(struct Curl_multi *multi); /* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */ size_t Curl_multi_max_total_connections(struct Curl_multi *multi); -void Curl_multiuse_state(struct connectdata *conn, - int bundlestate); /* use BUNDLE_* defines */ +void Curl_multiuse_state(struct connectdata *conn, + int bundlestate); /* use BUNDLE_* defines */ /* * Curl_multi_closed() diff --git a/contrib/libs/curl/lib/netrc.c b/contrib/libs/curl/lib/netrc.c index 416b39fc63..13610bb070 100644 --- a/contrib/libs/curl/lib/netrc.c +++ b/contrib/libs/curl/lib/netrc.c @@ -21,7 +21,7 @@ ***************************************************************************/ #include "curl_setup.h" -#ifndef CURL_DISABLE_NETRC +#ifndef CURL_DISABLE_NETRC #ifdef HAVE_PWD_H #include <pwd.h> @@ -45,22 +45,22 @@ enum host_lookup_state { HOSTVALID /* this is "our" machine! */ }; -#define NETRC_FILE_MISSING 1 -#define NETRC_FAILED -1 -#define NETRC_SUCCESS 0 - +#define NETRC_FILE_MISSING 1 +#define NETRC_FAILED -1 +#define NETRC_SUCCESS 0 + /* - * Returns zero on success. + * Returns zero on success. */ -static int parsenetrc(const char *host, - char **loginp, - char **passwordp, - bool *login_changed, - bool *password_changed, - char *netrcfile) +static int parsenetrc(const char *host, + char **loginp, + char **passwordp, + bool *login_changed, + bool *password_changed, + char *netrcfile) { FILE *file; - int retcode = NETRC_FILE_MISSING; + int retcode = NETRC_FILE_MISSING; char *login = *loginp; char *password = *passwordp; bool specific_login = (login && *login != 0); @@ -73,7 +73,7 @@ static int parsenetrc(const char *host, int state_our_login = FALSE; /* With specific_login, found *our* login name */ - DEBUGASSERT(netrcfile); + DEBUGASSERT(netrcfile); file = fopen(netrcfile, FOPEN_READTEXT); if(file) { @@ -106,14 +106,14 @@ static int parsenetrc(const char *host, } else if(strcasecompare("default", tok)) { state = HOSTVALID; - retcode = NETRC_SUCCESS; /* we did find our host */ + retcode = NETRC_SUCCESS; /* we did find our host */ } break; case HOSTFOUND: if(strcasecompare(host, tok)) { /* and yes, this is our host! */ state = HOSTVALID; - retcode = NETRC_SUCCESS; /* we did find our host */ + retcode = NETRC_SUCCESS; /* we did find our host */ } else /* not our host */ @@ -132,7 +132,7 @@ static int parsenetrc(const char *host, } login = strdup(tok); if(!login) { - retcode = NETRC_FAILED; /* allocation failed */ + retcode = NETRC_FAILED; /* allocation failed */ goto out; } login_alloc = TRUE; @@ -148,7 +148,7 @@ static int parsenetrc(const char *host, } password = strdup(tok); if(!password) { - retcode = NETRC_FAILED; /* allocation failed */ + retcode = NETRC_FAILED; /* allocation failed */ goto out; } password_alloc = TRUE; @@ -173,7 +173,7 @@ static int parsenetrc(const char *host, out: if(!retcode) { - /* success */ + /* success */ *login_changed = FALSE; *password_changed = FALSE; if(login_alloc) { @@ -200,79 +200,79 @@ static int parsenetrc(const char *host, return retcode; } - -/* - * @unittest: 1304 - * - * *loginp and *passwordp MUST be allocated if they aren't NULL when passed - * in. - */ -int Curl_parsenetrc(const char *host, - char **loginp, - char **passwordp, - bool *login_changed, - bool *password_changed, - char *netrcfile) -{ - int retcode = 1; - char *filealloc = NULL; - - if(!netrcfile) { - char *home = NULL; - char *homea = curl_getenv("HOME"); /* portable environment reader */ - if(homea) { - home = homea; -#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - } - else { - struct passwd pw, *pw_res; - char pwbuf[1024]; - if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) - && pw_res) { - home = pw.pw_dir; - } -#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - } - else { - struct passwd *pw; - pw = getpwuid(geteuid()); - if(pw) { - home = pw->pw_dir; - } -#endif - } - - if(!home) - return retcode; /* no home directory found (or possibly out of - memory) */ - - filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR); - if(!filealloc) { - free(homea); - return -1; - } - retcode = parsenetrc(host, loginp, passwordp, login_changed, - password_changed, filealloc); - free(filealloc); -#ifdef WIN32 - if(retcode == NETRC_FILE_MISSING) { - /* fallback to the old-style "_netrc" file */ - filealloc = curl_maprintf("%s%s_netrc", home, DIR_CHAR); - if(!filealloc) { - free(homea); - return -1; - } - retcode = parsenetrc(host, loginp, passwordp, login_changed, - password_changed, filealloc); - free(filealloc); - } -#endif - free(homea); - } - else - retcode = parsenetrc(host, loginp, passwordp, login_changed, - password_changed, netrcfile); - return retcode; -} - -#endif + +/* + * @unittest: 1304 + * + * *loginp and *passwordp MUST be allocated if they aren't NULL when passed + * in. + */ +int Curl_parsenetrc(const char *host, + char **loginp, + char **passwordp, + bool *login_changed, + bool *password_changed, + char *netrcfile) +{ + int retcode = 1; + char *filealloc = NULL; + + if(!netrcfile) { + char *home = NULL; + char *homea = curl_getenv("HOME"); /* portable environment reader */ + if(homea) { + home = homea; +#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) + } + else { + struct passwd pw, *pw_res; + char pwbuf[1024]; + if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) + && pw_res) { + home = pw.pw_dir; + } +#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) + } + else { + struct passwd *pw; + pw = getpwuid(geteuid()); + if(pw) { + home = pw->pw_dir; + } +#endif + } + + if(!home) + return retcode; /* no home directory found (or possibly out of + memory) */ + + filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR); + if(!filealloc) { + free(homea); + return -1; + } + retcode = parsenetrc(host, loginp, passwordp, login_changed, + password_changed, filealloc); + free(filealloc); +#ifdef WIN32 + if(retcode == NETRC_FILE_MISSING) { + /* fallback to the old-style "_netrc" file */ + filealloc = curl_maprintf("%s%s_netrc", home, DIR_CHAR); + if(!filealloc) { + free(homea); + return -1; + } + retcode = parsenetrc(host, loginp, passwordp, login_changed, + password_changed, filealloc); + free(filealloc); + } +#endif + free(homea); + } + else + retcode = parsenetrc(host, loginp, passwordp, login_changed, + password_changed, netrcfile); + return retcode; +} + +#endif diff --git a/contrib/libs/curl/lib/netrc.h b/contrib/libs/curl/lib/netrc.h index bbe0c161ed..4938a5916a 100644 --- a/contrib/libs/curl/lib/netrc.h +++ b/contrib/libs/curl/lib/netrc.h @@ -22,9 +22,9 @@ * ***************************************************************************/ -#include "curl_setup.h" -#ifndef CURL_DISABLE_NETRC - +#include "curl_setup.h" +#ifndef CURL_DISABLE_NETRC + /* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */ int Curl_parsenetrc(const char *host, char **loginp, @@ -37,9 +37,9 @@ int Curl_parsenetrc(const char *host, * section in the netrc. * If (*loginp)[0] != 0, search for password within machine and login. */ -#else -/* disabled */ -#define Curl_parsenetrc(a,b,c,d,e,f) 1 -#endif +#else +/* disabled */ +#define Curl_parsenetrc(a,b,c,d,e,f) 1 +#endif #endif /* HEADER_CURL_NETRC_H */ diff --git a/contrib/libs/curl/lib/non-ascii.c b/contrib/libs/curl/lib/non-ascii.c index d9a39fbce8..30c240b637 100644 --- a/contrib/libs/curl/lib/non-ascii.c +++ b/contrib/libs/curl/lib/non-ascii.c @@ -78,7 +78,7 @@ CURLcode Curl_convert_clone(struct Curl_easy *data, /* * Curl_convert_to_network() is an internal function for performing ASCII - * conversions on non-ASCII platforms. It converts the buffer _in place_. + * conversions on non-ASCII platforms. It converts the buffer _in place_. */ CURLcode Curl_convert_to_network(struct Curl_easy *data, char *buffer, size_t length) @@ -144,7 +144,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data, /* * Curl_convert_from_network() is an internal function for performing ASCII - * conversions on non-ASCII platforms. It converts the buffer _in place_. + * conversions on non-ASCII platforms. It converts the buffer _in place_. */ CURLcode Curl_convert_from_network(struct Curl_easy *data, char *buffer, size_t length) diff --git a/contrib/libs/curl/lib/openldap.c b/contrib/libs/curl/lib/openldap.c index c269e68a88..f8e3150308 100644 --- a/contrib/libs/curl/lib/openldap.c +++ b/contrib/libs/curl/lib/openldap.c @@ -36,7 +36,7 @@ * OpenLDAP library versions, USE_OPENLDAP shall not be defined. */ -#error #include <ldap.h> +#error #include <ldap.h> #include "urldata.h" #include <curl/curl.h> @@ -153,7 +153,7 @@ static const char *url_errs[] = { "bad or missing extensions" }; -struct ldapconninfo { +struct ldapconninfo { LDAP *ld; Curl_recv *recv; /* for stacking SSL handler */ Curl_send *send; @@ -162,7 +162,7 @@ struct ldapconninfo { bool ssldone; bool sslinst; bool didbind; -}; +}; struct ldapreqinfo { int msgid; @@ -171,7 +171,7 @@ struct ldapreqinfo { static CURLcode ldap_setup_connection(struct connectdata *conn) { - struct ldapconninfo *li; + struct ldapconninfo *li; LDAPURLDesc *lud; struct Curl_easy *data = conn->data; int rc, proto; @@ -192,11 +192,11 @@ static CURLcode ldap_setup_connection(struct connectdata *conn) proto = ldap_pvt_url_scheme2proto(lud->lud_scheme); ldap_free_urldesc(lud); - li = calloc(1, sizeof(struct ldapconninfo)); + li = calloc(1, sizeof(struct ldapconninfo)); if(!li) return CURLE_OUT_OF_MEMORY; li->proto = proto; - conn->proto.ldapc = li; + conn->proto.ldapc = li; connkeep(conn, "OpenLDAP default"); return CURLE_OK; } @@ -207,7 +207,7 @@ static Sockbuf_IO ldapsb_tls; static CURLcode ldap_connect(struct connectdata *conn, bool *done) { - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li = conn->proto.ldapc; struct Curl_easy *data = conn->data; int rc, proto = LDAP_VERSION3; char hosturl[1024]; @@ -254,7 +254,7 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done) static CURLcode ldap_connecting(struct connectdata *conn, bool *done) { - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li = conn->proto.ldapc; struct Curl_easy *data = conn->data; LDAPMessage *msg = NULL; struct timeval tv = {0, 1}, *tvp; @@ -359,7 +359,7 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done) static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection) { - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li = conn->proto.ldapc; (void) dead_connection; if(li) { @@ -367,7 +367,7 @@ static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection) ldap_unbind_ext(li->ld, NULL, NULL); li->ld = NULL; } - conn->proto.ldapc = NULL; + conn->proto.ldapc = NULL; free(li); } return CURLE_OK; @@ -375,7 +375,7 @@ static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection) static CURLcode ldap_do(struct connectdata *conn, bool *done) { - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li = conn->proto.ldapc; struct ldapreqinfo *lr; CURLcode status = CURLE_OK; int rc = 0; @@ -413,7 +413,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done) return CURLE_OUT_OF_MEMORY; lr->msgid = msgid; data->req.p.ldap = lr; - Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); *done = TRUE; return CURLE_OK; } @@ -429,7 +429,7 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res, if(lr) { /* if there was a search in progress, abandon it */ if(lr->msgid) { - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li = conn->proto.ldapc; ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL); lr->msgid = 0; } @@ -443,7 +443,7 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res, static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err) { - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li = conn->proto.ldapc; struct Curl_easy *data = conn->data; struct ldapreqinfo *lr = data->req.p.ldap; int rc, ret; @@ -720,7 +720,7 @@ static ber_slen_t ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) { struct connectdata *conn = sbiod->sbiod_pvt; - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li = conn->proto.ldapc; ber_slen_t ret; CURLcode err = CURLE_RECV_ERROR; @@ -735,7 +735,7 @@ static ber_slen_t ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) { struct connectdata *conn = sbiod->sbiod_pvt; - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li = conn->proto.ldapc; ber_slen_t ret; CURLcode err = CURLE_SEND_ERROR; diff --git a/contrib/libs/curl/lib/parsedate.c b/contrib/libs/curl/lib/parsedate.c index 9aa6aec43f..3c38f2c4c2 100644 --- a/contrib/libs/curl/lib/parsedate.c +++ b/contrib/libs/curl/lib/parsedate.c @@ -103,23 +103,23 @@ static int parsedate(const char *date, time_t *output); #if !defined(CURL_DISABLE_PARSEDATE) || !defined(CURL_DISABLE_FTP) || \ !defined(CURL_DISABLE_FILE) /* These names are also used by FTP and FILE code */ -const char * const Curl_wkday[] = -{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; -const char * const Curl_month[]= -{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +const char * const Curl_wkday[] = +{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; +const char * const Curl_month[]= +{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; #endif - + #ifndef CURL_DISABLE_PARSEDATE static const char * const weekday[] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; -struct tzinfo { - char name[5]; - int offset; /* +/- in minutes */ -}; - +struct tzinfo { + char name[5]; + int offset; /* +/- in minutes */ +}; + /* Here's a bunch of frequently used time zone names. These were supported by the old getdate parser. */ #define tDAYZONE -60 /* offset for daylight savings time */ @@ -526,15 +526,15 @@ static int parsedate(const char *date, time_t *output) return PARSEDATE_OK; } -#else -/* disabled */ -static int parsedate(const char *date, time_t *output) -{ - (void)date; - *output = 0; - return PARSEDATE_OK; /* a lie */ -} -#endif +#else +/* disabled */ +static int parsedate(const char *date, time_t *output) +{ + (void)date; + *output = 0; + return PARSEDATE_OK; /* a lie */ +} +#endif time_t curl_getdate(const char *p, const time_t *now) { diff --git a/contrib/libs/curl/lib/pingpong.c b/contrib/libs/curl/lib/pingpong.c index 1d38a83902..5d6109a7df 100644 --- a/contrib/libs/curl/lib/pingpong.c +++ b/contrib/libs/curl/lib/pingpong.c @@ -62,7 +62,7 @@ timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting) timeout_ms = response_time - Curl_timediff(Curl_now(), pp->response); /* spent time */ - if(data->set.timeout && !disconnecting) { + if(data->set.timeout && !disconnecting) { /* if timeout is requested, find out how much remaining time we have */ timediff_t timeout2_ms = data->set.timeout - /* timeout time */ Curl_timediff(Curl_now(), conn->now); /* spent time */ @@ -77,8 +77,8 @@ timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting) /* * Curl_pp_statemach() */ -CURLcode Curl_pp_statemach(struct pingpong *pp, bool block, - bool disconnecting) +CURLcode Curl_pp_statemach(struct pingpong *pp, bool block, + bool disconnecting) { struct connectdata *conn = pp->conn; curl_socket_t sock = conn->sock[FIRSTSOCKET]; @@ -457,7 +457,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, } int Curl_pp_getsock(struct pingpong *pp, - curl_socket_t *socks) + curl_socket_t *socks) { struct connectdata *conn = pp->conn; socks[0] = conn->sock[FIRSTSOCKET]; diff --git a/contrib/libs/curl/lib/pingpong.h b/contrib/libs/curl/lib/pingpong.h index c3f5ee8ac2..0d0c74afa0 100644 --- a/contrib/libs/curl/lib/pingpong.h +++ b/contrib/libs/curl/lib/pingpong.h @@ -81,8 +81,8 @@ struct pingpong { * called repeatedly until done. Set 'wait' to make it wait a while on the * socket if there's no traffic. */ -CURLcode Curl_pp_statemach(struct pingpong *pp, bool block, - bool disconnecting); +CURLcode Curl_pp_statemach(struct pingpong *pp, bool block, + bool disconnecting); /* initialize stuff to prepare for reading a fresh new response */ void Curl_pp_init(struct pingpong *pp); @@ -138,7 +138,7 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp); /* call this when a pingpong connection is disconnected */ CURLcode Curl_pp_disconnect(struct pingpong *pp); -int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks); +int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks); /*********************************************************************** diff --git a/contrib/libs/curl/lib/pop3.c b/contrib/libs/curl/lib/pop3.c index 9ecc6b0ff9..e71860e48a 100644 --- a/contrib/libs/curl/lib/pop3.c +++ b/contrib/libs/curl/lib/pop3.c @@ -30,7 +30,7 @@ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism * RFC5034 POP3 SASL Authentication Mechanism * RFC6749 OAuth 2.0 Authorization Framework - * RFC8314 Use of TLS for Email Submission and Access + * RFC8314 Use of TLS for Email Submission and Access * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt> * ***************************************************************************/ @@ -95,7 +95,7 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status, static CURLcode pop3_connect(struct connectdata *conn, bool *done); static CURLcode pop3_disconnect(struct connectdata *conn, bool dead); static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done); -static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks); +static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks); static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done); static CURLcode pop3_setup_connection(struct connectdata *conn); static CURLcode pop3_parse_url_options(struct connectdata *conn); @@ -210,7 +210,7 @@ static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len, /* Are we processing CAPA command responses? */ if(pop3c->state == POP3_CAPA) { /* Do we have the terminating line? */ - if(len >= 1 && line[0] == '.') + if(len >= 1 && line[0] == '.') /* Treat the response as a success */ *resp = '+'; else @@ -228,7 +228,7 @@ static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len, } /* Do we have a continuation response? */ - if(len >= 1 && line[0] == '+') { + if(len >= 1 && line[0] == '+') { *resp = '*'; return TRUE; @@ -341,7 +341,7 @@ static CURLcode pop3_perform_capa(struct connectdata *conn) static CURLcode pop3_perform_starttls(struct connectdata *conn) { /* Send the STLS command */ - CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS"); + CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS"); if(!result) state(conn, POP3_STARTTLS); @@ -357,10 +357,10 @@ static CURLcode pop3_perform_starttls(struct connectdata *conn) */ static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn) { - /* Start the SSL connection */ + /* Start the SSL connection */ struct pop3_conn *pop3c = &conn->proto.pop3c; - CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, - &pop3c->ssldone); + CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, + &pop3c->ssldone); if(!result) { if(pop3c->state != POP3_UPGRADETLS) @@ -592,7 +592,7 @@ static CURLcode pop3_perform_command(struct connectdata *conn) static CURLcode pop3_perform_quit(struct connectdata *conn) { /* Send the QUIT command */ - CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT"); + CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT"); if(!result) state(conn, POP3_QUIT); @@ -909,7 +909,7 @@ static CURLcode pop3_state_command_resp(struct connectdata *conn, if(pop3->transfer == FTPTRANSFER_BODY) { /* POP3 download */ - Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); if(pp->cache) { /* The header "cache" contains a bunch of data that is actually body @@ -1022,20 +1022,20 @@ static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done) return result; } - result = Curl_pp_statemach(&pop3c->pp, FALSE, FALSE); + result = Curl_pp_statemach(&pop3c->pp, FALSE, FALSE); *done = (pop3c->state == POP3_STOP) ? TRUE : FALSE; return result; } -static CURLcode pop3_block_statemach(struct connectdata *conn, - bool disconnecting) +static CURLcode pop3_block_statemach(struct connectdata *conn, + bool disconnecting) { CURLcode result = CURLE_OK; struct pop3_conn *pop3c = &conn->proto.pop3c; while(pop3c->state != POP3_STOP && !result) - result = Curl_pp_statemach(&pop3c->pp, TRUE, disconnecting); + result = Curl_pp_statemach(&pop3c->pp, TRUE, disconnecting); return result; } @@ -1056,9 +1056,9 @@ static CURLcode pop3_init(struct connectdata *conn) } /* For the POP3 "protocol connect" and "doing" phases only */ -static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks) +static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks) { - return Curl_pp_getsock(&conn->proto.pop3c.pp, socks); + return Curl_pp_getsock(&conn->proto.pop3c.pp, socks); } /*********************************************************************** @@ -1233,7 +1233,7 @@ static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection) point! */ if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart) if(!pop3_perform_quit(conn)) - (void)pop3_block_statemach(conn, TRUE); /* ignore errors on QUIT */ + (void)pop3_block_statemach(conn, TRUE); /* ignore errors on QUIT */ /* Disconnect from the server */ Curl_pp_disconnect(&pop3c->pp); diff --git a/contrib/libs/curl/lib/progress.c b/contrib/libs/curl/lib/progress.c index e16b072553..658d05ab8e 100644 --- a/contrib/libs/curl/lib/progress.c +++ b/contrib/libs/curl/lib/progress.c @@ -26,13 +26,13 @@ #include "sendf.h" #include "multiif.h" #include "progress.h" -#include "timeval.h" +#include "timeval.h" #include "curl_printf.h" /* check rate limits within this many recent milliseconds, at minimum. */ #define MIN_RATE_LIMIT_PERIOD 3000 -#ifndef CURL_DISABLE_PROGRESS_METER +#ifndef CURL_DISABLE_PROGRESS_METER /* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero byte) */ static void time2str(char *r, curl_off_t seconds) @@ -121,7 +121,7 @@ static char *max5data(curl_off_t bytes, char *max5) return max5; } -#endif +#endif /* @@ -173,7 +173,7 @@ void Curl_pgrsResetTransferSizes(struct Curl_easy *data) struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer) { struct curltime now = Curl_now(); - timediff_t *delta = NULL; + timediff_t *delta = NULL; switch(timer) { default: @@ -242,8 +242,8 @@ void Curl_pgrsStartNow(struct Curl_easy *data) data->progress.is_t_startransfer_set = false; data->progress.ul_limit_start = data->progress.start; data->progress.dl_limit_start = data->progress.start; - data->progress.downloaded = 0; - data->progress.uploaded = 0; + data->progress.downloaded = 0; + data->progress.uploaded = 0; /* clear all bits except HIDE and HEADERS_OUT */ data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT; Curl_ratelimit(data, data->progress.start); @@ -274,8 +274,8 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, struct curltime now) { curl_off_t size = cursize - startsize; - timediff_t minimum; - timediff_t actual; + timediff_t minimum; + timediff_t actual; if(!limit || !size) return 0; @@ -288,10 +288,10 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, minimum = (timediff_t) (CURL_OFF_T_C(1000) * size / limit); else { minimum = (timediff_t) (size / limit); - if(minimum < TIMEDIFF_T_MAX/1000) + if(minimum < TIMEDIFF_T_MAX/1000) minimum *= 1000; else - minimum = TIMEDIFF_T_MAX; + minimum = TIMEDIFF_T_MAX; } /* @@ -370,15 +370,15 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size) } } -/* returns TRUE if it's time to show the progress meter */ -static bool progress_calc(struct connectdata *conn, struct curltime now) +/* returns TRUE if it's time to show the progress meter */ +static bool progress_calc(struct connectdata *conn, struct curltime now) { curl_off_t timespent; curl_off_t timespent_ms; /* milliseconds */ struct Curl_easy *data = conn->data; curl_off_t dl = data->progress.downloaded; curl_off_t ul = data->progress.uploaded; - bool timetoshow = FALSE; + bool timetoshow = FALSE; /* The time spent so far (from the start) */ data->progress.timespent = Curl_timediff_us(now, data->progress.start); @@ -400,9 +400,9 @@ static bool progress_calc(struct connectdata *conn, struct curltime now) /* Calculations done at most once a second, unless end is reached */ if(data->progress.lastshow != now.tv_sec) { int countindex; /* amount of seconds stored in the speeder array */ - int nowindex = data->progress.speeder_c% CURR_TIME; + int nowindex = data->progress.speeder_c% CURR_TIME; data->progress.lastshow = now.tv_sec; - timetoshow = TRUE; + timetoshow = TRUE; /* Let's do the "current speed" thing, with the dl + ul speeds combined. Store the speed at entry 'nowindex'. */ @@ -435,7 +435,7 @@ static bool progress_calc(struct connectdata *conn, struct curltime now) data->progress.speeder_c%CURR_TIME:0; /* Figure out the exact time for the time span */ - span_ms = Curl_timediff(now, data->progress.speeder_time[checkindex]); + span_ms = Curl_timediff(now, data->progress.speeder_time[checkindex]); if(0 == span_ms) span_ms = 1; /* at least one millisecond MUST have passed */ @@ -461,131 +461,131 @@ static bool progress_calc(struct connectdata *conn, struct curltime now) data->progress.ulspeed + data->progress.dlspeed; } /* Calculations end */ - return timetoshow; -} - -#ifndef CURL_DISABLE_PROGRESS_METER -static void progress_meter(struct connectdata *conn) -{ - struct Curl_easy *data = conn->data; - char max5[6][10]; - curl_off_t dlpercen = 0; - curl_off_t ulpercen = 0; - curl_off_t total_percen = 0; - curl_off_t total_transfer; - curl_off_t total_expected_transfer; - char time_left[10]; - char time_total[10]; - char time_spent[10]; - curl_off_t ulestimate = 0; - curl_off_t dlestimate = 0; - curl_off_t total_estimate; - curl_off_t timespent = - (curl_off_t)data->progress.timespent/1000000; /* seconds */ - - if(!(data->progress.flags & PGRS_HEADERS_OUT)) { - if(data->state.resume_from) { - fprintf(data->set.err, - "** Resuming transfer from byte position %" - CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); - } - fprintf(data->set.err, - " %% Total %% Received %% Xferd Average Speed " - "Time Time Time Current\n" - " Dload Upload " - "Total Spent Left Speed\n"); - data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */ - } - - /* Figure out the estimated time of arrival for the upload */ - if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && - (data->progress.ulspeed > CURL_OFF_T_C(0))) { - ulestimate = data->progress.size_ul / data->progress.ulspeed; - - if(data->progress.size_ul > CURL_OFF_T_C(10000)) - ulpercen = data->progress.uploaded / - (data->progress.size_ul/CURL_OFF_T_C(100)); - else if(data->progress.size_ul > CURL_OFF_T_C(0)) - ulpercen = (data->progress.uploaded*100) / - data->progress.size_ul; - } - - /* ... and the download */ - if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && - (data->progress.dlspeed > CURL_OFF_T_C(0))) { - dlestimate = data->progress.size_dl / data->progress.dlspeed; - - if(data->progress.size_dl > CURL_OFF_T_C(10000)) - dlpercen = data->progress.downloaded / - (data->progress.size_dl/CURL_OFF_T_C(100)); - else if(data->progress.size_dl > CURL_OFF_T_C(0)) - dlpercen = (data->progress.downloaded*100) / - data->progress.size_dl; - } - - /* Now figure out which of them is slower and use that one for the - total estimate! */ - total_estimate = ulestimate>dlestimate?ulestimate:dlestimate; - - /* create the three time strings */ - time2str(time_left, total_estimate > 0?(total_estimate - timespent):0); - time2str(time_total, total_estimate); - time2str(time_spent, timespent); - - /* Get the total amount of data expected to get transferred */ - total_expected_transfer = - ((data->progress.flags & PGRS_UL_SIZE_KNOWN)? - data->progress.size_ul:data->progress.uploaded)+ - ((data->progress.flags & PGRS_DL_SIZE_KNOWN)? - data->progress.size_dl:data->progress.downloaded); - - /* We have transferred this much so far */ - total_transfer = data->progress.downloaded + data->progress.uploaded; - - /* Get the percentage of data transferred so far */ - if(total_expected_transfer > CURL_OFF_T_C(10000)) - total_percen = total_transfer / - (total_expected_transfer/CURL_OFF_T_C(100)); - else if(total_expected_transfer > CURL_OFF_T_C(0)) - total_percen = (total_transfer*100) / total_expected_transfer; - - fprintf(data->set.err, - "\r" - "%3" CURL_FORMAT_CURL_OFF_T " %s " - "%3" CURL_FORMAT_CURL_OFF_T " %s " - "%3" CURL_FORMAT_CURL_OFF_T " %s %s %s %s %s %s %s", - total_percen, /* 3 letters */ /* total % */ - max5data(total_expected_transfer, max5[2]), /* total size */ - dlpercen, /* 3 letters */ /* rcvd % */ - max5data(data->progress.downloaded, max5[0]), /* rcvd size */ - ulpercen, /* 3 letters */ /* xfer % */ - max5data(data->progress.uploaded, max5[1]), /* xfer size */ - max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */ - max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */ - time_total, /* 8 letters */ /* total time */ - time_spent, /* 8 letters */ /* time spent */ - time_left, /* 8 letters */ /* time left */ - max5data(data->progress.current_speed, max5[5]) - ); - - /* we flush the output stream to make it appear as soon as possible */ - fflush(data->set.err); -} -#else - /* progress bar disabled */ -#define progress_meter(x) Curl_nop_stmt -#endif - - -/* - * Curl_pgrsUpdate() returns 0 for success or the value returned by the - * progress callback! - */ -int Curl_pgrsUpdate(struct connectdata *conn) -{ - struct Curl_easy *data = conn->data; - struct curltime now = Curl_now(); /* what time is it */ - bool showprogress = progress_calc(conn, now); + return timetoshow; +} + +#ifndef CURL_DISABLE_PROGRESS_METER +static void progress_meter(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + char max5[6][10]; + curl_off_t dlpercen = 0; + curl_off_t ulpercen = 0; + curl_off_t total_percen = 0; + curl_off_t total_transfer; + curl_off_t total_expected_transfer; + char time_left[10]; + char time_total[10]; + char time_spent[10]; + curl_off_t ulestimate = 0; + curl_off_t dlestimate = 0; + curl_off_t total_estimate; + curl_off_t timespent = + (curl_off_t)data->progress.timespent/1000000; /* seconds */ + + if(!(data->progress.flags & PGRS_HEADERS_OUT)) { + if(data->state.resume_from) { + fprintf(data->set.err, + "** Resuming transfer from byte position %" + CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); + } + fprintf(data->set.err, + " %% Total %% Received %% Xferd Average Speed " + "Time Time Time Current\n" + " Dload Upload " + "Total Spent Left Speed\n"); + data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */ + } + + /* Figure out the estimated time of arrival for the upload */ + if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && + (data->progress.ulspeed > CURL_OFF_T_C(0))) { + ulestimate = data->progress.size_ul / data->progress.ulspeed; + + if(data->progress.size_ul > CURL_OFF_T_C(10000)) + ulpercen = data->progress.uploaded / + (data->progress.size_ul/CURL_OFF_T_C(100)); + else if(data->progress.size_ul > CURL_OFF_T_C(0)) + ulpercen = (data->progress.uploaded*100) / + data->progress.size_ul; + } + + /* ... and the download */ + if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && + (data->progress.dlspeed > CURL_OFF_T_C(0))) { + dlestimate = data->progress.size_dl / data->progress.dlspeed; + + if(data->progress.size_dl > CURL_OFF_T_C(10000)) + dlpercen = data->progress.downloaded / + (data->progress.size_dl/CURL_OFF_T_C(100)); + else if(data->progress.size_dl > CURL_OFF_T_C(0)) + dlpercen = (data->progress.downloaded*100) / + data->progress.size_dl; + } + + /* Now figure out which of them is slower and use that one for the + total estimate! */ + total_estimate = ulestimate>dlestimate?ulestimate:dlestimate; + + /* create the three time strings */ + time2str(time_left, total_estimate > 0?(total_estimate - timespent):0); + time2str(time_total, total_estimate); + time2str(time_spent, timespent); + + /* Get the total amount of data expected to get transferred */ + total_expected_transfer = + ((data->progress.flags & PGRS_UL_SIZE_KNOWN)? + data->progress.size_ul:data->progress.uploaded)+ + ((data->progress.flags & PGRS_DL_SIZE_KNOWN)? + data->progress.size_dl:data->progress.downloaded); + + /* We have transferred this much so far */ + total_transfer = data->progress.downloaded + data->progress.uploaded; + + /* Get the percentage of data transferred so far */ + if(total_expected_transfer > CURL_OFF_T_C(10000)) + total_percen = total_transfer / + (total_expected_transfer/CURL_OFF_T_C(100)); + else if(total_expected_transfer > CURL_OFF_T_C(0)) + total_percen = (total_transfer*100) / total_expected_transfer; + + fprintf(data->set.err, + "\r" + "%3" CURL_FORMAT_CURL_OFF_T " %s " + "%3" CURL_FORMAT_CURL_OFF_T " %s " + "%3" CURL_FORMAT_CURL_OFF_T " %s %s %s %s %s %s %s", + total_percen, /* 3 letters */ /* total % */ + max5data(total_expected_transfer, max5[2]), /* total size */ + dlpercen, /* 3 letters */ /* rcvd % */ + max5data(data->progress.downloaded, max5[0]), /* rcvd size */ + ulpercen, /* 3 letters */ /* xfer % */ + max5data(data->progress.uploaded, max5[1]), /* xfer size */ + max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */ + max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */ + time_total, /* 8 letters */ /* total time */ + time_spent, /* 8 letters */ /* time spent */ + time_left, /* 8 letters */ /* time left */ + max5data(data->progress.current_speed, max5[5]) + ); + + /* we flush the output stream to make it appear as soon as possible */ + fflush(data->set.err); +} +#else + /* progress bar disabled */ +#define progress_meter(x) Curl_nop_stmt +#endif + + +/* + * Curl_pgrsUpdate() returns 0 for success or the value returned by the + * progress callback! + */ +int Curl_pgrsUpdate(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct curltime now = Curl_now(); /* what time is it */ + bool showprogress = progress_calc(conn, now); if(!(data->progress.flags & PGRS_HIDE)) { if(data->set.fxferinfo) { int result; @@ -620,9 +620,9 @@ int Curl_pgrsUpdate(struct connectdata *conn) } } - if(showprogress) - progress_meter(conn); - } + if(showprogress) + progress_meter(conn); + } return 0; } diff --git a/contrib/libs/curl/lib/quic.h b/contrib/libs/curl/lib/quic.h index ff7536dd0b..83e10cb44f 100644 --- a/contrib/libs/curl/lib/quic.h +++ b/contrib/libs/curl/lib/quic.h @@ -1,59 +1,59 @@ -#ifndef HEADER_CURL_QUIC_H -#define HEADER_CURL_QUIC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +#ifndef HEADER_CURL_QUIC_H +#define HEADER_CURL_QUIC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef ENABLE_QUIC -#ifdef USE_NGTCP2 -#error #include "vquic/ngtcp2.h" -#endif -#ifdef USE_QUICHE -#error #include "vquic/quiche.h" -#endif - -#include "urldata.h" - -/* functions provided by the specific backends */ -CURLcode Curl_quic_connect(struct connectdata *conn, - curl_socket_t sockfd, - int sockindex, - const struct sockaddr *addr, - socklen_t addrlen); -CURLcode Curl_quic_is_connected(struct connectdata *conn, + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef ENABLE_QUIC +#ifdef USE_NGTCP2 +#error #include "vquic/ngtcp2.h" +#endif +#ifdef USE_QUICHE +#error #include "vquic/quiche.h" +#endif + +#include "urldata.h" + +/* functions provided by the specific backends */ +CURLcode Curl_quic_connect(struct connectdata *conn, + curl_socket_t sockfd, + int sockindex, + const struct sockaddr *addr, + socklen_t addrlen); +CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex, - bool *connected); -int Curl_quic_ver(char *p, size_t len); -CURLcode Curl_quic_done_sending(struct connectdata *conn); + bool *connected); +int Curl_quic_ver(char *p, size_t len); +CURLcode Curl_quic_done_sending(struct connectdata *conn); void Curl_quic_done(struct Curl_easy *data, bool premature); bool Curl_quic_data_pending(const struct Curl_easy *data); void Curl_quic_disconnect(struct connectdata *conn, int tempindex); - -#else /* ENABLE_QUIC */ -#define Curl_quic_done_sending(x) + +#else /* ENABLE_QUIC */ +#define Curl_quic_done_sending(x) #define Curl_quic_done(x,y) #define Curl_quic_data_pending(x) #define Curl_quic_disconnect(x,y) -#endif /* !ENABLE_QUIC */ - -#endif /* HEADER_CURL_QUIC_H */ +#endif /* !ENABLE_QUIC */ + +#endif /* HEADER_CURL_QUIC_H */ diff --git a/contrib/libs/curl/lib/rand.c b/contrib/libs/curl/lib/rand.c index 8ecd96db0b..951fedb0a9 100644 --- a/contrib/libs/curl/lib/rand.c +++ b/contrib/libs/curl/lib/rand.c @@ -106,7 +106,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) * 'rndptr' points to. * * If libcurl is built without TLS support or with a TLS backend that lacks a - * proper random API (Gskit or mbedTLS), this function will use "weak" random. + * proper random API (Gskit or mbedTLS), this function will use "weak" random. * * When built *with* TLS support and a backend that offers strong random, it * will return error if it cannot provide strong random values. diff --git a/contrib/libs/curl/lib/rand.h b/contrib/libs/curl/lib/rand.h index 78c8e88bd3..02d95d8e64 100644 --- a/contrib/libs/curl/lib/rand.h +++ b/contrib/libs/curl/lib/rand.h @@ -27,7 +27,7 @@ * 'rnd' points to. * * If libcurl is built without TLS support or with a TLS backend that lacks a - * proper random API (Gskit or mbedTLS), this function will use "weak" random. + * proper random API (Gskit or mbedTLS), this function will use "weak" random. * * When built *with* TLS support and a backend that offers strong random, it * will return error if it cannot provide strong random values. @@ -38,11 +38,11 @@ */ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num); -/* - * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random - * hexadecimal digits PLUS a zero terminating byte. It must be an odd number - * size. - */ +/* + * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random + * hexadecimal digits PLUS a zero terminating byte. It must be an odd number + * size. + */ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, size_t num); diff --git a/contrib/libs/curl/lib/rtsp.c b/contrib/libs/curl/lib/rtsp.c index 70f9ca62a2..151ff4af27 100644 --- a/contrib/libs/curl/lib/rtsp.c +++ b/contrib/libs/curl/lib/rtsp.c @@ -52,7 +52,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done); static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature); static CURLcode rtsp_connect(struct connectdata *conn, bool *done); static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead); -static int rtsp_getsock_do(struct connectdata *conn, curl_socket_t *socks); +static int rtsp_getsock_do(struct connectdata *conn, curl_socket_t *socks); /* * Parse and write out any available RTP data. @@ -74,7 +74,7 @@ static unsigned int rtsp_conncheck(struct connectdata *check, interface and then we're always _sending_ a request and thus we wait for the single socket to become writable only */ static int rtsp_getsock_do(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { /* write mode */ socks[0] = conn->sock[FIRSTSOCKET]; @@ -131,7 +131,7 @@ static CURLcode rtsp_setup_connection(struct connectdata *conn) * Instead, if it is readable, run Curl_connalive() to peek at the socket * and distinguish between closed and data. */ -static bool rtsp_connisdead(struct connectdata *check) +static bool rtsp_connisdead(struct connectdata *check) { int sval; bool ret_val = TRUE; @@ -308,7 +308,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) } if(rtspreq == RTSPREQ_RECEIVE) { - Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); return result; } @@ -571,15 +571,15 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) return result; } - Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, putsize?FIRSTSOCKET:-1); + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, putsize?FIRSTSOCKET:-1); /* Increment the CSeq on success */ data->state.rtsp_next_client_CSeq++; - if(data->req.writebytecount) { + if(data->req.writebytecount) { /* if a request-body has been sent off, we make sure this progress is noted properly */ - Curl_pgrsSetUploadCounter(data, data->req.writebytecount); + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); if(Curl_pgrsUpdate(conn)) result = CURLE_ABORTED_BY_CALLBACK; } diff --git a/contrib/libs/curl/lib/sendf.c b/contrib/libs/curl/lib/sendf.c index 31fd8106a1..04cc725f5a 100644 --- a/contrib/libs/curl/lib/sendf.c +++ b/contrib/libs/curl/lib/sendf.c @@ -371,9 +371,9 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num, *code = CURLE_AGAIN; } else { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(conn->data, "Send failure: %s", - Curl_strerror(err, buffer, sizeof(buffer))); + Curl_strerror(err, buffer, sizeof(buffer))); conn->data->state.os_errno = err; *code = CURLE_SEND_ERROR; } @@ -437,9 +437,9 @@ ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, *code = CURLE_AGAIN; } else { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(conn->data, "Recv failure: %s", - Curl_strerror(err, buffer, sizeof(buffer))); + Curl_strerror(err, buffer, sizeof(buffer))); conn->data->state.os_errno = err; *code = CURLE_RECV_ERROR; } @@ -536,10 +536,10 @@ static CURLcode chop_write(struct connectdata *conn, size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE; if(writebody) { - size_t wrote; - Curl_set_in_callback(data, true); - wrote = writebody(ptr, 1, chunklen, data->set.out); - Curl_set_in_callback(data, false); + size_t wrote; + Curl_set_in_callback(data, true); + wrote = writebody(ptr, 1, chunklen, data->set.out); + Curl_set_in_callback(data, false); if(CURL_WRITEFUNC_PAUSE == wrote) { if(conn->handler->flags & PROTOPT_NONETWORK) { @@ -676,8 +676,8 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */ *n = 0; /* reset amount to zero */ - bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); - buffertofill = buf; + bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); + buffertofill = buf; nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result); if(nread < 0) diff --git a/contrib/libs/curl/lib/setopt.c b/contrib/libs/curl/lib/setopt.c index 3dd81b3184..58956c1e95 100644 --- a/contrib/libs/curl/lib/setopt.c +++ b/contrib/libs/curl/lib/setopt.c @@ -46,7 +46,7 @@ #include "http2.h" #include "setopt.h" #include "multiif.h" -#include "altsvc.h" +#include "altsvc.h" #include "hsts.h" /* The last 3 #include files should be in this order */ @@ -64,13 +64,13 @@ CURLcode Curl_setstropt(char **charp, const char *s) if(s) { char *str = strdup(s); - if(str) { - size_t len = strlen(str); - if(len > CURL_MAX_INPUT_LENGTH) { - free(str); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } + if(str) { + size_t len = strlen(str); + if(len > CURL_MAX_INPUT_LENGTH) { + free(str); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } if(!str) return CURLE_OUT_OF_MEMORY; @@ -153,16 +153,16 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) #define C_SSLVERSION_VALUE(x) (x & 0xffff) #define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000) -/* - * Do not make Curl_vsetopt() static: it is called from - * packages/OS400/ccsidcurl.c. - */ -CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) +/* + * Do not make Curl_vsetopt() static: it is called from + * packages/OS400/ccsidcurl.c. + */ +CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) { char *argptr; CURLcode result = CURLE_OK; long arg; - unsigned long uarg; + unsigned long uarg; curl_off_t bigsize; switch(option) { @@ -173,20 +173,20 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.dns_cache_timeout = arg; break; case CURLOPT_DNS_USE_GLOBAL_CACHE: - /* deprecated */ + /* deprecated */ break; case CURLOPT_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection */ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG], va_arg(param, char *)); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection for proxy */ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY], va_arg(param, char *)); break; -#endif +#endif case CURLOPT_TLS13_CIPHERS: if(Curl_ssl_tls13_ciphersuites()) { /* set preferred list of TLS 1.3 cipher suites */ @@ -196,7 +196,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) else return CURLE_NOT_BUILT_IN; break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_TLS13_CIPHERS: if(Curl_ssl_tls13_ciphersuites()) { /* set preferred list of TLS 1.3 cipher suites for proxy */ @@ -206,7 +206,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) else return CURLE_NOT_BUILT_IN; break; -#endif +#endif case CURLOPT_RANDOM_FILE: /* * This is the path name to a file that contains random data to seed @@ -330,7 +330,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) else return CURLE_BAD_FUNCTION_ARGUMENT; break; -#ifndef CURL_DISABLE_TFTP +#ifndef CURL_DISABLE_TFTP case CURLOPT_TFTP_NO_OPTIONS: /* * Option that prevents libcurl from sending TFTP option requests to the @@ -347,8 +347,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) return CURLE_BAD_FUNCTION_ARGUMENT; data->set.tftp_blksize = arg; break; -#endif -#ifndef CURL_DISABLE_NETRC +#endif +#ifndef CURL_DISABLE_NETRC case CURLOPT_NETRC: /* * Parse the $HOME/.netrc file @@ -365,7 +365,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE], va_arg(param, char *)); break; -#endif +#endif case CURLOPT_TRANSFERTEXT: /* * This option was previously named 'FTPASCII'. Renamed to work with @@ -679,7 +679,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #ifndef CURL_DISABLE_HTTP -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXYHEADER: /* * Set a list with proxy headers to use (or replace internals with) @@ -693,13 +693,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ data->set.proxyheaders = va_arg(param, struct curl_slist *); break; -#endif +#endif case CURLOPT_HEADEROPT: /* * Set header option. */ arg = va_arg(param, long); - data->set.sep_headers = (bool)((arg & CURLHEADER_SEPARATE)? TRUE: FALSE); + data->set.sep_headers = (bool)((arg & CURLHEADER_SEPARATE)? TRUE: FALSE); break; case CURLOPT_HTTP200ALIASES: @@ -826,12 +826,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) if(checkprefix("Set-Cookie:", argptr)) /* HTTP Header format line */ Curl_cookie_add(data, data->cookies, TRUE, FALSE, argptr + 11, NULL, - NULL, TRUE); + NULL, TRUE); else /* Netscape format line */ Curl_cookie_add(data, data->cookies, FALSE, FALSE, argptr, NULL, - NULL, TRUE); + NULL, TRUE); Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); free(argptr); @@ -860,11 +860,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) arg = va_arg(param, long); if(arg < CURL_HTTP_VERSION_NONE) return CURLE_BAD_FUNCTION_ARGUMENT; -#ifdef ENABLE_QUIC - if(arg == CURL_HTTP_VERSION_3) - ; - else -#endif +#ifdef ENABLE_QUIC + if(arg == CURL_HTTP_VERSION_3) + ; + else +#endif #ifndef USE_NGHTTP2 if(arg >= CURL_HTTP_VERSION_2) return CURLE_UNSUPPORTED_PROTOCOL; @@ -888,12 +888,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.expect_100_timeout = arg; break; - case CURLOPT_HTTP09_ALLOWED: - arg = va_arg(param, unsigned long); - if(arg > 1L) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.http09_allowed = arg ? TRUE : FALSE; - break; + case CURLOPT_HTTP09_ALLOWED: + arg = va_arg(param, unsigned long); + if(arg > 1L) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.http09_allowed = arg ? TRUE : FALSE; + break; #endif /* CURL_DISABLE_HTTP */ case CURLOPT_HTTPAUTH: @@ -912,8 +912,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authhost.iestyle = - (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); + data->state.authhost.iestyle = + (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -996,8 +996,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authproxy.iestyle = - (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); + data->state.authproxy.iestyle = + (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -1099,7 +1099,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE; break; #endif -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_SOCKS5_GSSAPI_SERVICE: case CURLOPT_PROXY_SERVICE_NAME: /* @@ -1108,7 +1108,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME], va_arg(param, char *)); break; -#endif +#endif case CURLOPT_SERVICE_NAME: /* * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO @@ -1137,33 +1137,33 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ data->set.out = va_arg(param, void *); break; - - case CURLOPT_DIRLISTONLY: - /* - * An option that changes the command to one that asks for a list only, no - * file info details. Used for FTP, POP3 and SFTP. - */ - data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_APPEND: - /* - * We want to upload and append to an existing file. Used for FTP and - * SFTP. - */ - data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - -#ifndef CURL_DISABLE_FTP - case CURLOPT_FTP_FILEMETHOD: - /* - * How do access files over FTP. - */ - arg = va_arg(param, long); + + case CURLOPT_DIRLISTONLY: + /* + * An option that changes the command to one that asks for a list only, no + * file info details. Used for FTP, POP3 and SFTP. + */ + data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_APPEND: + /* + * We want to upload and append to an existing file. Used for FTP and + * SFTP. + */ + data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + +#ifndef CURL_DISABLE_FTP + case CURLOPT_FTP_FILEMETHOD: + /* + * How do access files over FTP. + */ + arg = va_arg(param, long); if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ftp_filemethod = (curl_ftpfile)arg; - break; + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.ftp_filemethod = (curl_ftpfile)arg; + break; case CURLOPT_FTPPORT: /* * Use FTP PORT, this also specifies which IP address to use @@ -1200,39 +1200,39 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE; break; - case CURLOPT_FTP_ACCOUNT: - result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT], - va_arg(param, char *)); - break; - - case CURLOPT_FTP_ALTERNATIVE_TO_USER: - result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], - va_arg(param, char *)); - break; - - case CURLOPT_FTPSSLAUTH: - /* - * Set a specific auth for FTP-SSL transfers. - */ - arg = va_arg(param, long); + case CURLOPT_FTP_ACCOUNT: + result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT], + va_arg(param, char *)); + break; + + case CURLOPT_FTP_ALTERNATIVE_TO_USER: + result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], + va_arg(param, char *)); + break; + + case CURLOPT_FTPSSLAUTH: + /* + * Set a specific auth for FTP-SSL transfers. + */ + arg = va_arg(param, long); if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ftpsslauth = (curl_ftpauth)arg; - break; - case CURLOPT_KRBLEVEL: - /* - * A string that defines the kerberos security level. - */ - result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL], - va_arg(param, char *)); - data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE; - break; -#endif - case CURLOPT_FTP_CREATE_MISSING_DIRS: - /* - * An FTP/SFTP option that modifies an upload to create missing - * directories on the server. - */ + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.ftpsslauth = (curl_ftpauth)arg; + break; + case CURLOPT_KRBLEVEL: + /* + * A string that defines the kerberos security level. + */ + result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL], + va_arg(param, char *)); + data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE; + break; +#endif + case CURLOPT_FTP_CREATE_MISSING_DIRS: + /* + * An FTP/SFTP option that modifies an upload to create missing + * directories on the server. + */ arg = va_arg(param, long); /* reserve other values for future use */ if((arg < CURLFTP_CREATE_DIR_NONE) || @@ -1240,7 +1240,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = CURLE_BAD_FUNCTION_ARGUMENT; else data->set.ftp_create_missing_dirs = (int)arg; - break; + break; case CURLOPT_READDATA: /* * FILE pointer to read the file to be uploaded from. Or possibly @@ -1656,7 +1656,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_ORIG], va_arg(param, struct curl_blob *)); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLCERT: /* * String that holds file name of the SSL certificate to use for proxy @@ -1671,7 +1671,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_PROXY], va_arg(param, struct curl_blob *)); break; -#endif +#endif case CURLOPT_SSLCERTTYPE: /* * String that holds file type of the SSL certificate to use @@ -1679,7 +1679,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG], va_arg(param, char *)); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLCERTTYPE: /* * String that holds file type of the SSL certificate to use for proxy @@ -1687,7 +1687,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_PROXY], va_arg(param, char *)); break; -#endif +#endif case CURLOPT_SSLKEY: /* * String that holds file name of the SSL key to use @@ -1702,7 +1702,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_ORIG], va_arg(param, struct curl_blob *)); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLKEY: /* * String that holds file name of the SSL key to use for proxy @@ -1717,7 +1717,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_PROXY], va_arg(param, struct curl_blob *)); break; -#endif +#endif case CURLOPT_SSLKEYTYPE: /* * String that holds file type of the SSL key to use @@ -1725,7 +1725,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG], va_arg(param, char *)); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSLKEYTYPE: /* * String that holds file type of the SSL key to use for proxy @@ -1733,7 +1733,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_PROXY], va_arg(param, char *)); break; -#endif +#endif case CURLOPT_KEYPASSWD: /* * String that holds the SSL or SSH private key password. @@ -1741,7 +1741,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG], va_arg(param, char *)); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_KEYPASSWD: /* * String that holds the SSL private key password for proxy. @@ -1749,7 +1749,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY], va_arg(param, char *)); break; -#endif +#endif case CURLOPT_SSLENGINE: /* * String that holds the SSL crypto engine. @@ -1776,14 +1776,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE; break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_HAPROXYPROTOCOL: /* * Set to send the HAProxy Proxy Protocol header */ data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE; break; -#endif +#endif case CURLOPT_INTERFACE: /* * Set what interface or address/hostname to bind the socket to when @@ -1827,12 +1827,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) TRUE : FALSE; /* Update the current connection ssl_config. */ - if(data->conn) { - data->conn->ssl_config.verifypeer = + if(data->conn) { + data->conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer; } break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_VERIFYPEER: /* * Enable peer SSL verifying for proxy. @@ -1841,12 +1841,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) (0 != va_arg(param, long))?TRUE:FALSE; /* Update the current connection proxy_ssl_config. */ - if(data->conn) { - data->conn->proxy_ssl_config.verifypeer = + if(data->conn) { + data->conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer; } break; -#endif +#endif case CURLOPT_SSL_VERIFYHOST: /* * Enable verification of the host name in the peer certificate @@ -1854,33 +1854,33 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) arg = va_arg(param, long); /* Obviously people are not reading documentation and too many thought - this argument took a boolean when it wasn't and misused it. - Treat 1 and 2 the same */ - data->set.ssl.primary.verifyhost = (bool)((arg & 3) ? TRUE : FALSE); + this argument took a boolean when it wasn't and misused it. + Treat 1 and 2 the same */ + data->set.ssl.primary.verifyhost = (bool)((arg & 3) ? TRUE : FALSE); /* Update the current connection ssl_config. */ - if(data->conn) { - data->conn->ssl_config.verifyhost = + if(data->conn) { + data->conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost; } break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_VERIFYHOST: /* * Enable verification of the host name in the peer certificate for proxy */ arg = va_arg(param, long); - /* Treat both 1 and 2 as TRUE */ - data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE); + /* Treat both 1 and 2 as TRUE */ + data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE); /* Update the current connection proxy_ssl_config. */ - if(data->conn) { - data->conn->proxy_ssl_config.verifyhost = + if(data->conn) { + data->conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost; } break; -#endif +#endif case CURLOPT_SSL_VERIFYSTATUS: /* * Enable certificate status verifying. @@ -1894,8 +1894,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) TRUE : FALSE; /* Update the current connection ssl_config. */ - if(data->conn) { - data->conn->ssl_config.verifystatus = + if(data->conn) { + data->conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus; } break; @@ -1953,7 +1953,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif result = CURLE_NOT_BUILT_IN; break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_PINNEDPUBLICKEY: /* * Set pinned public key for SSL connection. @@ -1967,7 +1967,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif result = CURLE_NOT_BUILT_IN; break; -#endif +#endif case CURLOPT_CAINFO: /* * Set CA info for SSL connection. Specify file name of the CA certificate @@ -1975,7 +1975,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG], va_arg(param, char *)); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_CAINFO: /* * Set CA info SSL connection for proxy. Specify file name of the @@ -1984,7 +1984,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY], va_arg(param, char *)); break; -#endif +#endif case CURLOPT_CAPATH: /* * Set CA path info for SSL connection. Specify directory name of the CA @@ -1999,7 +1999,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif result = CURLE_NOT_BUILT_IN; break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_CAPATH: /* * Set CA path info for SSL connection proxy. Specify directory name of the @@ -2014,7 +2014,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif result = CURLE_NOT_BUILT_IN; break; -#endif +#endif case CURLOPT_CRLFILE: /* * Set CRL file info for SSL connection. Specify file name of the CRL @@ -2023,7 +2023,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG], va_arg(param, char *)); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_CRLFILE: /* * Set CRL file info for SSL connection for proxy. Specify file name of the @@ -2032,7 +2032,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY], va_arg(param, char *)); break; -#endif +#endif case CURLOPT_ISSUERCERT: /* * Set Issuer certificate file @@ -2065,14 +2065,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) va_arg(param, struct curl_blob *)); break; #endif -#ifndef CURL_DISABLE_TELNET +#ifndef CURL_DISABLE_TELNET case CURLOPT_TELNETOPTIONS: /* * Set a linked list of telnet options */ data->set.telnet_options = va_arg(param, struct curl_slist *); break; -#endif +#endif case CURLOPT_BUFFERSIZE: /* * The application kindly asks for a differently sized receive buffer. @@ -2217,26 +2217,26 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_SSL_OPTIONS: arg = va_arg(param, long); - data->set.ssl.enable_beast = - (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); + data->set.ssl.enable_beast = + (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT); data->set.ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA); break; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_OPTIONS: arg = va_arg(param, long); - data->set.proxy_ssl.enable_beast = - (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); + data->set.proxy_ssl.enable_beast = + (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA); data->set.proxy_ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT); break; -#endif +#endif case CURLOPT_SSL_EC_CURVES: /* @@ -2350,7 +2350,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif break; -#ifdef USE_SSH +#ifdef USE_SSH /* we only include SSH options if explicitly built to support SSH */ case CURLOPT_SSH_AUTH_TYPES: data->set.ssh_auth_types = va_arg(param, long); @@ -2379,7 +2379,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], va_arg(param, char *)); break; - + case CURLOPT_SSH_KNOWNHOSTS: /* * Store the file name to read known hosts from. @@ -2401,11 +2401,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.ssh_keyfunc_userp = va_arg(param, void *); break; - case CURLOPT_SSH_COMPRESSION: - data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE; - break; -#endif /* USE_SSH */ - + case CURLOPT_SSH_COMPRESSION: + data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE; + break; +#endif /* USE_SSH */ + case CURLOPT_HTTP_TRANSFER_DECODING: /* * disable libcurl transfer encoding is used @@ -2420,7 +2420,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; break; -#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) +#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) case CURLOPT_NEW_FILE_PERMS: /* * Uses these permissions instead of 0644 @@ -2440,20 +2440,20 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) return CURLE_BAD_FUNCTION_ARGUMENT; data->set.new_directory_perms = arg; break; -#endif +#endif case CURLOPT_ADDRESS_SCOPE: /* - * Use this scope id when using IPv6 - * We always get longs when passed plain numericals so we should check - * that the value fits into an unsigned 32 bit integer. + * Use this scope id when using IPv6 + * We always get longs when passed plain numericals so we should check + * that the value fits into an unsigned 32 bit integer. */ - uarg = va_arg(param, unsigned long); -#if SIZEOF_LONG > 4 - if(uarg > UINT_MAX) + uarg = va_arg(param, unsigned long); +#if SIZEOF_LONG > 4 + if(uarg > UINT_MAX) return CURLE_BAD_FUNCTION_ARGUMENT; -#endif - data->set.scope_id = (unsigned int)uarg; +#endif + data->set.scope_id = (unsigned int)uarg; break; case CURLOPT_PROTOCOLS: @@ -2467,7 +2467,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_REDIR_PROTOCOLS: /* set the bitmask for the protocols that libcurl is allowed to follow to, as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. */ + to be set in both bitmasks to be allowed to get redirected to. */ data->set.redir_protocols = va_arg(param, long); break; @@ -2476,7 +2476,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL], va_arg(param, char *)); break; -#ifndef CURL_DISABLE_SMTP +#ifndef CURL_DISABLE_SMTP case CURLOPT_MAIL_FROM: /* Set the SMTP mail originator */ result = Curl_setstropt(&data->set.str[STRING_MAIL_FROM], @@ -2497,19 +2497,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* allow RCPT TO command to fail for some recipients */ data->set.mail_rcpt_allowfails = (0 != va_arg(param, long)) ? TRUE : FALSE; break; -#endif +#endif + + case CURLOPT_SASL_AUTHZID: + /* Authorisation identity (identity to act as) */ + result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID], + va_arg(param, char *)); + break; - case CURLOPT_SASL_AUTHZID: - /* Authorisation identity (identity to act as) */ - result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID], - va_arg(param, char *)); - break; - case CURLOPT_SASL_IR: /* Enable/disable SASL initial response */ data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE; break; -#ifndef CURL_DISABLE_RTSP +#ifndef CURL_DISABLE_RTSP case CURLOPT_RTSP_REQUEST: { /* @@ -2618,8 +2618,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* Set the user defined RTP write function */ data->set.fwrite_rtp = va_arg(param, curl_write_callback); break; -#endif -#ifndef CURL_DISABLE_FTP +#endif +#ifndef CURL_DISABLE_FTP case CURLOPT_WILDCARDMATCH: data->set.wildcard_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE; break; @@ -2638,7 +2638,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_FNMATCH_DATA: data->set.fnmatch_data = va_arg(param, void *); break; -#endif +#endif #ifdef USE_TLS_SRP case CURLOPT_TLSAUTH_USERNAME: result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG], @@ -2689,7 +2689,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #endif #endif -#ifdef USE_ARES +#ifdef USE_ARES case CURLOPT_DNS_SERVERS: result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS], va_arg(param, char *)); @@ -2718,7 +2718,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) return result; result = Curl_set_dns_local_ip6(data, data->set.str[STRING_DNS_LOCAL_IP6]); break; -#endif +#endif case CURLOPT_TCP_KEEPALIVE: data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE; break; @@ -2804,44 +2804,44 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) return CURLE_BAD_FUNCTION_ARGUMENT; data->set.happy_eyeballs_timeout = arg; break; -#ifndef CURL_DISABLE_SHUFFLE_DNS +#ifndef CURL_DISABLE_SHUFFLE_DNS case CURLOPT_DNS_SHUFFLE_ADDRESSES: data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE; break; -#endif +#endif case CURLOPT_DISALLOW_USERNAME_IN_URL: data->set.disallow_username_in_url = (0 != va_arg(param, long)) ? TRUE : FALSE; break; -#ifndef CURL_DISABLE_DOH +#ifndef CURL_DISABLE_DOH case CURLOPT_DOH_URL: result = Curl_setstropt(&data->set.str[STRING_DOH], va_arg(param, char *)); data->set.doh = data->set.str[STRING_DOH]?TRUE:FALSE; break; -#endif +#endif case CURLOPT_UPKEEP_INTERVAL_MS: arg = va_arg(param, long); if(arg < 0) return CURLE_BAD_FUNCTION_ARGUMENT; data->set.upkeep_interval_ms = arg; break; - case CURLOPT_MAXAGE_CONN: - arg = va_arg(param, long); - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.maxage_conn = arg; - break; - case CURLOPT_TRAILERFUNCTION: -#ifndef CURL_DISABLE_HTTP - data->set.trailer_callback = va_arg(param, curl_trailer_callback); -#endif - break; - case CURLOPT_TRAILERDATA: -#ifndef CURL_DISABLE_HTTP - data->set.trailer_data = va_arg(param, void *); -#endif - break; + case CURLOPT_MAXAGE_CONN: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.maxage_conn = arg; + break; + case CURLOPT_TRAILERFUNCTION: +#ifndef CURL_DISABLE_HTTP + data->set.trailer_callback = va_arg(param, curl_trailer_callback); +#endif + break; + case CURLOPT_TRAILERDATA: +#ifndef CURL_DISABLE_HTTP + data->set.trailer_data = va_arg(param, void *); +#endif + break; #ifdef USE_HSTS case CURLOPT_HSTSREADFUNCTION: data->set.hsts_read = va_arg(param, curl_hstsread_callback); @@ -2882,31 +2882,31 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #endif #ifndef CURL_DISABLE_ALTSVC - case CURLOPT_ALTSVC: - if(!data->asi) { - data->asi = Curl_altsvc_init(); - if(!data->asi) - return CURLE_OUT_OF_MEMORY; - } - argptr = va_arg(param, char *); - result = Curl_setstropt(&data->set.str[STRING_ALTSVC], argptr); - if(result) - return result; + case CURLOPT_ALTSVC: + if(!data->asi) { + data->asi = Curl_altsvc_init(); + if(!data->asi) + return CURLE_OUT_OF_MEMORY; + } + argptr = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_ALTSVC], argptr); + if(result) + return result; if(argptr) (void)Curl_altsvc_load(data->asi, argptr); - break; - case CURLOPT_ALTSVC_CTRL: - if(!data->asi) { - data->asi = Curl_altsvc_init(); - if(!data->asi) - return CURLE_OUT_OF_MEMORY; - } - arg = va_arg(param, long); - result = Curl_altsvc_ctrl(data->asi, arg); - if(result) - return result; - break; -#endif + break; + case CURLOPT_ALTSVC_CTRL: + if(!data->asi) { + data->asi = Curl_altsvc_init(); + if(!data->asi) + return CURLE_OUT_OF_MEMORY; + } + arg = va_arg(param, long); + result = Curl_altsvc_ctrl(data->asi, arg); + if(result) + return result; + break; +#endif default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; diff --git a/contrib/libs/curl/lib/setopt.h b/contrib/libs/curl/lib/setopt.h index b7f324341b..affbfd9960 100644 --- a/contrib/libs/curl/lib/setopt.h +++ b/contrib/libs/curl/lib/setopt.h @@ -25,6 +25,6 @@ CURLcode Curl_setstropt(char **charp, const char *s); CURLcode Curl_setblobopt(struct curl_blob **blobp, const struct curl_blob *blob); -CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list arg); +CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list arg); #endif /* HEADER_CURL_SETOPT_H */ diff --git a/contrib/libs/curl/lib/sigpipe.h b/contrib/libs/curl/lib/sigpipe.h index d5def5feef..430cfc6489 100644 --- a/contrib/libs/curl/lib/sigpipe.h +++ b/contrib/libs/curl/lib/sigpipe.h @@ -23,8 +23,8 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && \ - (defined(USE_OPENSSL) || defined(USE_MBEDTLS)) +#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && \ + (defined(USE_OPENSSL) || defined(USE_MBEDTLS)) #include <signal.h> struct sigpipe_ignore { diff --git a/contrib/libs/curl/lib/smb.c b/contrib/libs/curl/lib/smb.c index fb82889a52..dd914a05bf 100644 --- a/contrib/libs/curl/lib/smb.c +++ b/contrib/libs/curl/lib/smb.c @@ -62,7 +62,7 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done); static CURLcode smb_done(struct connectdata *conn, CURLcode status, bool premature); static CURLcode smb_disconnect(struct connectdata *conn, bool dead); -static int smb_getsock(struct connectdata *conn, curl_socket_t *socks); +static int smb_getsock(struct connectdata *conn, curl_socket_t *socks); static CURLcode smb_parse_url_path(struct connectdata *conn); /* @@ -606,7 +606,7 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg) { struct smb_conn *smbc = &conn->proto.smbc; CURLcode result; - *msg = NULL; /* if it returns early */ + *msg = NULL; /* if it returns early */ /* Check if there is data in the transfer buffer */ if(!smbc->send_size && smbc->upload_size) { @@ -786,8 +786,8 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done) case SMB_OPEN: if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) { req->result = CURLE_REMOTE_FILE_NOT_FOUND; - if(h->status == smb_swap32(SMB_ERR_NOACCESS)) - req->result = CURLE_REMOTE_ACCESS_DENIED; + if(h->status == smb_swap32(SMB_ERR_NOACCESS)) + req->result = CURLE_REMOTE_ACCESS_DENIED; next_state = SMB_TREE_DISCONNECT; break; } @@ -937,7 +937,7 @@ static CURLcode smb_disconnect(struct connectdata *conn, bool dead) return CURLE_OK; } -static int smb_getsock(struct connectdata *conn, curl_socket_t *socks) +static int smb_getsock(struct connectdata *conn, curl_socket_t *socks) { socks[0] = conn->sock[FIRSTSOCKET]; return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0); @@ -949,7 +949,7 @@ static CURLcode smb_do(struct connectdata *conn, bool *done) *done = FALSE; if(smbc->share) { - return CURLE_OK; + return CURLE_OK; } return CURLE_URL_MALFORMAT; } @@ -963,7 +963,7 @@ static CURLcode smb_parse_url_path(struct connectdata *conn) char *slash; /* URL decode the path */ - CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &path, NULL, + CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &path, NULL, REJECT_CTRL); if(result) return result; @@ -987,7 +987,7 @@ static CURLcode smb_parse_url_path(struct connectdata *conn) /* Parse the path for the file path converting any forward slashes into backslashes */ *slash++ = 0; - req->path = slash; + req->path = slash; for(; *slash; slash++) { if(*slash == '/') diff --git a/contrib/libs/curl/lib/smtp.c b/contrib/libs/curl/lib/smtp.c index 0face5aa26..509d802f1c 100644 --- a/contrib/libs/curl/lib/smtp.c +++ b/contrib/libs/curl/lib/smtp.c @@ -31,7 +31,7 @@ * RFC6531 SMTP Extension for Internationalized Email * RFC6532 Internationalized Email Headers * RFC6749 OAuth 2.0 Authorization Framework - * RFC8314 Use of TLS for Email Submission and Access + * RFC8314 Use of TLS for Email Submission and Access * Draft SMTP URL Interface <draft-earhart-url-smtp-00.txt> * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt> * @@ -98,7 +98,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status, static CURLcode smtp_connect(struct connectdata *conn, bool *done); static CURLcode smtp_disconnect(struct connectdata *conn, bool dead); static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done); -static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks); +static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks); static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done); static CURLcode smtp_setup_connection(struct connectdata *conn); static CURLcode smtp_parse_url_options(struct connectdata *conn); @@ -214,12 +214,12 @@ static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len, Section 4. Examples of RFC-4954 but some e-mail servers ignore this and only send the response code instead as per Section 4.2. */ if(line[3] == ' ' || len == 5) { - char tmpline[6]; - + char tmpline[6]; + result = TRUE; - memset(tmpline, '\0', sizeof(tmpline)); - memcpy(tmpline, line, (len == 5 ? 5 : 3)); - *resp = curlx_sltosi(strtol(tmpline, NULL, 10)); + memset(tmpline, '\0', sizeof(tmpline)); + memcpy(tmpline, line, (len == 5 ? 5 : 3)); + *resp = curlx_sltosi(strtol(tmpline, NULL, 10)); /* Make sure real server never sends internal value */ if(*resp == 1) @@ -366,7 +366,7 @@ static CURLcode smtp_perform_helo(struct connectdata *conn) static CURLcode smtp_perform_starttls(struct connectdata *conn) { /* Send the STARTTLS command */ - CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS"); + CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS"); if(!result) state(conn, SMTP_STARTTLS); @@ -382,10 +382,10 @@ static CURLcode smtp_perform_starttls(struct connectdata *conn) */ static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn) { - /* Start the SSL connection */ + /* Start the SSL connection */ struct smtp_conn *smtpc = &conn->proto.smtpc; - CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, - &smtpc->ssldone); + CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, + &smtpc->ssldone); if(!result) { if(smtpc->state != SMTP_UPGRADETLS) @@ -781,7 +781,7 @@ static CURLcode smtp_perform_rcpt_to(struct connectdata *conn) static CURLcode smtp_perform_quit(struct connectdata *conn) { /* Send the QUIT command */ - CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT"); + CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT"); if(!result) state(conn, SMTP_QUIT); @@ -853,7 +853,7 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode, result = CURLE_REMOTE_ACCESS_DENIED; } } - else if(len >= 4) { + else if(len >= 4) { line += 4; len -= 4; @@ -928,10 +928,10 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode, result = smtp_perform_authentication(conn); } } - else { - failf(data, "Unexpectedly short EHLO response"); - result = CURLE_WEIRD_SERVER_REPLY; - } + else { + failf(data, "Unexpectedly short EHLO response"); + result = CURLE_WEIRD_SERVER_REPLY; + } return result; } @@ -1129,7 +1129,7 @@ static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode, Curl_pgrsSetUploadSize(data, data->state.infilesize); /* SMTP upload */ - Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); /* End of DO phase */ state(conn, SMTP_STOP); @@ -1254,20 +1254,20 @@ static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done) return result; } - result = Curl_pp_statemach(&smtpc->pp, FALSE, FALSE); + result = Curl_pp_statemach(&smtpc->pp, FALSE, FALSE); *done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE; return result; } -static CURLcode smtp_block_statemach(struct connectdata *conn, - bool disconnecting) +static CURLcode smtp_block_statemach(struct connectdata *conn, + bool disconnecting) { CURLcode result = CURLE_OK; struct smtp_conn *smtpc = &conn->proto.smtpc; while(smtpc->state != SMTP_STOP && !result) - result = Curl_pp_statemach(&smtpc->pp, TRUE, disconnecting); + result = Curl_pp_statemach(&smtpc->pp, TRUE, disconnecting); return result; } @@ -1288,9 +1288,9 @@ static CURLcode smtp_init(struct connectdata *conn) } /* For the SMTP "protocol connect" and "doing" phases only */ -static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks) +static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks) { - return Curl_pp_getsock(&conn->proto.smtpc.pp, socks); + return Curl_pp_getsock(&conn->proto.smtpc.pp, socks); } /*********************************************************************** @@ -1388,7 +1388,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status, returned CURLE_AGAIN, we duplicate the EOB now rather than when the bytes written doesn't equal len. */ if(smtp->trailing_crlf || !conn->data->state.infilesize) { - eob = strdup(&SMTP_EOB[2]); + eob = strdup(&SMTP_EOB[2]); len = SMTP_EOB_LEN - 2; } else { @@ -1422,8 +1422,8 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status, state(conn, SMTP_POSTDATA); - /* Run the state-machine */ - result = smtp_block_statemach(conn, FALSE); + /* Run the state-machine */ + result = smtp_block_statemach(conn, FALSE); } /* Clear the transfer mode for the next request */ @@ -1536,7 +1536,7 @@ static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection) point! */ if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart) if(!smtp_perform_quit(conn)) - (void)smtp_block_statemach(conn, TRUE); /* ignore errors on QUIT */ + (void)smtp_block_statemach(conn, TRUE); /* ignore errors on QUIT */ /* Disconnect from the server */ Curl_pp_disconnect(&smtpc->pp); @@ -1559,7 +1559,7 @@ static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected) if(smtp->transfer != FTPTRANSFER_BODY) /* no data to transfer */ - Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); return CURLE_OK; } diff --git a/contrib/libs/curl/lib/socks.c b/contrib/libs/curl/lib/socks.c index ec95c6e550..a2d1e621f9 100644 --- a/contrib/libs/curl/lib/socks.c +++ b/contrib/libs/curl/lib/socks.c @@ -57,7 +57,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */ ssize_t buffersize, /* max amount to read */ ssize_t *n) /* amount bytes read */ { - ssize_t nread = 0; + ssize_t nread = 0; ssize_t allread = 0; int result; *n = 0; @@ -682,24 +682,24 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, len = 0; socksreq[len++] = 1; /* username/pw subnegotiation version */ socksreq[len++] = (unsigned char) proxy_user_len; - if(proxy_user && proxy_user_len) { - /* the length must fit in a single byte */ - if(proxy_user_len >= 255) { - failf(data, "Excessive user name length for proxy auth"); + if(proxy_user && proxy_user_len) { + /* the length must fit in a single byte */ + if(proxy_user_len >= 255) { + failf(data, "Excessive user name length for proxy auth"); return CURLPX_LONG_USER; - } + } memcpy(socksreq + len, proxy_user, proxy_user_len); - } + } len += proxy_user_len; socksreq[len++] = (unsigned char) proxy_password_len; - if(proxy_password && proxy_password_len) { - /* the length must fit in a single byte */ - if(proxy_password_len > 255) { - failf(data, "Excessive password length for proxy auth"); + if(proxy_password && proxy_password_len) { + /* the length must fit in a single byte */ + if(proxy_password_len > 255) { + failf(data, "Excessive password length for proxy auth"); return CURLPX_LONG_PASSWD; - } + } memcpy(socksreq + len, proxy_password, proxy_password_len); - } + } len += proxy_password_len; sxstate(conn, CONNECT_AUTH_SEND); sx->outstanding = len; diff --git a/contrib/libs/curl/lib/socks_sspi.c b/contrib/libs/curl/lib/socks_sspi.c index b57e66bdbe..b9ac2ade8e 100644 --- a/contrib/libs/curl/lib/socks_sspi.c +++ b/contrib/libs/curl/lib/socks_sspi.c @@ -51,9 +51,9 @@ static int check_sspi_err(struct connectdata *conn, status != SEC_I_COMPLETE_AND_CONTINUE && status != SEC_I_COMPLETE_NEEDED && status != SEC_I_CONTINUE_NEEDED) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(conn->data, "SSPI error: %s failed: %s", function, - Curl_sspi_strerror(status, buffer, sizeof(buffer))); + Curl_sspi_strerror(status, buffer, sizeof(buffer))); return 1; } return 0; diff --git a/contrib/libs/curl/lib/splay.c b/contrib/libs/curl/lib/splay.c index 930b50007f..98baf5d871 100644 --- a/contrib/libs/curl/lib/splay.c +++ b/contrib/libs/curl/lib/splay.c @@ -198,7 +198,7 @@ struct Curl_tree *Curl_splaygetbest(struct curltime i, /* Deletes the very node we point out from the tree if it's there. Stores a * pointer to the new resulting tree in 'newroot'. * - * Returns zero on success and non-zero on errors! + * Returns zero on success and non-zero on errors! * When returning error, it does not touch the 'newroot' pointer. * * NOTE: when the last node of the tree is removed, there's no tree left so diff --git a/contrib/libs/curl/lib/strerror.c b/contrib/libs/curl/lib/strerror.c index b8aa0be50b..1751fd38f5 100644 --- a/contrib/libs/curl/lib/strerror.c +++ b/contrib/libs/curl/lib/strerror.c @@ -311,9 +311,9 @@ curl_easy_strerror(CURLcode error) case CURLE_RECURSIVE_API_CALL: return "API function called from within callback"; - case CURLE_AUTH_ERROR: - return "An authentication function returned an error"; - + case CURLE_AUTH_ERROR: + return "An authentication function returned an error"; + case CURLE_HTTP3: return "HTTP/3 error"; @@ -709,13 +709,13 @@ get_winapi_error(int err, char *buf, size_t buflen) * Call Curl_sspi_strerror if the error code is definitely Windows SSPI. * Call Curl_winapi_strerror if the error code is definitely Windows API. */ -const char *Curl_strerror(int err, char *buf, size_t buflen) +const char *Curl_strerror(int err, char *buf, size_t buflen) { #ifdef PRESERVE_WINDOWS_ERROR_CODE DWORD old_win_err = GetLastError(); #endif int old_errno = errno; - char *p; + char *p; size_t max; if(!buflen) @@ -723,7 +723,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) DEBUGASSERT(err >= 0); - max = buflen - 1; + max = buflen - 1; *buf = '\0'; #if defined(WIN32) || defined(_WIN32_WCE) @@ -858,7 +858,7 @@ const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen) * Curl_sspi_strerror: * Variant of Curl_strerror if the error code is definitely Windows SSPI. */ -const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) +const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) { #ifdef PRESERVE_WINDOWS_ERROR_CODE DWORD old_win_err = GetLastError(); diff --git a/contrib/libs/curl/lib/strerror.h b/contrib/libs/curl/lib/strerror.h index dda14a9a0e..96a7e27c51 100644 --- a/contrib/libs/curl/lib/strerror.h +++ b/contrib/libs/curl/lib/strerror.h @@ -26,12 +26,12 @@ #define STRERROR_LEN 256 /* a suitable length */ -const char *Curl_strerror(int err, char *buf, size_t buflen); +const char *Curl_strerror(int err, char *buf, size_t buflen); #if defined(WIN32) || defined(_WIN32_WCE) const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen); #endif #ifdef USE_WINDOWS_SSPI -const char *Curl_sspi_strerror(int err, char *buf, size_t buflen); +const char *Curl_sspi_strerror(int err, char *buf, size_t buflen); #endif #endif /* HEADER_CURL_STRERROR_H */ diff --git a/contrib/libs/curl/lib/system_win32.c b/contrib/libs/curl/lib/system_win32.c index 26e018025d..b377da7d8b 100644 --- a/contrib/libs/curl/lib/system_win32.c +++ b/contrib/libs/curl/lib/system_win32.c @@ -27,112 +27,112 @@ #include <curl/curl.h> #include "system_win32.h" #include "version_win32.h" -#include "curl_sspi.h" +#include "curl_sspi.h" #include "warnless.h" /* The last #include files should be: */ #include "curl_memory.h" #include "memdebug.h" -LARGE_INTEGER Curl_freq; -bool Curl_isVistaOrGreater; - -/* Handle of iphlpapp.dll */ -static HMODULE s_hIpHlpApiDll = NULL; - -/* Pointer to the if_nametoindex function */ -IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL; - -/* Curl_win32_init() performs win32 global initialization */ -CURLcode Curl_win32_init(long flags) -{ - /* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which - is just for Winsock at the moment. Any required win32 initialization - should take place after this block. */ - if(flags & CURL_GLOBAL_WIN32) { -#ifdef USE_WINSOCK - WORD wVersionRequested; - WSADATA wsaData; - int res; - +LARGE_INTEGER Curl_freq; +bool Curl_isVistaOrGreater; + +/* Handle of iphlpapp.dll */ +static HMODULE s_hIpHlpApiDll = NULL; + +/* Pointer to the if_nametoindex function */ +IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL; + +/* Curl_win32_init() performs win32 global initialization */ +CURLcode Curl_win32_init(long flags) +{ + /* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which + is just for Winsock at the moment. Any required win32 initialization + should take place after this block. */ + if(flags & CURL_GLOBAL_WIN32) { +#ifdef USE_WINSOCK + WORD wVersionRequested; + WSADATA wsaData; + int res; + wVersionRequested = MAKEWORD(2, 2); - res = WSAStartup(wVersionRequested, &wsaData); - - if(res != 0) - /* Tell the user that we couldn't find a usable */ - /* winsock.dll. */ - return CURLE_FAILED_INIT; - - /* Confirm that the Windows Sockets DLL supports what we need.*/ - /* Note that if the DLL supports versions greater */ - /* than wVersionRequested, it will still return */ - /* wVersionRequested in wVersion. wHighVersion contains the */ - /* highest supported version. */ - - if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || - HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { - /* Tell the user that we couldn't find a usable */ - - /* winsock.dll. */ - WSACleanup(); - return CURLE_FAILED_INIT; - } - /* The Windows Sockets DLL is acceptable. Proceed. */ + res = WSAStartup(wVersionRequested, &wsaData); + + if(res != 0) + /* Tell the user that we couldn't find a usable */ + /* winsock.dll. */ + return CURLE_FAILED_INIT; + + /* Confirm that the Windows Sockets DLL supports what we need.*/ + /* Note that if the DLL supports versions greater */ + /* than wVersionRequested, it will still return */ + /* wVersionRequested in wVersion. wHighVersion contains the */ + /* highest supported version. */ + + if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || + HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { + /* Tell the user that we couldn't find a usable */ + + /* winsock.dll. */ + WSACleanup(); + return CURLE_FAILED_INIT; + } + /* The Windows Sockets DLL is acceptable. Proceed. */ #elif defined(USE_LWIPSOCK) - lwip_init(); + lwip_init(); +#endif + } /* CURL_GLOBAL_WIN32 */ + +#ifdef USE_WINDOWS_SSPI + { + CURLcode result = Curl_sspi_global_init(); + if(result) + return result; + } #endif - } /* CURL_GLOBAL_WIN32 */ - -#ifdef USE_WINDOWS_SSPI - { - CURLcode result = Curl_sspi_global_init(); - if(result) - return result; - } -#endif - - s_hIpHlpApiDll = Curl_load_library(TEXT("iphlpapi.dll")); - if(s_hIpHlpApiDll) { - /* Get the address of the if_nametoindex function */ - IF_NAMETOINDEX_FN pIfNameToIndex = - CURLX_FUNCTION_CAST(IF_NAMETOINDEX_FN, - (GetProcAddress(s_hIpHlpApiDll, "if_nametoindex"))); - - if(pIfNameToIndex) - Curl_if_nametoindex = pIfNameToIndex; - } - + + s_hIpHlpApiDll = Curl_load_library(TEXT("iphlpapi.dll")); + if(s_hIpHlpApiDll) { + /* Get the address of the if_nametoindex function */ + IF_NAMETOINDEX_FN pIfNameToIndex = + CURLX_FUNCTION_CAST(IF_NAMETOINDEX_FN, + (GetProcAddress(s_hIpHlpApiDll, "if_nametoindex"))); + + if(pIfNameToIndex) + Curl_if_nametoindex = pIfNameToIndex; + } + if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT, VERSION_GREATER_THAN_EQUAL)) { - Curl_isVistaOrGreater = TRUE; - } - else - Curl_isVistaOrGreater = FALSE; - + Curl_isVistaOrGreater = TRUE; + } + else + Curl_isVistaOrGreater = FALSE; + QueryPerformanceFrequency(&Curl_freq); - return CURLE_OK; -} - -/* Curl_win32_cleanup() is the opposite of Curl_win32_init() */ -void Curl_win32_cleanup(long init_flags) -{ - if(s_hIpHlpApiDll) { - FreeLibrary(s_hIpHlpApiDll); - s_hIpHlpApiDll = NULL; - Curl_if_nametoindex = NULL; - } - -#ifdef USE_WINDOWS_SSPI - Curl_sspi_global_cleanup(); -#endif - - if(init_flags & CURL_GLOBAL_WIN32) { -#ifdef USE_WINSOCK - WSACleanup(); -#endif - } -} - + return CURLE_OK; +} + +/* Curl_win32_cleanup() is the opposite of Curl_win32_init() */ +void Curl_win32_cleanup(long init_flags) +{ + if(s_hIpHlpApiDll) { + FreeLibrary(s_hIpHlpApiDll); + s_hIpHlpApiDll = NULL; + Curl_if_nametoindex = NULL; + } + +#ifdef USE_WINDOWS_SSPI + Curl_sspi_global_cleanup(); +#endif + + if(init_flags & CURL_GLOBAL_WIN32) { +#ifdef USE_WINSOCK + WSACleanup(); +#endif + } +} + #if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 #endif @@ -171,7 +171,7 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); */ HMODULE Curl_load_library(LPCTSTR filename) { -#ifndef CURL_WINDOWS_APP +#ifndef CURL_WINDOWS_APP HMODULE hModule = NULL; LOADLIBRARYEX_FN pLoadLibraryEx = NULL; @@ -227,11 +227,11 @@ HMODULE Curl_load_library(LPCTSTR filename) } } return hModule; -#else - /* the Universal Windows Platform (UWP) can't do this */ - (void)filename; - return NULL; -#endif +#else + /* the Universal Windows Platform (UWP) can't do this */ + (void)filename; + return NULL; +#endif } #endif /* WIN32 */ diff --git a/contrib/libs/curl/lib/system_win32.h b/contrib/libs/curl/lib/system_win32.h index 5899570ae7..69e0c812c0 100644 --- a/contrib/libs/curl/lib/system_win32.h +++ b/contrib/libs/curl/lib/system_win32.h @@ -26,18 +26,18 @@ #if defined(WIN32) -extern LARGE_INTEGER Curl_freq; -extern bool Curl_isVistaOrGreater; - -CURLcode Curl_win32_init(long flags); -void Curl_win32_cleanup(long init_flags); - -/* We use our own typedef here since some headers might lack this */ -typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *); - -/* This is used instead of if_nametoindex if available on Windows */ -extern IF_NAMETOINDEX_FN Curl_if_nametoindex; - +extern LARGE_INTEGER Curl_freq; +extern bool Curl_isVistaOrGreater; + +CURLcode Curl_win32_init(long flags); +void Curl_win32_cleanup(long init_flags); + +/* We use our own typedef here since some headers might lack this */ +typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *); + +/* This is used instead of if_nametoindex if available on Windows */ +extern IF_NAMETOINDEX_FN Curl_if_nametoindex; + /* This is used to dynamically load DLLs */ HMODULE Curl_load_library(LPCTSTR filename); diff --git a/contrib/libs/curl/lib/telnet.c b/contrib/libs/curl/lib/telnet.c index 1bb9927847..8bf64a9f2b 100644 --- a/contrib/libs/curl/lib/telnet.c +++ b/contrib/libs/curl/lib/telnet.c @@ -1580,7 +1580,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) } #endif /* mark this as "no further transfer wanted" */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); return result; } diff --git a/contrib/libs/curl/lib/tftp.c b/contrib/libs/curl/lib/tftp.c index fe1f66a9d5..fba3f5e8c2 100644 --- a/contrib/libs/curl/lib/tftp.c +++ b/contrib/libs/curl/lib/tftp.c @@ -157,7 +157,7 @@ static CURLcode tftp_done(struct connectdata *conn, static CURLcode tftp_setup_connection(struct connectdata *conn); static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done); static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done); -static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks); +static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks); static CURLcode tftp_translate_code(tftp_error_t error); @@ -405,13 +405,13 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state, } static CURLcode tftp_option_add(struct tftp_state_data *state, size_t *csize, - char *buf, const char *option) + char *buf, const char *option) { - if(( strlen(option) + *csize + 1) > (size_t)state->blksize) - return CURLE_TFTP_ILLEGAL; + if(( strlen(option) + *csize + 1) > (size_t)state->blksize) + return CURLE_TFTP_ILLEGAL; strcpy(buf, option); - *csize += strlen(option) + 1; - return CURLE_OK; + *csize += strlen(option) + 1; + return CURLE_OK; } static CURLcode tftp_connect_for_tx(struct tftp_state_data *state, @@ -513,38 +513,38 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, else strcpy(buf, "0"); /* the destination is large enough */ - result = tftp_option_add(state, &sbytes, - (char *)state->spacket.data + sbytes, - TFTP_OPTION_TSIZE); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, - (char *)state->spacket.data + sbytes, buf); - + result = tftp_option_add(state, &sbytes, + (char *)state->spacket.data + sbytes, + TFTP_OPTION_TSIZE); + if(result == CURLE_OK) + result = tftp_option_add(state, &sbytes, + (char *)state->spacket.data + sbytes, buf); + /* add blksize option */ msnprintf(buf, sizeof(buf), "%d", state->requested_blksize); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, - (char *)state->spacket.data + sbytes, - TFTP_OPTION_BLKSIZE); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, - (char *)state->spacket.data + sbytes, buf); + if(result == CURLE_OK) + result = tftp_option_add(state, &sbytes, + (char *)state->spacket.data + sbytes, + TFTP_OPTION_BLKSIZE); + if(result == CURLE_OK) + result = tftp_option_add(state, &sbytes, + (char *)state->spacket.data + sbytes, buf); /* add timeout option */ msnprintf(buf, sizeof(buf), "%d", state->retry_time); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, - (char *)state->spacket.data + sbytes, - TFTP_OPTION_INTERVAL); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, - (char *)state->spacket.data + sbytes, buf); - - if(result != CURLE_OK) { - failf(data, "TFTP buffer too small for options"); - free(filename); - return CURLE_TFTP_ILLEGAL; - } + if(result == CURLE_OK) + result = tftp_option_add(state, &sbytes, + (char *)state->spacket.data + sbytes, + TFTP_OPTION_INTERVAL); + if(result == CURLE_OK) + result = tftp_option_add(state, &sbytes, + (char *)state->spacket.data + sbytes, buf); + + if(result != CURLE_OK) { + failf(data, "TFTP buffer too small for options"); + free(filename); + return CURLE_TFTP_ILLEGAL; + } } /* the typecase for the 3rd argument is mostly for systems that do @@ -554,8 +554,8 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, state->conn->ip_addr->ai_addr, state->conn->ip_addr->ai_addrlen); if(senddata != (ssize_t)sbytes) { - char buffer[STRERROR_LEN]; - failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + char buffer[STRERROR_LEN]; + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); } free(filename); break; @@ -606,7 +606,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state, ssize_t sbytes; int rblock; struct Curl_easy *data = state->conn->data; - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; switch(event) { @@ -639,7 +639,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state, (struct sockaddr *)&state->remote_addr, state->remote_addrlen); if(sbytes < 0) { - failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } @@ -664,7 +664,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state, (struct sockaddr *)&state->remote_addr, state->remote_addrlen); if(sbytes < 0) { - failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } @@ -690,7 +690,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state, (struct sockaddr *)&state->remote_addr, state->remote_addrlen); if(sbytes<0) { - failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } } @@ -730,7 +730,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) CURLcode result = CURLE_OK; struct SingleRequest *k = &data->req; size_t cb; /* Bytes currently read */ - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; switch(event) { @@ -765,8 +765,8 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) state->remote_addrlen); /* Check all sbytes were sent */ if(sbytes<0) { - failf(data, "%s", Curl_strerror(SOCKERRNO, - buffer, sizeof(buffer))); + failf(data, "%s", Curl_strerror(SOCKERRNO, + buffer, sizeof(buffer))); result = CURLE_SEND_ERROR; } } @@ -810,7 +810,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) state->remote_addrlen); /* Check all sbytes were sent */ if(sbytes<0) { - failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } /* Update the progress meter */ @@ -836,7 +836,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) state->remote_addrlen); /* Check all sbytes were sent */ if(sbytes<0) { - failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_SEND_ERROR; } /* since this was a re-send, we remain at the still byte position */ @@ -988,7 +988,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) { struct tftp_state_data *state; int blksize; - int need_blksize; + int need_blksize; blksize = TFTP_BLKSIZE_DEFAULT; @@ -1003,20 +1003,20 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) return CURLE_TFTP_ILLEGAL; } - need_blksize = blksize; - /* default size is the fallback when no OACK is received */ - if(need_blksize < TFTP_BLKSIZE_DEFAULT) - need_blksize = TFTP_BLKSIZE_DEFAULT; - + need_blksize = blksize; + /* default size is the fallback when no OACK is received */ + if(need_blksize < TFTP_BLKSIZE_DEFAULT) + need_blksize = TFTP_BLKSIZE_DEFAULT; + if(!state->rpacket.data) { - state->rpacket.data = calloc(1, need_blksize + 2 + 2); + state->rpacket.data = calloc(1, need_blksize + 2 + 2); if(!state->rpacket.data) return CURLE_OUT_OF_MEMORY; } if(!state->spacket.data) { - state->spacket.data = calloc(1, need_blksize + 2 + 2); + state->spacket.data = calloc(1, need_blksize + 2 + 2); if(!state->spacket.data) return CURLE_OUT_OF_MEMORY; @@ -1030,7 +1030,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) state->sockfd = state->conn->sock[FIRSTSOCKET]; state->state = TFTP_STATE_START; state->error = TFTP_ERR_NONE; - state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */ + state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */ state->requested_blksize = blksize; ((struct sockaddr *)&state->local_addr)->sa_family = @@ -1055,9 +1055,9 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr, conn->ip_addr->ai_addrlen); if(rc) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(conn->data, "bind() failed; %s", - Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); return CURLE_COULDNT_CONNECT; } conn->bits.bound = TRUE; @@ -1103,7 +1103,7 @@ static CURLcode tftp_done(struct connectdata *conn, CURLcode status, * The getsock callback * **********************************************************/ -static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks) +static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks) { socks[0] = conn->sock[FIRSTSOCKET]; return GETSOCK_READSOCK(0); @@ -1263,7 +1263,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done) *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE; if(*done) /* Tell curl we're done */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); } else { /* no timeouts to handle, check our socket */ @@ -1272,8 +1272,8 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done) if(rc == -1) { /* bail out */ int error = SOCKERRNO; - char buffer[STRERROR_LEN]; - failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer))); + char buffer[STRERROR_LEN]; + failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer))); state->event = TFTP_EVENT_ERROR; } else if(rc != 0) { @@ -1286,7 +1286,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done) *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE; if(*done) /* Tell curl we're done */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); } /* if rc == 0, then select() timed out */ } @@ -1392,7 +1392,7 @@ static CURLcode tftp_setup_connection(struct connectdata *conn) struct Curl_easy *data = conn->data; char *type; - conn->transport = TRNSPRT_UDP; + conn->transport = TRNSPRT_UDP; /* TFTP URLs support an extension like ";mode=<typecode>" that * we'll try to get now! */ diff --git a/contrib/libs/curl/lib/timeval.c b/contrib/libs/curl/lib/timeval.c index 61f7810da5..8523dad400 100644 --- a/contrib/libs/curl/lib/timeval.c +++ b/contrib/libs/curl/lib/timeval.c @@ -24,35 +24,35 @@ #if defined(WIN32) && !defined(MSDOS) -/* set in win32_init() */ -extern LARGE_INTEGER Curl_freq; -extern bool Curl_isVistaOrGreater; - +/* set in win32_init() */ +extern LARGE_INTEGER Curl_freq; +extern bool Curl_isVistaOrGreater; + /* In case of bug fix this function has a counterpart in tool_util.c */ struct curltime Curl_now(void) { struct curltime now; - if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */ - LARGE_INTEGER count; - QueryPerformanceCounter(&count); - now.tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart); - now.tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 / - Curl_freq.QuadPart); - } - else { - /* Disable /analyze warning that GetTickCount64 is preferred */ -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:28159) + if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */ + LARGE_INTEGER count; + QueryPerformanceCounter(&count); + now.tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart); + now.tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 / + Curl_freq.QuadPart); + } + else { + /* Disable /analyze warning that GetTickCount64 is preferred */ +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:28159) +#endif + DWORD milliseconds = GetTickCount(); +#if defined(_MSC_VER) +#pragma warning(pop) #endif - DWORD milliseconds = GetTickCount(); -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - - now.tv_sec = milliseconds / 1000; - now.tv_usec = (milliseconds % 1000) * 1000; - } + + now.tv_sec = milliseconds / 1000; + now.tv_usec = (milliseconds % 1000) * 1000; + } return now; } @@ -67,9 +67,9 @@ struct curltime Curl_now(void) ** in any case the time starting point does not change once that the ** system has started up. */ -#ifdef HAVE_GETTIMEOFDAY +#ifdef HAVE_GETTIMEOFDAY struct timeval now; -#endif +#endif struct curltime cnow; struct timespec tsnow; @@ -183,11 +183,11 @@ struct curltime Curl_now(void) */ timediff_t Curl_timediff(struct curltime newer, struct curltime older) { - timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec; - if(diff >= (TIMEDIFF_T_MAX/1000)) - return TIMEDIFF_T_MAX; - else if(diff <= (TIMEDIFF_T_MIN/1000)) - return TIMEDIFF_T_MIN; + timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec; + if(diff >= (TIMEDIFF_T_MAX/1000)) + return TIMEDIFF_T_MAX; + else if(diff <= (TIMEDIFF_T_MIN/1000)) + return TIMEDIFF_T_MIN; return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000; } @@ -197,10 +197,10 @@ timediff_t Curl_timediff(struct curltime newer, struct curltime older) */ timediff_t Curl_timediff_us(struct curltime newer, struct curltime older) { - timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec; - if(diff >= (TIMEDIFF_T_MAX/1000000)) - return TIMEDIFF_T_MAX; - else if(diff <= (TIMEDIFF_T_MIN/1000000)) - return TIMEDIFF_T_MIN; + timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec; + if(diff >= (TIMEDIFF_T_MAX/1000000)) + return TIMEDIFF_T_MAX; + else if(diff <= (TIMEDIFF_T_MIN/1000000)) + return TIMEDIFF_T_MIN; return diff * 1000000 + newer.tv_usec-older.tv_usec; } diff --git a/contrib/libs/curl/lib/timeval.h b/contrib/libs/curl/lib/timeval.h index 8f73ad963b..685e72961d 100644 --- a/contrib/libs/curl/lib/timeval.h +++ b/contrib/libs/curl/lib/timeval.h @@ -24,14 +24,14 @@ #include "curl_setup.h" -/* Use a larger type even for 32 bit time_t systems so that we can keep - microsecond accuracy in it */ +/* Use a larger type even for 32 bit time_t systems so that we can keep + microsecond accuracy in it */ typedef curl_off_t timediff_t; -#define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T +#define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T + +#define TIMEDIFF_T_MAX CURL_OFF_T_MAX +#define TIMEDIFF_T_MIN CURL_OFF_T_MIN -#define TIMEDIFF_T_MAX CURL_OFF_T_MAX -#define TIMEDIFF_T_MIN CURL_OFF_T_MIN - struct curltime { time_t tv_sec; /* seconds */ int tv_usec; /* microseconds */ diff --git a/contrib/libs/curl/lib/transfer.c b/contrib/libs/curl/lib/transfer.c index 2f0b68edef..bfd0218fef 100644 --- a/contrib/libs/curl/lib/transfer.c +++ b/contrib/libs/curl/lib/transfer.c @@ -120,37 +120,37 @@ CURLcode Curl_get_upload_buffer(struct Curl_easy *data) return CURLE_OK; } -#ifndef CURL_DISABLE_HTTP +#ifndef CURL_DISABLE_HTTP /* - * This function will be called to loop through the trailers buffer - * until no more data is available for sending. - */ -static size_t Curl_trailers_read(char *buffer, size_t size, size_t nitems, - void *raw) -{ - struct Curl_easy *data = (struct Curl_easy *)raw; + * This function will be called to loop through the trailers buffer + * until no more data is available for sending. + */ +static size_t Curl_trailers_read(char *buffer, size_t size, size_t nitems, + void *raw) +{ + struct Curl_easy *data = (struct Curl_easy *)raw; struct dynbuf *trailers_buf = &data->state.trailers_buf; size_t bytes_left = Curl_dyn_len(trailers_buf) - data->state.trailers_bytes_sent; - size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left; - if(to_copy) { - memcpy(buffer, + size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left; + if(to_copy) { + memcpy(buffer, Curl_dyn_ptr(trailers_buf) + data->state.trailers_bytes_sent, - to_copy); - data->state.trailers_bytes_sent += to_copy; - } - return to_copy; -} - -static size_t Curl_trailers_left(void *raw) -{ - struct Curl_easy *data = (struct Curl_easy *)raw; + to_copy); + data->state.trailers_bytes_sent += to_copy; + } + return to_copy; +} + +static size_t Curl_trailers_left(void *raw) +{ + struct Curl_easy *data = (struct Curl_easy *)raw; struct dynbuf *trailers_buf = &data->state.trailers_buf; return Curl_dyn_len(trailers_buf) - data->state.trailers_bytes_sent; -} -#endif - -/* +} +#endif + +/* * This function will call the read callback to fill our buffer with data * to upload. */ @@ -160,10 +160,10 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, struct Curl_easy *data = conn->data; size_t buffersize = bytes; size_t nread; - - curl_read_callback readfunc = NULL; - void *extra_data = NULL; - + + curl_read_callback readfunc = NULL; + void *extra_data = NULL; + #ifdef CURL_DOES_CONVERSIONS bool sending_http_headers = FALSE; @@ -177,73 +177,73 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, } #endif -#ifndef CURL_DISABLE_HTTP - if(data->state.trailers_state == TRAILERS_INITIALIZED) { - struct curl_slist *trailers = NULL; - CURLcode result; - int trailers_ret_code; - - /* at this point we already verified that the callback exists - so we compile and store the trailers buffer, then proceed */ - infof(data, - "Moving trailers state machine from initialized to sending.\n"); - data->state.trailers_state = TRAILERS_SENDING; +#ifndef CURL_DISABLE_HTTP + if(data->state.trailers_state == TRAILERS_INITIALIZED) { + struct curl_slist *trailers = NULL; + CURLcode result; + int trailers_ret_code; + + /* at this point we already verified that the callback exists + so we compile and store the trailers buffer, then proceed */ + infof(data, + "Moving trailers state machine from initialized to sending.\n"); + data->state.trailers_state = TRAILERS_SENDING; Curl_dyn_init(&data->state.trailers_buf, DYN_TRAILERS); - data->state.trailers_bytes_sent = 0; - Curl_set_in_callback(data, true); - trailers_ret_code = data->set.trailer_callback(&trailers, - data->set.trailer_data); - Curl_set_in_callback(data, false); - if(trailers_ret_code == CURL_TRAILERFUNC_OK) { - result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf, - data); - } - else { - failf(data, "operation aborted by trailing headers callback"); - *nreadp = 0; - result = CURLE_ABORTED_BY_CALLBACK; - } - if(result) { + data->state.trailers_bytes_sent = 0; + Curl_set_in_callback(data, true); + trailers_ret_code = data->set.trailer_callback(&trailers, + data->set.trailer_data); + Curl_set_in_callback(data, false); + if(trailers_ret_code == CURL_TRAILERFUNC_OK) { + result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf, + data); + } + else { + failf(data, "operation aborted by trailing headers callback"); + *nreadp = 0; + result = CURLE_ABORTED_BY_CALLBACK; + } + if(result) { Curl_dyn_free(&data->state.trailers_buf); - curl_slist_free_all(trailers); - return result; - } - infof(data, "Successfully compiled trailers.\r\n"); - curl_slist_free_all(trailers); - } -#endif - - /* if we are transmitting trailing data, we don't need to write - a chunk size so we skip this */ - if(data->req.upload_chunky && - data->state.trailers_state == TRAILERS_NONE) { + curl_slist_free_all(trailers); + return result; + } + infof(data, "Successfully compiled trailers.\r\n"); + curl_slist_free_all(trailers); + } +#endif + + /* if we are transmitting trailing data, we don't need to write + a chunk size so we skip this */ + if(data->req.upload_chunky && + data->state.trailers_state == TRAILERS_NONE) { /* if chunked Transfer-Encoding */ buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */ data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */ } -#ifndef CURL_DISABLE_HTTP - if(data->state.trailers_state == TRAILERS_SENDING) { - /* if we're here then that means that we already sent the last empty chunk - but we didn't send a final CR LF, so we sent 0 CR LF. We then start - pulling trailing data until we have no more at which point we - simply return to the previous point in the state machine as if - nothing happened. - */ - readfunc = Curl_trailers_read; - extra_data = (void *)data; - } - else -#endif - { - readfunc = data->state.fread_func; - extra_data = data->state.in; - } - +#ifndef CURL_DISABLE_HTTP + if(data->state.trailers_state == TRAILERS_SENDING) { + /* if we're here then that means that we already sent the last empty chunk + but we didn't send a final CR LF, so we sent 0 CR LF. We then start + pulling trailing data until we have no more at which point we + simply return to the previous point in the state machine as if + nothing happened. + */ + readfunc = Curl_trailers_read; + extra_data = (void *)data; + } + else +#endif + { + readfunc = data->state.fread_func; + extra_data = data->state.in; + } + Curl_set_in_callback(data, true); - nread = readfunc(data->req.upload_fromhere, 1, - buffersize, extra_data); + nread = readfunc(data->req.upload_fromhere, 1, + buffersize, extra_data); Curl_set_in_callback(data, false); if(nread == CURL_READFUNC_ABORT) { @@ -295,8 +295,8 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, here, knowing they'll become CRLFs later on. */ - bool added_crlf = FALSE; - int hexlen = 0; + bool added_crlf = FALSE; + int hexlen = 0; const char *endofline_native; const char *endofline_network; @@ -314,37 +314,37 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, endofline_network = "\x0d\x0a"; } - /* if we're not handling trailing data, proceed as usual */ - if(data->state.trailers_state != TRAILERS_SENDING) { - char hexbuffer[11] = ""; - hexlen = msnprintf(hexbuffer, sizeof(hexbuffer), - "%zx%s", nread, endofline_native); - - /* move buffer pointer */ - data->req.upload_fromhere -= hexlen; - nread += hexlen; - - /* copy the prefix to the buffer, leaving out the NUL */ - memcpy(data->req.upload_fromhere, hexbuffer, hexlen); - - /* always append ASCII CRLF to the data unless - we have a valid trailer callback */ -#ifndef CURL_DISABLE_HTTP - if((nread-hexlen) == 0 && - data->set.trailer_callback != NULL && - data->state.trailers_state == TRAILERS_NONE) { - data->state.trailers_state = TRAILERS_INITIALIZED; - } - else -#endif - { - memcpy(data->req.upload_fromhere + nread, - endofline_network, - strlen(endofline_network)); - added_crlf = TRUE; - } - } - + /* if we're not handling trailing data, proceed as usual */ + if(data->state.trailers_state != TRAILERS_SENDING) { + char hexbuffer[11] = ""; + hexlen = msnprintf(hexbuffer, sizeof(hexbuffer), + "%zx%s", nread, endofline_native); + + /* move buffer pointer */ + data->req.upload_fromhere -= hexlen; + nread += hexlen; + + /* copy the prefix to the buffer, leaving out the NUL */ + memcpy(data->req.upload_fromhere, hexbuffer, hexlen); + + /* always append ASCII CRLF to the data unless + we have a valid trailer callback */ +#ifndef CURL_DISABLE_HTTP + if((nread-hexlen) == 0 && + data->set.trailer_callback != NULL && + data->state.trailers_state == TRAILERS_NONE) { + data->state.trailers_state = TRAILERS_INITIALIZED; + } + else +#endif + { + memcpy(data->req.upload_fromhere + nread, + endofline_network, + strlen(endofline_network)); + added_crlf = TRUE; + } + } + #ifdef CURL_DOES_CONVERSIONS { CURLcode result; @@ -354,40 +354,40 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, length = nread; else /* just translate the protocol portion */ - length = hexlen; - if(length) { - result = Curl_convert_to_network(data, data->req.upload_fromhere, - length); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) - return result; - } + length = hexlen; + if(length) { + result = Curl_convert_to_network(data, data->req.upload_fromhere, + length); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) + return result; + } } #endif /* CURL_DOES_CONVERSIONS */ -#ifndef CURL_DISABLE_HTTP - if(data->state.trailers_state == TRAILERS_SENDING && - !Curl_trailers_left(data)) { +#ifndef CURL_DISABLE_HTTP + if(data->state.trailers_state == TRAILERS_SENDING && + !Curl_trailers_left(data)) { Curl_dyn_free(&data->state.trailers_buf); - data->state.trailers_state = TRAILERS_DONE; - data->set.trailer_data = NULL; - data->set.trailer_callback = NULL; - /* mark the transfer as done */ + data->state.trailers_state = TRAILERS_DONE; + data->set.trailer_data = NULL; + data->set.trailer_callback = NULL; + /* mark the transfer as done */ data->req.upload_done = TRUE; - infof(data, "Signaling end of chunked upload after trailers.\n"); + infof(data, "Signaling end of chunked upload after trailers.\n"); } - else -#endif - if((nread - hexlen) == 0 && - data->state.trailers_state != TRAILERS_INITIALIZED) { - /* mark this as done once this chunk is transferred */ - data->req.upload_done = TRUE; - infof(data, - "Signaling end of chunked upload via terminating chunk.\n"); - } - - if(added_crlf) - nread += strlen(endofline_network); /* for the added end of line */ + else +#endif + if((nread - hexlen) == 0 && + data->state.trailers_state != TRAILERS_INITIALIZED) { + /* mark this as done once this chunk is transferred */ + data->req.upload_done = TRUE; + infof(data, + "Signaling end of chunked upload via terminating chunk.\n"); + } + + if(added_crlf) + nread += strlen(endofline_network); /* for the added end of line */ } #ifdef CURL_DOES_CONVERSIONS else if((data->set.prefer_ascii) && (!sending_http_headers)) { @@ -506,7 +506,7 @@ static int data_pending(const struct Curl_easy *data) TRUE. The thing is if we read everything, then http2_recv won't be called and we cannot signal the HTTP/2 stream has closed. As a workaround, we return nonzero here to call http2_recv. */ - ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20); + ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20); #else Curl_ssl_data_pending(conn, FIRSTSOCKET); #endif @@ -591,7 +591,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, !is_http2 && #endif k->size != -1 && !k->header) { - /* make sure we don't read too much */ + /* make sure we don't read too much */ curl_off_t totalleft = k->size - k->bytecount; if(totalleft < (curl_off_t)bytestoread) bytestoread = (size_t)totalleft; @@ -615,7 +615,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, nread = 0; } - if(!k->bytecount) { + if(!k->bytecount) { Curl_pgrsTime(data, TIMER_STARTTRANSFER); if(k->exp100 > EXP100_SEND_DATA) /* set time stamp to compare with when waiting for the 100 */ @@ -629,7 +629,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, if(0 < nread || is_empty_data) { buf[nread] = 0; } - else { + else { /* if we receive 0 or less here, either the http2 stream is closed or the server closed the connection and we bail out from this! */ #ifdef USE_NGHTTP2 @@ -677,11 +677,11 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* We've stopped dealing with input, get out of the do-while loop */ if(nread > 0) { - infof(data, - "Excess found:" - " excess = %zd" - " url = %s (zero-length body)\n", - nread, data->state.up.path); + infof(data, + "Excess found:" + " excess = %zd" + " url = %s (zero-length body)\n", + nread, data->state.up.path); } break; @@ -837,13 +837,13 @@ static CURLcode readwrite_data(struct Curl_easy *data, excess = (size_t)(k->bytecount + nread - k->maxdownload); if(excess > 0 && !k->ignorebody) { - infof(data, - "Excess found in a read:" - " excess = %zu" - ", size = %" CURL_FORMAT_CURL_OFF_T - ", maxdownload = %" CURL_FORMAT_CURL_OFF_T - ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n", - excess, k->size, k->maxdownload, k->bytecount); + infof(data, + "Excess found in a read:" + " excess = %zu" + ", size = %" CURL_FORMAT_CURL_OFF_T + ", maxdownload = %" CURL_FORMAT_CURL_OFF_T + ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n", + excess, k->size, k->maxdownload, k->bytecount); connclose(conn, "excess found in a read"); } @@ -958,14 +958,14 @@ static CURLcode readwrite_data(struct Curl_easy *data, return CURLE_OK; } -CURLcode Curl_done_sending(struct connectdata *conn, - struct SingleRequest *k) +CURLcode Curl_done_sending(struct connectdata *conn, + struct SingleRequest *k) { k->keepon &= ~KEEP_SEND; /* we're done writing */ - /* These functions should be moved into the handler struct! */ + /* These functions should be moved into the handler struct! */ Curl_http2_done_sending(conn); - Curl_quic_done_sending(conn); + Curl_quic_done_sending(conn); if(conn->bits.rewindaftersend) { CURLcode result = Curl_readrewind(conn); @@ -1069,7 +1069,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, break; } if(nread <= 0) { - result = Curl_done_sending(conn, k); + result = Curl_done_sending(conn, k); if(result) return result; break; @@ -1158,7 +1158,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, (size_t)bytes_written); k->writebytecount += bytes_written; - Curl_pgrsSetUploadCounter(data, k->writebytecount); + Curl_pgrsSetUploadCounter(data, k->writebytecount); if((!k->upload_chunky || k->forbidchunk) && (k->writebytecount == data->state.infilesize)) { @@ -1186,7 +1186,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, k->upload_present = 0; /* no more bytes left */ if(k->upload_done) { - result = Curl_done_sending(conn, k); + result = Curl_done_sending(conn, k); if(result) return result; } @@ -1267,7 +1267,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, k->now = Curl_now(); if(didwhat) { - ; + ; } else { /* no read no write, this is a timeout? */ @@ -1306,15 +1306,15 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(k->keepon) { if(0 > Curl_timeleft(data, &k->now, FALSE)) { if(k->size != -1) { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes received", Curl_timediff(k->now, data->progress.t_startsingle), k->bytecount, k->size); } else { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received", + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received", Curl_timediff(k->now, data->progress.t_startsingle), k->bytecount); } @@ -1374,14 +1374,14 @@ CURLcode Curl_readwrite(struct connectdata *conn, * in the proper state to have this information available. */ int Curl_single_getsock(const struct connectdata *conn, - curl_socket_t *sock) + curl_socket_t *sock) { const struct Curl_easy *data = conn->data; int bitmap = GETSOCK_BLANK; unsigned sockindex = 0; if(conn->handler->perform_getsock) - return conn->handler->perform_getsock(conn, sock); + return conn->handler->perform_getsock(conn, sock); /* don't include HOLD and PAUSE connections */ if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) { @@ -1483,8 +1483,8 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) if(data->set.postfields && (data->state.infilesize == -1)) data->state.infilesize = (curl_off_t)strlen(data->set.postfields); } - else - data->state.infilesize = 0; + else + data->state.infilesize = 0; /* If there is a list of cookie files to read, do it now! */ if(data->change.cookielist) @@ -1518,7 +1518,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) data->state.authhost.picked &= data->state.authhost.want; data->state.authproxy.picked &= data->state.authproxy.want; -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP if(data->state.wildcardmatch) { struct WildcardData *wc = &data->wildcard; if(wc->state < CURLWC_INIT) { @@ -1527,7 +1527,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) return CURLE_OUT_OF_MEMORY; } } -#endif +#endif Curl_http2_init_state(&data->state); Curl_hsts_loadcb(data, data->hsts); } @@ -1826,7 +1826,7 @@ CURLcode Curl_retry_request(struct connectdata *conn, if(conn->handler->protocol&PROTO_FAMILY_HTTP) { - if(data->req.writebytecount) { + if(data->req.writebytecount) { CURLcode result = Curl_readrewind(conn); if(result) { Curl_safefree(*url); @@ -1844,16 +1844,16 @@ CURLcode Curl_retry_request(struct connectdata *conn, */ void Curl_setup_transfer( - struct Curl_easy *data, /* transfer */ + struct Curl_easy *data, /* transfer */ int sockindex, /* socket index to read from or -1 */ curl_off_t size, /* -1 if unknown at this point */ bool getheader, /* TRUE if header parsing is wanted */ - int writesockindex /* socket index to write to, it may very well be + int writesockindex /* socket index to write to, it may very well be the same we read from. -1 disables */ ) { - struct SingleRequest *k = &data->req; - struct connectdata *conn = data->conn; + struct SingleRequest *k = &data->req; + struct connectdata *conn = data->conn; struct HTTP *http = data->req.p.http; bool httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) && (http->sending == HTTPSEND_REQUEST)); diff --git a/contrib/libs/curl/lib/transfer.h b/contrib/libs/curl/lib/transfer.h index 3f0c304274..178bb58fb0 100644 --- a/contrib/libs/curl/lib/transfer.h +++ b/contrib/libs/curl/lib/transfer.h @@ -47,7 +47,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, struct Curl_easy *data, bool *done, bool *comeback); int Curl_single_getsock(const struct connectdata *conn, - curl_socket_t *socks); + curl_socket_t *socks); CURLcode Curl_readrewind(struct connectdata *conn); CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, size_t *nreadp); @@ -55,18 +55,18 @@ CURLcode Curl_retry_request(struct connectdata *conn, char **url); bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc); CURLcode Curl_get_upload_buffer(struct Curl_easy *data); -CURLcode Curl_done_sending(struct connectdata *conn, - struct SingleRequest *k); - +CURLcode Curl_done_sending(struct connectdata *conn, + struct SingleRequest *k); + /* This sets up a forthcoming transfer */ void -Curl_setup_transfer (struct Curl_easy *data, - int sockindex, /* socket index to read from or -1 */ - curl_off_t size, /* -1 if unknown at this point */ - bool getheader, /* TRUE if header parsing is wanted */ - int writesockindex /* socket index to write to. May be - the same we read from. -1 - disables */ - ); +Curl_setup_transfer (struct Curl_easy *data, + int sockindex, /* socket index to read from or -1 */ + curl_off_t size, /* -1 if unknown at this point */ + bool getheader, /* TRUE if header parsing is wanted */ + int writesockindex /* socket index to write to. May be + the same we read from. -1 + disables */ + ); #endif /* HEADER_CURL_TRANSFER_H */ diff --git a/contrib/libs/curl/lib/url.c b/contrib/libs/curl/lib/url.c index 0ac322a8d4..95e37dfeed 100644 --- a/contrib/libs/curl/lib/url.c +++ b/contrib/libs/curl/lib/url.c @@ -34,9 +34,9 @@ #ifdef HAVE_NET_IF_H #include <net/if.h> #endif -#ifdef HAVE_IPHLPAPI_H -#include <Iphlpapi.h> -#endif +#ifdef HAVE_IPHLPAPI_H +#include <Iphlpapi.h> +#endif #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif @@ -95,7 +95,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "inet_pton.h" #include "getinfo.h" #include "urlapi-int.h" -#include "system_win32.h" +#include "system_win32.h" #include "hsts.h" /* And now for the protocols */ @@ -122,7 +122,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "dotdot.h" #include "strdup.h" #include "setopt.h" -#include "altsvc.h" +#include "altsvc.h" #include "dynbuf.h" /* The last 3 #include files should be in this order */ @@ -324,7 +324,7 @@ void Curl_freeset(struct Curl_easy *data) } /* free the URL pieces */ -static void up_free(struct Curl_easy *data) +static void up_free(struct Curl_easy *data) { struct urlpieces *up = &data->state.up; Curl_safefree(up->scheme); @@ -405,7 +405,7 @@ CURLcode Curl_close(struct Curl_easy **datap) } data->change.referer = NULL; - up_free(data); + up_free(data); Curl_safefree(data->state.buffer); Curl_dyn_free(&data->state.headerb); Curl_safefree(data->state.ulbuf); @@ -414,9 +414,9 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_altsvc_cleanup(&data->asi); Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]); Curl_hsts_cleanup(&data->hsts); -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) - Curl_http_auth_cleanup_digest(data); -#endif +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) + Curl_http_auth_cleanup_digest(data); +#endif Curl_safefree(data->info.contenttype); Curl_safefree(data->info.wouldredirect); @@ -492,13 +492,13 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->method = HTTPREQ_GET; /* Default HTTP request */ set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */ -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ set->ftp_filemethod = FTPFILE_MULTICWD; set->ftp_skip_ip = TRUE; /* skip PASV IP by default */ -#endif +#endif set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ /* Set the default size of the SSL session ID cache */ @@ -541,8 +541,8 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) define since we internally only use the lower 16 bits for the passed in bitmask to not conflict with the private bits */ set->allowed_protocols = CURLPROTO_ALL; - set->redir_protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | - CURLPROTO_FTPS; + set->redir_protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | + CURLPROTO_FTPS; #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) /* @@ -554,9 +554,9 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) /* Set the default CA cert bundle/path detected/specified at build time. * - * If Schannel is the selected SSL backend then these locations are - * ignored. We allow setting CA location for schannel only when explicitly - * specified by the user via CURLOPT_CAINFO / --cacert. + * If Schannel is the selected SSL backend then these locations are + * ignored. We allow setting CA location for schannel only when explicitly + * specified by the user via CURLOPT_CAINFO / --cacert. */ if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { #if defined(CURL_CA_BUNDLE) @@ -598,8 +598,8 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->fnmatch = ZERO_NULL; set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT; set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ - set->maxage_conn = 118; - set->http09_allowed = FALSE; + set->maxage_conn = 118; + set->http09_allowed = FALSE; set->httpversion = #ifdef USE_NGHTTP2 CURL_HTTP_VERSION_2TLS @@ -705,13 +705,13 @@ static void conn_reset_all_postponed_data(struct connectdata *conn) #define conn_reset_all_postponed_data(c) do {} while(0) #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ - -static void conn_shutdown(struct connectdata *conn) + +static void conn_shutdown(struct connectdata *conn) { DEBUGASSERT(conn); - infof(conn->data, "Closing connection %ld\n", conn->connection_id); - DEBUGASSERT(conn->data); - + infof(conn->data, "Closing connection %ld\n", conn->connection_id); + DEBUGASSERT(conn->data); + /* possible left-overs from the async name resolvers */ Curl_resolver_cancel(conn); @@ -729,12 +729,12 @@ static void conn_shutdown(struct connectdata *conn) Curl_closesocket(conn, conn->tempsock[0]); if(CURL_SOCKET_BAD != conn->tempsock[1]) Curl_closesocket(conn, conn->tempsock[1]); -} +} -static void conn_free(struct connectdata *conn) -{ +static void conn_free(struct connectdata *conn) +{ DEBUGASSERT(conn); - + Curl_free_idnconverted_hostname(&conn->host); Curl_free_idnconverted_hostname(&conn->conn_to_host); #ifndef CURL_DISABLE_PROXY @@ -750,7 +750,7 @@ static void conn_free(struct connectdata *conn) #endif Curl_safefree(conn->user); Curl_safefree(conn->passwd); - Curl_safefree(conn->sasl_authzid); + Curl_safefree(conn->sasl_authzid); Curl_safefree(conn->options); Curl_dyn_free(&conn->trailer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ @@ -760,7 +760,7 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->connect_state); conn_reset_all_postponed_data(conn); - Curl_llist_destroy(&conn->easyq, NULL); + Curl_llist_destroy(&conn->easyq, NULL); Curl_safefree(conn->localdev); Curl_free_primary_ssl_config(&conn->ssl_config); @@ -818,24 +818,24 @@ CURLcode Curl_disconnect(struct Curl_easy *data, } /* Cleanup NTLM connection-related data */ - Curl_http_auth_cleanup_ntlm(conn); - - /* Cleanup NEGOTIATE connection-related data */ - Curl_http_auth_cleanup_negotiate(conn); - - /* the protocol specific disconnect handler and conn_shutdown need a transfer - for the connection! */ - conn->data = data; - - if(conn->bits.connect_only) - /* treat the connection as dead in CONNECT_ONLY situations */ - dead_connection = TRUE; - + Curl_http_auth_cleanup_ntlm(conn); + + /* Cleanup NEGOTIATE connection-related data */ + Curl_http_auth_cleanup_negotiate(conn); + + /* the protocol specific disconnect handler and conn_shutdown need a transfer + for the connection! */ + conn->data = data; + + if(conn->bits.connect_only) + /* treat the connection as dead in CONNECT_ONLY situations */ + dead_connection = TRUE; + if(conn->handler->disconnect) /* This is set if protocol-specific cleanups should be made */ conn->handler->disconnect(conn, dead_connection); - conn_shutdown(conn); + conn_shutdown(conn); conn_free(conn); return CURLE_OK; } @@ -859,21 +859,21 @@ static bool SocketIsDead(curl_socket_t sock) } /* - * IsMultiplexingPossible() + * IsMultiplexingPossible() * - * Return a bitmask with the available multiplexing options for the given - * requested connection. + * Return a bitmask with the available multiplexing options for the given + * requested connection. */ -static int IsMultiplexingPossible(const struct Curl_easy *handle, - const struct connectdata *conn) +static int IsMultiplexingPossible(const struct Curl_easy *handle, + const struct connectdata *conn) { int avail = 0; - /* If a HTTP protocol and multiplexing is enabled */ + /* If a HTTP protocol and multiplexing is enabled */ if((conn->handler->protocol & PROTO_FAMILY_HTTP) && (!conn->bits.protoconnstart || !conn->bits.close)) { - if(Curl_multiplex_wanted(handle->multi) && + if(Curl_multiplex_wanted(handle->multi) && (handle->set.httpversion >= CURL_HTTP_VERSION_2)) /* allows HTTP/2 */ avail |= CURLPIPE_MULTIPLEX; @@ -881,7 +881,7 @@ static int IsMultiplexingPossible(const struct Curl_easy *handle, return avail; } -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY static bool proxy_info_matches(const struct proxy_info *data, const struct proxy_info *needle) @@ -920,32 +920,32 @@ socks_proxy_info_matches(const struct proxy_info *data, return FALSE; return TRUE; } -#else -/* disabled, won't get called */ -#define proxy_info_matches(x,y) FALSE +#else +/* disabled, won't get called */ +#define proxy_info_matches(x,y) FALSE #define socks_proxy_info_matches(x,y) FALSE -#endif - -/* A connection has to have been idle for a shorter time than 'maxage_conn' to - be subject for reuse. The success rate is just too low after this. */ - -static bool conn_maxage(struct Curl_easy *data, - struct connectdata *conn, - struct curltime now) -{ - if(!conn->data) { - timediff_t idletime = Curl_timediff(now, conn->lastused); - idletime /= 1000; /* integer seconds is fine */ - - if(idletime > data->set.maxage_conn) { - infof(data, "Too old connection (%ld seconds), disconnect it\n", - idletime); - return TRUE; - } - } - return FALSE; -} - +#endif + +/* A connection has to have been idle for a shorter time than 'maxage_conn' to + be subject for reuse. The success rate is just too low after this. */ + +static bool conn_maxage(struct Curl_easy *data, + struct connectdata *conn, + struct curltime now) +{ + if(!conn->data) { + timediff_t idletime = Curl_timediff(now, conn->lastused); + idletime /= 1000; /* integer seconds is fine */ + + if(idletime > data->set.maxage_conn) { + infof(data, "Too old connection (%ld seconds), disconnect it\n", + idletime); + return TRUE; + } + } + return FALSE; +} + /* * This function checks if the given connection is dead and extracts it from * the connection cache if so. @@ -958,22 +958,22 @@ static bool conn_maxage(struct Curl_easy *data, static bool extract_if_dead(struct connectdata *conn, struct Curl_easy *data) { - if(!CONN_INUSE(conn) && !conn->data) { - /* The check for a dead socket makes sense only if the connection isn't in + if(!CONN_INUSE(conn) && !conn->data) { + /* The check for a dead socket makes sense only if the connection isn't in use */ bool dead; - struct curltime now = Curl_now(); - if(conn_maxage(data, conn, now)) { - dead = TRUE; - } - else if(conn->handler->connection_check) { + struct curltime now = Curl_now(); + if(conn_maxage(data, conn, now)) { + dead = TRUE; + } + else if(conn->handler->connection_check) { /* The protocol has a special method for checking the state of the connection. Use it to check if the connection is dead. */ unsigned int state; - struct Curl_easy *olddata = conn->data; - conn->data = data; /* use this transfer for now */ + struct Curl_easy *olddata = conn->data; + conn->data = data; /* use this transfer for now */ state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD); - conn->data = olddata; + conn->data = olddata; dead = (state & CONNRESULT_DEAD); } else { @@ -983,7 +983,7 @@ static bool extract_if_dead(struct connectdata *conn, if(dead) { infof(data, "Connection %ld seems to be dead!\n", conn->connection_id); - Curl_conncache_remove_conn(data, conn, FALSE); + Curl_conncache_remove_conn(data, conn, FALSE); return TRUE; } } @@ -1022,7 +1022,7 @@ static void prune_dead_connections(struct Curl_easy *data) CONNCACHE_LOCK(data); elapsed = - Curl_timediff(now, data->state.conn_cache->last_cleanup); + Curl_timediff(now, data->state.conn_cache->last_cleanup); CONNCACHE_UNLOCK(data); if(elapsed >= 1000L) { @@ -1054,7 +1054,7 @@ static void prune_dead_connections(struct Curl_easy *data) * connection as 'in-use'. It must later be called with ConnectionDone() to * return back to 'idle' (unused) state. * - * The force_reuse flag is set if the connection must be used. + * The force_reuse flag is set if the connection must be used. */ static bool ConnectionExists(struct Curl_easy *data, @@ -1066,9 +1066,9 @@ ConnectionExists(struct Curl_easy *data, struct connectdata *check; struct connectdata *chosen = 0; bool foundPendingCandidate = FALSE; - bool canmultiplex = IsMultiplexingPossible(data, needle); + bool canmultiplex = IsMultiplexingPossible(data, needle); struct connectbundle *bundle; - const char *hostbundle; + const char *hostbundle; #ifdef USE_NTLM bool wantNTLMhttp = ((data->state.authhost.want & @@ -1089,38 +1089,38 @@ ConnectionExists(struct Curl_easy *data, /* Look up the bundle with all the connections to this particular host. Locks the connection cache, beware of early returns! */ - bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache, - &hostbundle); + bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache, + &hostbundle); if(bundle) { /* Max pipe length is zero (unlimited) for multiplexed connections */ struct Curl_llist_element *curr; infof(data, "Found bundle for host %s: %p [%s]\n", - hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? - "can multiplex" : "serially")); + hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? + "can multiplex" : "serially")); - /* We can't multiplex if we don't know anything about the server */ - if(canmultiplex) { - if(bundle->multiuse == BUNDLE_UNKNOWN) { + /* We can't multiplex if we don't know anything about the server */ + if(canmultiplex) { + if(bundle->multiuse == BUNDLE_UNKNOWN) { if(data->set.pipewait) { - infof(data, "Server doesn't support multiplex yet, wait\n"); + infof(data, "Server doesn't support multiplex yet, wait\n"); *waitpipe = TRUE; CONNCACHE_UNLOCK(data); return FALSE; /* no re-use */ } - infof(data, "Server doesn't support multiplex (yet)\n"); - canmultiplex = FALSE; + infof(data, "Server doesn't support multiplex (yet)\n"); + canmultiplex = FALSE; } - if((bundle->multiuse == BUNDLE_MULTIPLEX) && - !Curl_multiplex_wanted(data->multi)) { + if((bundle->multiuse == BUNDLE_MULTIPLEX) && + !Curl_multiplex_wanted(data->multi)) { infof(data, "Could multiplex, but not asked to!\n"); - canmultiplex = FALSE; + canmultiplex = FALSE; + } + if(bundle->multiuse == BUNDLE_NO_MULTIUSE) { + infof(data, "Can not multiplex, even if we wanted to!\n"); + canmultiplex = FALSE; } - if(bundle->multiuse == BUNDLE_NO_MULTIUSE) { - infof(data, "Can not multiplex, even if we wanted to!\n"); - canmultiplex = FALSE; - } } curr = bundle->conn_list.head; @@ -1148,11 +1148,11 @@ ConnectionExists(struct Curl_easy *data, if(bundle->multiuse == BUNDLE_MULTIPLEX) multiplexed = CONN_INUSE(check); - if(canmultiplex) { + if(canmultiplex) { ; } else { - if(multiplexed) { + if(multiplexed) { /* can only happen within multi handles, and means that another easy handle is using this connection */ continue; @@ -1251,14 +1251,14 @@ ConnectionExists(struct Curl_easy *data, DEBUGASSERT(!check->data || GOOD_EASY_HANDLE(check->data)); - if(!canmultiplex && check->data) - /* this request can't be multiplexed but the checked connection is + if(!canmultiplex && check->data) + /* this request can't be multiplexed but the checked connection is already in use so we skip it */ continue; if(check->data && (check->data->multi != needle->data->multi)) - /* this could be subject for multiplex use, but only if they belong to - * the same multi handle */ + /* this could be subject for multiplex use, but only if they belong to + * the same multi handle */ continue; if(needle->localdev || needle->localport) { @@ -1358,7 +1358,7 @@ ConnectionExists(struct Curl_easy *data, continue; } } - else if(check->http_ntlm_state != NTLMSTATE_NONE) { + else if(check->http_ntlm_state != NTLMSTATE_NONE) { /* Connection is using NTLM auth but we don't want NTLM */ continue; } @@ -1375,7 +1375,7 @@ ConnectionExists(struct Curl_easy *data, strcmp(needle->http_proxy.passwd, check->http_proxy.passwd)) continue; } - else if(check->proxy_ntlm_state != NTLMSTATE_NONE) { + else if(check->proxy_ntlm_state != NTLMSTATE_NONE) { /* Proxy connection is using NTLM auth but we don't want NTLM */ continue; } @@ -1385,9 +1385,9 @@ ConnectionExists(struct Curl_easy *data, chosen = check; if((wantNTLMhttp && - (check->http_ntlm_state != NTLMSTATE_NONE)) || + (check->http_ntlm_state != NTLMSTATE_NONE)) || (wantProxyNTLMhttp && - (check->proxy_ntlm_state != NTLMSTATE_NONE))) { + (check->proxy_ntlm_state != NTLMSTATE_NONE))) { /* We must use this connection, no other */ *force_reuse = TRUE; break; @@ -1397,11 +1397,11 @@ ConnectionExists(struct Curl_easy *data, continue; } #endif - if(canmultiplex) { - /* We can multiplex if we want to. Let's continue looking for - the optimal connection to use. */ + if(canmultiplex) { + /* We can multiplex if we want to. Let's continue looking for + the optimal connection to use. */ - if(!multiplexed) { + if(!multiplexed) { /* We have the optimal connection. Let's stop looking. */ chosen = check; break; @@ -1412,9 +1412,9 @@ ConnectionExists(struct Curl_easy *data, if(check->bits.multiplex) { /* Multiplexed connections can only be HTTP/2 for now */ struct http_conn *httpc = &check->proto.httpc; - if(multiplexed >= httpc->settings.max_concurrent_streams) { + if(multiplexed >= httpc->settings.max_concurrent_streams) { infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n", - multiplexed); + multiplexed); continue; } else if(multiplexed >= @@ -1426,10 +1426,10 @@ ConnectionExists(struct Curl_easy *data, } } #endif - /* When not multiplexed, we have a match here! */ - chosen = check; - infof(data, "Multiplexed connection found!\n"); - break; + /* When not multiplexed, we have a match here! */ + chosen = check; + infof(data, "Multiplexed connection found!\n"); + break; } else { /* We have found a connection. Let's stop searching. */ @@ -1502,8 +1502,8 @@ bool Curl_is_ASCII_name(const char *hostname) static void strip_trailing_dot(struct hostname *host) { size_t len; - if(!host || !host->name) - return; + if(!host || !host->name) + return; len = strlen(host->name); if(len && (host->name[len-1] == '.')) host->name[len-1] = 0; @@ -1686,10 +1686,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) #endif /* CURL_DISABLE_PROXY */ conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE; -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; -#endif +#endif conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus; conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer; conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost; @@ -1700,8 +1700,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost; #endif conn->ip_version = data->set.ipver; - conn->bits.connect_only = data->set.connect_only; - conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */ + conn->bits.connect_only = data->set.connect_only; + conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */ #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ defined(NTLM_WB_ENABLED) @@ -1709,8 +1709,8 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->proxyntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; #endif - /* Initialize the easy handle list */ - Curl_llist_init(&conn->easyq, NULL); + /* Initialize the easy handle list */ + Curl_llist_init(&conn->easyq, NULL); #ifdef HAVE_GSSAPI conn->data_prot = PROT_CLEAR; @@ -1734,7 +1734,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) return conn; error: - Curl_llist_destroy(&conn->easyq, NULL); + Curl_llist_destroy(&conn->easyq, NULL); free(conn->localdev); #ifdef USE_SSL free(conn->ssl_extra); @@ -1807,50 +1807,50 @@ CURLcode Curl_uc_to_curlcode(CURLUcode uc) } /* - * If the URL was set with an IPv6 numerical address with a zone id part, set - * the scope_id based on that! - */ - -static void zonefrom_url(CURLU *uh, struct connectdata *conn) -{ - char *zoneid; - CURLUcode uc; - - uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0); - - if(!uc && zoneid) { - char *endp; - unsigned long scope = strtoul(zoneid, &endp, 10); - if(!*endp && (scope < UINT_MAX)) - /* A plain number, use it directly as a scope id. */ - conn->scope_id = (unsigned int)scope; -#if defined(HAVE_IF_NAMETOINDEX) - else { -#elif defined(WIN32) - else if(Curl_if_nametoindex) { -#endif - -#if defined(HAVE_IF_NAMETOINDEX) || defined(WIN32) - /* Zone identifier is not numeric */ - unsigned int scopeidx = 0; -#if defined(WIN32) - scopeidx = Curl_if_nametoindex(zoneid); -#else - scopeidx = if_nametoindex(zoneid); -#endif - if(!scopeidx) - infof(conn->data, "Invalid zoneid: %s; %s\n", zoneid, - strerror(errno)); - else - conn->scope_id = scopeidx; - } -#endif /* HAVE_IF_NAMETOINDEX || WIN32 */ - - free(zoneid); - } -} - -/* + * If the URL was set with an IPv6 numerical address with a zone id part, set + * the scope_id based on that! + */ + +static void zonefrom_url(CURLU *uh, struct connectdata *conn) +{ + char *zoneid; + CURLUcode uc; + + uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0); + + if(!uc && zoneid) { + char *endp; + unsigned long scope = strtoul(zoneid, &endp, 10); + if(!*endp && (scope < UINT_MAX)) + /* A plain number, use it directly as a scope id. */ + conn->scope_id = (unsigned int)scope; +#if defined(HAVE_IF_NAMETOINDEX) + else { +#elif defined(WIN32) + else if(Curl_if_nametoindex) { +#endif + +#if defined(HAVE_IF_NAMETOINDEX) || defined(WIN32) + /* Zone identifier is not numeric */ + unsigned int scopeidx = 0; +#if defined(WIN32) + scopeidx = Curl_if_nametoindex(zoneid); +#else + scopeidx = if_nametoindex(zoneid); +#endif + if(!scopeidx) + infof(conn->data, "Invalid zoneid: %s; %s\n", zoneid, + strerror(errno)); + else + conn->scope_id = scopeidx; + } +#endif /* HAVE_IF_NAMETOINDEX || WIN32 */ + + free(zoneid); + } +} + +/* * Parse URL and fill in the relevant members of the connection struct. */ static CURLcode parseurlandfillconn(struct Curl_easy *data, @@ -1862,11 +1862,11 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, char *hostname; bool use_set_uh = (data->set.uh && !data->state.this_is_a_follow); - up_free(data); /* cleanup previous leftovers first */ + up_free(data); /* cleanup previous leftovers first */ /* parse the URL */ if(use_set_uh) { - uh = data->state.uh = curl_url_dup(data->set.uh); + uh = data->state.uh = curl_url_dup(data->set.uh); } else { uh = data->state.uh = curl_url(); @@ -1899,7 +1899,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, if(uc) { DEBUGF(infof(data, "curl_url_set rejected %s\n", data->change.url)); return Curl_uc_to_curlcode(uc); - } + } /* after it was parsed, get the generated normalized version */ uc = curl_url_get(uh, CURLUPART_URL, &newurl, 0); @@ -2003,23 +2003,23 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, } else { unsigned long port = strtoul(data->state.up.port, NULL, 10); - conn->port = conn->remote_port = curlx_ultous(port); + conn->port = conn->remote_port = curlx_ultous(port); } (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); hostname = data->state.up.hostname; if(hostname && hostname[0] == '[') { - /* This looks like an IPv6 address literal. See if there is an address + /* This looks like an IPv6 address literal. See if there is an address scope. */ - size_t hlen; + size_t hlen; conn->bits.ipv6_ip = TRUE; - /* cut off the brackets! */ - hostname++; - hlen = strlen(hostname); - hostname[hlen - 1] = 0; + /* cut off the brackets! */ + hostname++; + hlen = strlen(hostname); + hostname[hlen - 1] = 0; - zonefrom_url(uh, conn); + zonefrom_url(uh, conn); } /* make sure the connect struct gets its own copy of the host name */ @@ -2286,55 +2286,55 @@ static CURLcode parse_proxy(struct Curl_easy *data, struct connectdata *conn, char *proxy, curl_proxytype proxytype) { - char *portptr = NULL; + char *portptr = NULL; long port = -1; char *proxyuser = NULL; char *proxypasswd = NULL; - char *host; + char *host; bool sockstype; - CURLUcode uc; - struct proxy_info *proxyinfo; - CURLU *uhp = curl_url(); - CURLcode result = CURLE_OK; - char *scheme = NULL; - - /* When parsing the proxy, allowing non-supported schemes since we have - these made up ones for proxies. Guess scheme for URLs without it. */ - uc = curl_url_set(uhp, CURLUPART_URL, proxy, - CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME); - if(!uc) { - /* parsed okay as a URL */ - uc = curl_url_get(uhp, CURLUPART_SCHEME, &scheme, 0); - if(uc) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - if(strcasecompare("https", scheme)) + CURLUcode uc; + struct proxy_info *proxyinfo; + CURLU *uhp = curl_url(); + CURLcode result = CURLE_OK; + char *scheme = NULL; + + /* When parsing the proxy, allowing non-supported schemes since we have + these made up ones for proxies. Guess scheme for URLs without it. */ + uc = curl_url_set(uhp, CURLUPART_URL, proxy, + CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME); + if(!uc) { + /* parsed okay as a URL */ + uc = curl_url_get(uhp, CURLUPART_SCHEME, &scheme, 0); + if(uc) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } + + if(strcasecompare("https", scheme)) proxytype = CURLPROXY_HTTPS; - else if(strcasecompare("socks5h", scheme)) + else if(strcasecompare("socks5h", scheme)) proxytype = CURLPROXY_SOCKS5_HOSTNAME; - else if(strcasecompare("socks5", scheme)) + else if(strcasecompare("socks5", scheme)) proxytype = CURLPROXY_SOCKS5; - else if(strcasecompare("socks4a", scheme)) + else if(strcasecompare("socks4a", scheme)) proxytype = CURLPROXY_SOCKS4A; - else if(strcasecompare("socks4", scheme) || - strcasecompare("socks", scheme)) + else if(strcasecompare("socks4", scheme) || + strcasecompare("socks", scheme)) proxytype = CURLPROXY_SOCKS4; - else if(strcasecompare("http", scheme)) + else if(strcasecompare("http", scheme)) ; /* leave it as HTTP or HTTP/1.0 */ else { /* Any other xxx:// reject! */ failf(data, "Unsupported proxy scheme for \'%s\'", proxy); - result = CURLE_COULDNT_CONNECT; - goto error; + result = CURLE_COULDNT_CONNECT; + goto error; } } - else { - failf(data, "Unsupported proxy syntax in \'%s\'", proxy); - result = CURLE_COULDNT_RESOLVE_PROXY; - goto error; - } + else { + failf(data, "Unsupported proxy syntax in \'%s\'", proxy); + result = CURLE_COULDNT_RESOLVE_PROXY; + goto error; + } #ifdef USE_SSL if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY)) @@ -2342,42 +2342,42 @@ static CURLcode parse_proxy(struct Curl_easy *data, if(proxytype == CURLPROXY_HTTPS) { failf(data, "Unsupported proxy \'%s\', libcurl is built without the " "HTTPS-proxy support.", proxy); - result = CURLE_NOT_BUILT_IN; - goto error; + result = CURLE_NOT_BUILT_IN; + goto error; } - sockstype = - proxytype == CURLPROXY_SOCKS5_HOSTNAME || - proxytype == CURLPROXY_SOCKS5 || - proxytype == CURLPROXY_SOCKS4A || - proxytype == CURLPROXY_SOCKS4; + sockstype = + proxytype == CURLPROXY_SOCKS5_HOSTNAME || + proxytype == CURLPROXY_SOCKS5 || + proxytype == CURLPROXY_SOCKS4A || + proxytype == CURLPROXY_SOCKS4; + + proxyinfo = sockstype ? &conn->socks_proxy : &conn->http_proxy; + proxyinfo->proxytype = proxytype; - proxyinfo = sockstype ? &conn->socks_proxy : &conn->http_proxy; - proxyinfo->proxytype = proxytype; - /* Is there a username and password given in this proxy url? */ - curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE); - curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE); - if(proxyuser || proxypasswd) { - Curl_safefree(proxyinfo->user); - proxyinfo->user = proxyuser; - Curl_safefree(proxyinfo->passwd); - if(!proxypasswd) { - proxypasswd = strdup(""); - if(!proxypasswd) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } + curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE); + curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE); + if(proxyuser || proxypasswd) { + Curl_safefree(proxyinfo->user); + proxyinfo->user = proxyuser; + Curl_safefree(proxyinfo->passwd); + if(!proxypasswd) { + proxypasswd = strdup(""); + if(!proxypasswd) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } } - proxyinfo->passwd = proxypasswd; - conn->bits.proxy_user_passwd = TRUE; /* enable it */ + proxyinfo->passwd = proxypasswd; + conn->bits.proxy_user_passwd = TRUE; /* enable it */ } - curl_url_get(uhp, CURLUPART_PORT, &portptr, 0); + curl_url_get(uhp, CURLUPART_PORT, &portptr, 0); - if(portptr) { - port = strtol(portptr, NULL, 10); - free(portptr); + if(portptr) { + port = strtol(portptr, NULL, 10); + free(portptr); } else { if(data->set.proxyport) @@ -2391,33 +2391,33 @@ static CURLcode parse_proxy(struct Curl_easy *data, port = CURL_DEFAULT_PROXY_PORT; } } - if(port >= 0) { - proxyinfo->port = port; - if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc) - conn->port = port; - } - - /* now, clone the proxy host name */ - uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE); - if(uc) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - Curl_safefree(proxyinfo->host.rawalloc); - proxyinfo->host.rawalloc = host; - if(host[0] == '[') { - /* this is a numerical IPv6, strip off the brackets */ - size_t len = strlen(host); - host[len-1] = 0; /* clear the trailing bracket */ - host++; - zonefrom_url(uhp, conn); - } - proxyinfo->host.name = host; - - error: - free(scheme); - curl_url_cleanup(uhp); - return result; + if(port >= 0) { + proxyinfo->port = port; + if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc) + conn->port = port; + } + + /* now, clone the proxy host name */ + uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE); + if(uc) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } + Curl_safefree(proxyinfo->host.rawalloc); + proxyinfo->host.rawalloc = host; + if(host[0] == '[') { + /* this is a numerical IPv6, strip off the brackets */ + size_t len = strlen(host); + host[len-1] = 0; /* clear the trailing bracket */ + host++; + zonefrom_url(uhp, conn); + } + proxyinfo->host.name = host; + + error: + free(scheme); + curl_url_cleanup(uhp); + return result; } /* @@ -2765,7 +2765,7 @@ static CURLcode parse_remote_port(struct Curl_easy *data, char portbuf[16]; CURLUcode uc; conn->remote_port = (unsigned short)data->set.use_port; - msnprintf(portbuf, sizeof(portbuf), "%d", conn->remote_port); + msnprintf(portbuf, sizeof(portbuf), "%d", conn->remote_port); uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0); if(uc) return CURLE_OUT_OF_MEMORY; @@ -2836,7 +2836,7 @@ static CURLcode override_login(struct Curl_easy *data, &netrc_user_changed, &netrc_passwd_changed, data->set.str[STRING_NETRC_FILE]); if(ret > 0) { - infof(data, "Couldn't find host %s in the .netrc file; using defaults\n", + infof(data, "Couldn't find host %s in the .netrc file; using defaults\n", conn->host.name); } else if(ret < 0) { @@ -3125,7 +3125,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, } #ifndef CURL_DISABLE_ALTSVC - if(data->asi && !host && (port == -1) && + if(data->asi && !host && (port == -1) && ((conn->handler->protocol == CURLPROTO_HTTPS) || #ifdef CURLDEBUG /* allow debug builds to circumvent the HTTPS restriction */ @@ -3134,70 +3134,70 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, 0 #endif )) { - /* no connect_to match, try alt-svc! */ - enum alpnid srcalpnid; - bool hit; - struct altsvc *as; - const int allowed_versions = ( ALPN_h1 -#ifdef USE_NGHTTP2 - | ALPN_h2 -#endif -#ifdef ENABLE_QUIC - | ALPN_h3 -#endif - ) & data->asi->flags; - - host = conn->host.rawalloc; -#ifdef USE_NGHTTP2 - /* with h2 support, check that first */ - srcalpnid = ALPN_h2; - hit = Curl_altsvc_lookup(data->asi, - srcalpnid, host, conn->remote_port, /* from */ - &as /* to */, - allowed_versions); - if(!hit) -#endif - { - srcalpnid = ALPN_h1; - hit = Curl_altsvc_lookup(data->asi, - srcalpnid, host, conn->remote_port, /* from */ - &as /* to */, - allowed_versions); - } - if(hit) { - char *hostd = strdup((char *)as->dst.host); - if(!hostd) - return CURLE_OUT_OF_MEMORY; - conn->conn_to_host.rawalloc = hostd; - conn->conn_to_host.name = hostd; - conn->bits.conn_to_host = TRUE; - conn->conn_to_port = as->dst.port; - conn->bits.conn_to_port = TRUE; - conn->bits.altused = TRUE; - infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n", - Curl_alpnid2str(srcalpnid), host, conn->remote_port, - Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port); - if(srcalpnid != as->dst.alpnid) { - /* protocol version switch */ - switch(as->dst.alpnid) { - case ALPN_h1: - conn->httpversion = 11; - break; - case ALPN_h2: - conn->httpversion = 20; - break; - case ALPN_h3: - conn->transport = TRNSPRT_QUIC; - conn->httpversion = 30; - break; - default: /* shouldn't be possible */ - break; - } - } - } - } -#endif - + /* no connect_to match, try alt-svc! */ + enum alpnid srcalpnid; + bool hit; + struct altsvc *as; + const int allowed_versions = ( ALPN_h1 +#ifdef USE_NGHTTP2 + | ALPN_h2 +#endif +#ifdef ENABLE_QUIC + | ALPN_h3 +#endif + ) & data->asi->flags; + + host = conn->host.rawalloc; +#ifdef USE_NGHTTP2 + /* with h2 support, check that first */ + srcalpnid = ALPN_h2; + hit = Curl_altsvc_lookup(data->asi, + srcalpnid, host, conn->remote_port, /* from */ + &as /* to */, + allowed_versions); + if(!hit) +#endif + { + srcalpnid = ALPN_h1; + hit = Curl_altsvc_lookup(data->asi, + srcalpnid, host, conn->remote_port, /* from */ + &as /* to */, + allowed_versions); + } + if(hit) { + char *hostd = strdup((char *)as->dst.host); + if(!hostd) + return CURLE_OUT_OF_MEMORY; + conn->conn_to_host.rawalloc = hostd; + conn->conn_to_host.name = hostd; + conn->bits.conn_to_host = TRUE; + conn->conn_to_port = as->dst.port; + conn->bits.conn_to_port = TRUE; + conn->bits.altused = TRUE; + infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n", + Curl_alpnid2str(srcalpnid), host, conn->remote_port, + Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port); + if(srcalpnid != as->dst.alpnid) { + /* protocol version switch */ + switch(as->dst.alpnid) { + case ALPN_h1: + conn->httpversion = 11; + break; + case ALPN_h2: + conn->httpversion = 20; + break; + case ALPN_h3: + conn->transport = TRNSPRT_QUIC; + conn->httpversion = 30; + break; + default: /* shouldn't be possible */ + break; + } + } + } + } +#endif + return result; } @@ -3211,8 +3211,8 @@ static CURLcode resolve_server(struct Curl_easy *data, CURLcode result = CURLE_OK; timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); - DEBUGASSERT(conn); - DEBUGASSERT(data); + DEBUGASSERT(conn); + DEBUGASSERT(data); /************************************************************* * Resolve the name of the server or proxy *************************************************************/ @@ -3410,7 +3410,7 @@ static void reuse_conn(struct connectdata *old_conn, Curl_safefree(old_conn->passwd); Curl_safefree(old_conn->options); Curl_safefree(old_conn->localdev); - Curl_llist_destroy(&old_conn->easyq, NULL); + Curl_llist_destroy(&old_conn->easyq, NULL); #ifdef USE_UNIX_SOCKETS Curl_safefree(old_conn->unix_domain_socket); @@ -3448,7 +3448,7 @@ static CURLcode create_conn(struct Curl_easy *data, size_t max_total_connections = Curl_multi_max_total_connections(data->multi); *async = FALSE; - *in_connect = NULL; + *in_connect = NULL; /************************************************************* * Check input data @@ -3478,14 +3478,14 @@ static CURLcode create_conn(struct Curl_easy *data, if(result) goto out; - if(data->set.str[STRING_SASL_AUTHZID]) { - conn->sasl_authzid = strdup(data->set.str[STRING_SASL_AUTHZID]); - if(!conn->sasl_authzid) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - + if(data->set.str[STRING_SASL_AUTHZID]) { + conn->sasl_authzid = strdup(data->set.str[STRING_SASL_AUTHZID]); + if(!conn->sasl_authzid) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + } + #ifdef USE_UNIX_SOCKETS if(data->set.str[STRING_UNIX_SOCKET_PATH]) { conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]); @@ -3635,7 +3635,7 @@ static CURLcode create_conn(struct Curl_easy *data, (void)conn->handler->done(conn, result, FALSE); goto out; } - Curl_setup_transfer(data, -1, -1, FALSE, -1); + Curl_setup_transfer(data, -1, -1, FALSE, -1); } /* since we skip do_init() */ @@ -3736,9 +3736,9 @@ static CURLcode create_conn(struct Curl_easy *data, /* reuse_fresh is TRUE if we are told to use a new connection by force, but we only acknowledge this option if this is not a re-used connection already (which happens due to follow-location or during a HTTP - authentication phase). CONNECT_ONLY transfers also refuse reuse. */ - if((data->set.reuse_fresh && !data->state.this_is_a_follow) || - data->set.connect_only) + authentication phase). CONNECT_ONLY transfers also refuse reuse. */ + if((data->set.reuse_fresh && !data->state.this_is_a_follow) || + data->set.connect_only) reuse = FALSE; else reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe); @@ -3785,14 +3785,14 @@ static CURLcode create_conn(struct Curl_easy *data, } if(waitpipe) - /* There is a connection that *might* become usable for multiplexing + /* There is a connection that *might* become usable for multiplexing "soon", and we wait for that */ connections_available = FALSE; else { /* this gets a lock on the conncache */ - const char *bundlehost; + const char *bundlehost; struct connectbundle *bundle = - Curl_conncache_find_bundle(conn, data->state.conn_cache, &bundlehost); + Curl_conncache_find_bundle(conn, data->state.conn_cache, &bundlehost); if(max_host_connections > 0 && bundle && (bundle->num_connections >= max_host_connections)) { @@ -3805,8 +3805,8 @@ static CURLcode create_conn(struct Curl_easy *data, if(conn_candidate) (void)Curl_disconnect(data, conn_candidate, FALSE); else { - infof(data, "No more connections allowed to host %s: %zu\n", - bundlehost, max_host_connections); + infof(data, "No more connections allowed to host %s: %zu\n", + bundlehost, max_host_connections); connections_available = FALSE; } } @@ -3990,7 +3990,7 @@ CURLcode Curl_connect(struct Curl_easy *data, bool *protocol_done) { CURLcode result; - struct connectdata *conn; + struct connectdata *conn; *asyncp = FALSE; /* assume synchronous resolves by default */ @@ -4000,29 +4000,29 @@ CURLcode Curl_connect(struct Curl_easy *data, data->req.maxdownload = -1; /* call the stuff that needs to be called */ - result = create_conn(data, &conn, asyncp); + result = create_conn(data, &conn, asyncp); if(!result) { if(CONN_INUSE(conn) > 1) - /* multiplexed */ + /* multiplexed */ *protocol_done = TRUE; else if(!*asyncp) { /* DNS resolution is done: that's either because this is a reused connection, in which case DNS was unnecessary, or because DNS really did finish already (synch resolver/fast async resolve) */ - result = Curl_setup_conn(conn, protocol_done); + result = Curl_setup_conn(conn, protocol_done); } } if(result == CURLE_NO_CONNECTION_AVAILABLE) { return result; } - else if(result && conn) { + else if(result && conn) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ Curl_detach_connnection(data); Curl_conncache_remove_conn(data, conn, TRUE); - Curl_disconnect(data, conn, TRUE); + Curl_disconnect(data, conn, TRUE); } return result; diff --git a/contrib/libs/curl/lib/url.h b/contrib/libs/curl/lib/url.h index f7bd45bed6..a9d5bda29c 100644 --- a/contrib/libs/curl/lib/url.h +++ b/contrib/libs/curl/lib/url.h @@ -50,7 +50,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data); void Curl_freeset(struct Curl_easy *data); CURLcode Curl_uc_to_curlcode(CURLUcode uc); CURLcode Curl_close(struct Curl_easy **datap); /* opposite of curl_open() */ -CURLcode Curl_connect(struct Curl_easy *, bool *async, bool *protocol_connect); +CURLcode Curl_connect(struct Curl_easy *, bool *async, bool *protocol_connect); CURLcode Curl_disconnect(struct Curl_easy *data, struct connectdata *, bool dead_connection); CURLcode Curl_setup_conn(struct connectdata *conn, diff --git a/contrib/libs/curl/lib/urlapi-int.h b/contrib/libs/curl/lib/urlapi-int.h index f9d25dcda5..4257233094 100644 --- a/contrib/libs/curl/lib/urlapi-int.h +++ b/contrib/libs/curl/lib/urlapi-int.h @@ -22,8 +22,8 @@ * ***************************************************************************/ #include "curl_setup.h" -/* scheme is not URL encoded, the longest libcurl supported ones are... */ -#define MAX_SCHEME_LEN 40 +/* scheme is not URL encoded, the longest libcurl supported ones are... */ +#define MAX_SCHEME_LEN 40 bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen); diff --git a/contrib/libs/curl/lib/urlapi.c b/contrib/libs/curl/lib/urlapi.c index 3766ac558d..ae75963595 100644 --- a/contrib/libs/curl/lib/urlapi.c +++ b/contrib/libs/curl/lib/urlapi.c @@ -29,7 +29,7 @@ #include "url.h" #include "escape.h" #include "curl_ctype.h" -#include "inet_pton.h" +#include "inet_pton.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -57,7 +57,7 @@ struct Curl_URL { char *password; char *options; /* IMAP only? */ char *host; - char *zoneid; /* for numerical IPv6 addresses */ + char *zoneid; /* for numerical IPv6 addresses */ char *port; char *path; char *query; @@ -77,7 +77,7 @@ static void free_urlhandle(struct Curl_URL *u) free(u->password); free(u->options); free(u->host); - free(u->zoneid); + free(u->zoneid); free(u->port); free(u->path); free(u->query); @@ -140,7 +140,7 @@ static bool urlchar_needs_escaping(int c) * URL encoding should be skipped for host names, otherwise IDN resolution * will fail. */ -static size_t strlen_url(const char *url, bool relative) +static size_t strlen_url(const char *url, bool relative) { const unsigned char *ptr; size_t newlen = 0; @@ -182,7 +182,7 @@ static size_t strlen_url(const char *url, bool relative) * URL encoding should be skipped for host names, otherwise IDN resolution * will fail. */ -static void strcpy_url(char *output, const char *url, bool relative) +static void strcpy_url(char *output, const char *url, bool relative) { /* we must add this with whitespace-replacing */ bool left = TRUE; @@ -267,7 +267,7 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) * The returned pointer must be freed by the caller unless NULL * (returns NULL on out of memory). */ -static char *concat_url(const char *base, const char *relurl) +static char *concat_url(const char *base, const char *relurl) { /*** TRY to append this new path to the old URL @@ -391,7 +391,7 @@ static char *concat_url(const char *base, const char *relurl) letter we replace each space with %20 while it is replaced with '+' on the right side of the '?' letter. */ - newlen = strlen_url(useurl, !host_changed); + newlen = strlen_url(useurl, !host_changed); urllen = strlen(url_clone); @@ -413,7 +413,7 @@ static char *concat_url(const char *base, const char *relurl) newest[urllen++]='/'; /* then append the new piece on the right side */ - strcpy_url(&newest[urllen], useurl, !host_changed); + strcpy_url(&newest[urllen], useurl, !host_changed); free(url_clone); @@ -514,11 +514,11 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, portptr = &hostname[len]; else if('%' == endbracket) { int zonelen = len; - if(1 == sscanf(hostname + zonelen, "%*[^]]%c%n", &endbracket, &len)) { - if(']' != endbracket) - return CURLUE_MALFORMED_INPUT; - portptr = &hostname[--zonelen + len + 1]; - } + if(1 == sscanf(hostname + zonelen, "%*[^]]%c%n", &endbracket, &len)) { + if(']' != endbracket) + return CURLUE_MALFORMED_INPUT; + portptr = &hostname[--zonelen + len + 1]; + } else return CURLUE_MALFORMED_INPUT; } @@ -541,18 +541,18 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, long port; char portbuf[7]; - /* Browser behavior adaptation. If there's a colon with no digits after, - just cut off the name there which makes us ignore the colon and just + /* Browser behavior adaptation. If there's a colon with no digits after, + just cut off the name there which makes us ignore the colon and just use the default port. Firefox, Chrome and Safari all do that. Don't do it if the URL has no scheme, to make something that looks like a scheme not work! */ - if(!portptr[1]) { - *portptr = '\0'; + if(!portptr[1]) { + *portptr = '\0'; return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER; - } - + } + if(!ISDIGIT(portptr[1])) return CURLUE_BAD_PORT_NUMBER; @@ -566,14 +566,14 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, if(rest[0]) return CURLUE_BAD_PORT_NUMBER; - *portptr++ = '\0'; /* cut off the name there */ - *rest = 0; - /* generate a new port number string to get rid of leading zeroes etc */ - msnprintf(portbuf, sizeof(portbuf), "%ld", port); - u->portnum = port; - u->port = strdup(portbuf); - if(!u->port) - return CURLUE_OUT_OF_MEMORY; + *portptr++ = '\0'; /* cut off the name there */ + *rest = 0; + /* generate a new port number string to get rid of leading zeroes etc */ + msnprintf(portbuf, sizeof(portbuf), "%ld", port); + u->portnum = port; + u->port = strdup(portbuf); + if(!u->port) + return CURLUE_OUT_OF_MEMORY; } return CURLUE_OK; @@ -583,14 +583,14 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, static CURLUcode junkscan(const char *part) { if(part) { - static const char badbytes[]={ - /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x7f, + static const char badbytes[]={ + /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x7f, 0x00 /* null-terminate */ - }; + }; size_t n = strlen(part); size_t nfine = strcspn(part, badbytes); if(nfine != n) @@ -601,57 +601,57 @@ static CURLUcode junkscan(const char *part) return CURLUE_OK; } -static CURLUcode hostname_check(struct Curl_URL *u, char *hostname) +static CURLUcode hostname_check(struct Curl_URL *u, char *hostname) { size_t len; size_t hlen = strlen(hostname); if(hostname[0] == '[') { #ifdef ENABLE_IPV6 - char dest[16]; /* fits a binary IPv6 address */ + char dest[16]; /* fits a binary IPv6 address */ #endif - const char *l = "0123456789abcdefABCDEF:."; + const char *l = "0123456789abcdefABCDEF:."; if(hlen < 4) /* '[::]' is the shortest possible valid string */ return CURLUE_MALFORMED_INPUT; hostname++; hlen -= 2; - if(hostname[hlen] != ']') - return CURLUE_MALFORMED_INPUT; - + if(hostname[hlen] != ']') + return CURLUE_MALFORMED_INPUT; + /* only valid letters are ok */ len = strspn(hostname, l); - if(hlen != len) { - hlen = len; - if(hostname[len] == '%') { - /* this could now be '%[zone id]' */ - char zoneid[16]; - int i = 0; - char *h = &hostname[len + 1]; - /* pass '25' if present and is a url encoded percent sign */ - if(!strncmp(h, "25", 2) && h[2] && (h[2] != ']')) - h += 2; - while(*h && (*h != ']') && (i < 15)) - zoneid[i++] = *h++; - if(!i || (']' != *h)) - return CURLUE_MALFORMED_INPUT; - zoneid[i] = 0; - u->zoneid = strdup(zoneid); - if(!u->zoneid) - return CURLUE_OUT_OF_MEMORY; - hostname[len] = ']'; /* insert end bracket */ - hostname[len + 1] = 0; /* terminate the hostname */ - } - else - return CURLUE_MALFORMED_INPUT; - /* hostname is fine */ - } -#ifdef ENABLE_IPV6 - hostname[hlen] = 0; /* end the address there */ - if(1 != Curl_inet_pton(AF_INET6, hostname, dest)) + if(hlen != len) { + hlen = len; + if(hostname[len] == '%') { + /* this could now be '%[zone id]' */ + char zoneid[16]; + int i = 0; + char *h = &hostname[len + 1]; + /* pass '25' if present and is a url encoded percent sign */ + if(!strncmp(h, "25", 2) && h[2] && (h[2] != ']')) + h += 2; + while(*h && (*h != ']') && (i < 15)) + zoneid[i++] = *h++; + if(!i || (']' != *h)) + return CURLUE_MALFORMED_INPUT; + zoneid[i] = 0; + u->zoneid = strdup(zoneid); + if(!u->zoneid) + return CURLUE_OUT_OF_MEMORY; + hostname[len] = ']'; /* insert end bracket */ + hostname[len + 1] = 0; /* terminate the hostname */ + } + else + return CURLUE_MALFORMED_INPUT; + /* hostname is fine */ + } +#ifdef ENABLE_IPV6 + hostname[hlen] = 0; /* end the address there */ + if(1 != Curl_inet_pton(AF_INET6, hostname, dest)) return CURLUE_MALFORMED_INPUT; - hostname[hlen] = ']'; /* restore ending bracket */ -#endif + hostname[hlen] = ']'; /* restore ending bracket */ +#endif } else { /* letters from the second string is not ok */ @@ -660,8 +660,8 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname) /* hostname with bad content */ return CURLUE_MALFORMED_INPUT; } - if(!hostname[0]) - return CURLUE_NO_HOST; + if(!hostname[0]) + return CURLUE_NO_HOST; return CURLUE_OK; } @@ -676,7 +676,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) char *fragment = NULL; CURLUcode result; bool url_has_scheme = FALSE; - char schemebuf[MAX_SCHEME_LEN + 1]; + char schemebuf[MAX_SCHEME_LEN + 1]; const char *schemep = NULL; size_t schemelen = 0; size_t urllen; @@ -689,10 +689,10 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) ************************************************************/ /* allocate scratch area */ urllen = strlen(url); - if(urllen > CURL_MAX_INPUT_LENGTH) - /* excessive input length */ - return CURLUE_MALFORMED_INPUT; - + if(urllen > CURL_MAX_INPUT_LENGTH) + /* excessive input length */ + return CURLUE_MALFORMED_INPUT; + path = u->scratch = malloc(urllen * 2 + 2); if(!path) return CURLUE_OUT_OF_MEMORY; @@ -1048,9 +1048,9 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, ptr = u->host; ifmissing = CURLUE_NO_HOST; break; - case CURLUPART_ZONEID: - ptr = u->zoneid; - break; + case CURLUPART_ZONEID: + ptr = u->zoneid; + break; case CURLUPART_PORT: ptr = u->port; ifmissing = CURLUE_NO_PORT; @@ -1097,7 +1097,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, char *scheme; char *options = u->options; char *port = u->port; - char *allochost = NULL; + char *allochost = NULL; if(u->scheme && strcasecompare("file", u->scheme)) { url = aprintf("file://%s%s%s", u->path, @@ -1135,18 +1135,18 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, if(h && !(h->flags & PROTOPT_URLOPTIONS)) options = NULL; - if((u->host[0] == '[') && u->zoneid) { - /* make it '[ host %25 zoneid ]' */ - size_t hostlen = strlen(u->host); - size_t alen = hostlen + 3 + strlen(u->zoneid) + 1; - allochost = malloc(alen); - if(!allochost) - return CURLUE_OUT_OF_MEMORY; - memcpy(allochost, u->host, hostlen - 1); - msnprintf(&allochost[hostlen - 1], alen - hostlen + 1, - "%%25%s]", u->zoneid); - } - + if((u->host[0] == '[') && u->zoneid) { + /* make it '[ host %25 zoneid ]' */ + size_t hostlen = strlen(u->host); + size_t alen = hostlen + 3 + strlen(u->zoneid) + 1; + allochost = malloc(alen); + if(!allochost) + return CURLUE_OUT_OF_MEMORY; + memcpy(allochost, u->host, hostlen - 1); + msnprintf(&allochost[hostlen - 1], alen - hostlen + 1, + "%%25%s]", u->zoneid); + } + url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", scheme, u->user ? u->user : "", @@ -1155,16 +1155,16 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, options ? ";" : "", options ? options : "", (u->user || u->password || options) ? "@": "", - allochost ? allochost : u->host, + allochost ? allochost : u->host, port ? ":": "", port ? port : "", (u->path && (u->path[0] != '/')) ? "/": "", u->path ? u->path : "/", - (u->query && u->query[0]) ? "?": "", - (u->query && u->query[0]) ? u->query : "", + (u->query && u->query[0]) ? "?": "", + (u->query && u->query[0]) ? u->query : "", u->fragment? "#": "", u->fragment? u->fragment : ""); - free(allochost); + free(allochost); } if(!url) return CURLUE_OUT_OF_MEMORY; @@ -1173,7 +1173,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, } default: ptr = NULL; - break; + break; } if(ptr) { *part = strdup(ptr); @@ -1240,11 +1240,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, case CURLUPART_HOST: storep = &u->host; break; - case CURLUPART_ZONEID: - storep = &u->zoneid; - break; + case CURLUPART_ZONEID: + storep = &u->zoneid; + break; case CURLUPART_PORT: - u->portnum = 0; + u->portnum = 0; storep = &u->port; break; case CURLUPART_PATH: @@ -1267,9 +1267,9 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, switch(what) { case CURLUPART_SCHEME: - if(strlen(part) > MAX_SCHEME_LEN) - /* too long */ - return CURLUE_MALFORMED_INPUT; + if(strlen(part) > MAX_SCHEME_LEN) + /* too long */ + return CURLUE_MALFORMED_INPUT; if(!(flags & CURLU_NON_SUPPORT_SCHEME) && /* verify that it is a fine scheme */ !Curl_builtin_scheme(part)) @@ -1290,22 +1290,22 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, storep = &u->host; Curl_safefree(u->zoneid); break; - case CURLUPART_ZONEID: - storep = &u->zoneid; - break; + case CURLUPART_ZONEID: + storep = &u->zoneid; + break; case CURLUPART_PORT: - { - char *endp; + { + char *endp; urlencode = FALSE; /* never */ - port = strtol(part, &endp, 10); /* Port number must be decimal */ + port = strtol(part, &endp, 10); /* Port number must be decimal */ if((port <= 0) || (port > 0xffff)) return CURLUE_BAD_PORT_NUMBER; - if(*endp) - /* weirdly provided number, not good! */ - return CURLUE_MALFORMED_INPUT; + if(*endp) + /* weirdly provided number, not good! */ + return CURLUE_MALFORMED_INPUT; storep = &u->port; - } - break; + } + break; case CURLUPART_PATH: urlskipslash = TRUE; storep = &u->path; @@ -1331,7 +1331,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, char *redired_url; CURLU *handle2; - if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN + 1)) { + if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN + 1)) { handle2 = curl_url(); if(!handle2) return CURLUE_OUT_OF_MEMORY; @@ -1358,7 +1358,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, } /* apply the relative part to create a new URL */ - redired_url = concat_url(oldurl, part); + redired_url = concat_url(oldurl, part); free(oldurl); if(!redired_url) return CURLUE_OUT_OF_MEMORY; @@ -1385,12 +1385,12 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, const char *newp = part; size_t nalloc = strlen(part); - if(nalloc > CURL_MAX_INPUT_LENGTH) - /* excessive input length */ - return CURLUE_MALFORMED_INPUT; - + if(nalloc > CURL_MAX_INPUT_LENGTH) + /* excessive input length */ + return CURLUE_MALFORMED_INPUT; + if(urlencode) { - const unsigned char *i; + const unsigned char *i; char *o; char *enc = malloc(nalloc * 3 + 1); /* for worst case! */ if(!enc) @@ -1459,18 +1459,18 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, } } - if(what == CURLUPART_HOST) { + if(what == CURLUPART_HOST) { if(0 == strlen(newp) && (flags & CURLU_NO_AUTHORITY)) { /* Skip hostname check, it's allowed to be empty. */ - } + } else { if(hostname_check(u, (char *)newp)) { free((char *)newp); return CURLUE_MALFORMED_INPUT; } } - } - + } + free(*storep); *storep = (char *)newp; } diff --git a/contrib/libs/curl/lib/urldata.h b/contrib/libs/curl/lib/urldata.h index 3aebfad137..b824856427 100644 --- a/contrib/libs/curl/lib/urldata.h +++ b/contrib/libs/curl/lib/urldata.h @@ -77,12 +77,12 @@ #define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") /* Default FTP/IMAP etc response timeout in milliseconds */ -#define RESP_TIMEOUT (120*1000) +#define RESP_TIMEOUT (120*1000) /* Max string input length is a precaution against abuse and to detect junk - input easier and better. */ -#define CURL_MAX_INPUT_LENGTH 8000000 - + input easier and better. */ +#define CURL_MAX_INPUT_LENGTH 8000000 + #include "cookie.h" #include "psl.h" #include "formdata.h" @@ -131,39 +131,39 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #include "mqtt.h" #include "wildcard.h" #include "multihandle.h" -#include "quic.h" +#include "quic.h" #ifdef HAVE_GSSAPI # ifdef HAVE_GSSGNU # include <gss.h> -# elif defined HAVE_GSSAPI_GSSAPI_H +# elif defined HAVE_GSSAPI_GSSAPI_H # include <gssapi/gssapi.h> # else # include <gssapi.h> # endif -# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H -# include <gssapi/gssapi_generic.h> -# endif +# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H +# include <gssapi/gssapi_generic.h> +# endif #endif #ifdef HAVE_LIBSSH2_H -#error #include <libssh2.h> -#error #include <libssh2_sftp.h> +#error #include <libssh2.h> +#error #include <libssh2_sftp.h> #endif /* HAVE_LIBSSH2_H */ #define CURLEASY_MAGIC_NUMBER 0xc0dedbadU #define GOOD_EASY_HANDLE(x) \ ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) -/* the type we use for storing a single boolean bit */ +/* the type we use for storing a single boolean bit */ #ifdef _MSC_VER typedef bool bit; #define BIT(x) bool x #else -typedef unsigned int bit; +typedef unsigned int bit; #define BIT(x) bit x:1 #endif - + #ifdef HAVE_GSSAPI /* Types needed for krb5-ftp connections */ struct krb5buffer { @@ -316,14 +316,14 @@ typedef enum { NTLMSTATE_LAST } curlntlm; -typedef enum { - GSS_AUTHNONE, - GSS_AUTHRECV, - GSS_AUTHSENT, - GSS_AUTHDONE, - GSS_AUTHSUCC -} curlnegotiate; - +typedef enum { + GSS_AUTHNONE, + GSS_AUTHRECV, + GSS_AUTHSENT, + GSS_AUTHDONE, + GSS_AUTHSUCC +} curlnegotiate; + #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) #include <iconv.h> #endif @@ -350,12 +350,12 @@ struct kerberos5data { #if defined(USE_NTLM) struct ntlmdata { #ifdef USE_WINDOWS_SSPI -/* The sslContext is used for the Schannel bindings. The - * api is available on the Windows 7 SDK and later. - */ -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - CtxtHandle *sslContext; -#endif +/* The sslContext is used for the Schannel bindings. The + * api is available on the Windows 7 SDK and later. + */ +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + CtxtHandle *sslContext; +#endif CredHandle *credentials; CtxtHandle *context; SEC_WINNT_AUTH_IDENTITY identity; @@ -382,7 +382,7 @@ struct ntlmdata { }; #endif -/* Struct used for Negotiate (SPNEGO) authentication */ +/* Struct used for Negotiate (SPNEGO) authentication */ #ifdef USE_SPNEGO struct negotiatedata { #ifdef HAVE_GSSAPI @@ -392,9 +392,9 @@ struct negotiatedata { gss_buffer_desc output_token; #else #ifdef USE_WINDOWS_SSPI -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - CtxtHandle *sslContext; -#endif +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + CtxtHandle *sslContext; +#endif DWORD status; CredHandle *credentials; CtxtHandle *context; @@ -421,8 +421,8 @@ struct ConnectBits { bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set the first time on the first connect function call */ #ifndef CURL_DISABLE_PROXY - bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy - is complete */ + bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy + is complete */ BIT(httpproxy); /* if set, this transfer is done through a http proxy */ BIT(socksproxy); /* if set, this transfer is done through a socks proxy */ BIT(proxy_user_passwd); /* user+password for the proxy? */ @@ -461,7 +461,7 @@ struct ConnectBits { though it will be discarded. When the whole send operation is done, we must call the data rewind callback. */ -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP BIT(ftp_use_epsv); /* As set with CURLOPT_FTP_USE_EPSV, but if we find out EPSV doesn't work we disable it for the forthcoming requests */ @@ -470,7 +470,7 @@ struct ConnectBits { requests */ BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */ BIT(ftp_use_control_ssl); /* Enabled SSL for the control connection */ -#endif +#endif BIT(netrc); /* name+password provided by netrc */ BIT(bound); /* set true if bind() has already been done on this socket/ connection */ @@ -596,13 +596,13 @@ struct SingleRequest { curl_off_t bytecount; /* total number of bytes read */ curl_off_t writebytecount; /* number of bytes written */ - curl_off_t headerbytecount; /* only count received headers */ - curl_off_t deductheadercount; /* this amount of bytes doesn't count when we - check if anything has been transferred at - the end of a connection. We use this - counter to make only a 100 reply (without a - following second response code) result in a - CURLE_GOT_NOTHING error code */ + curl_off_t headerbytecount; /* only count received headers */ + curl_off_t deductheadercount; /* this amount of bytes doesn't count when we + check if anything has been transferred at + the end of a connection. We use this + counter to make only a 100 reply (without a + following second response code) result in a + CURLE_GOT_NOTHING error code */ struct curltime start; /* transfer started at this time */ struct curltime now; /* current time */ @@ -638,10 +638,10 @@ struct SingleRequest { still left in the buffer, aimed for upload. */ ssize_t upload_present; - /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a - buffer, so the next read should read from where this pointer points to, - and the 'upload_present' contains the number of bytes available at this - position */ + /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a + buffer, so the next read should read from where this pointer points to, + and the 'upload_present' contains the number of bytes available at this + position */ char *upload_fromhere; /* Allocated protocol-specific data. Each protocol handler makes sure this @@ -660,9 +660,9 @@ struct SingleRequest { struct SSHPROTO *ssh; struct TELNET *telnet; } p; -#ifndef CURL_DISABLE_DOH +#ifndef CURL_DISABLE_DOH struct dohdata doh; /* DoH specific data for this request */ -#endif +#endif BIT(header); /* incoming data has HTTP header */ BIT(content_range); /* set TRUE if Content-Range: was found */ BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding @@ -714,23 +714,23 @@ struct Curl_handler { /* Called from the multi interface during the PROTOCONNECT phase, and it should then return a proper fd set */ int (*proto_getsock)(struct connectdata *conn, - curl_socket_t *socks); + curl_socket_t *socks); /* Called from the multi interface during the DOING phase, and it should then return a proper fd set */ int (*doing_getsock)(struct connectdata *conn, - curl_socket_t *socks); + curl_socket_t *socks); /* Called from the multi interface during the DO_MORE phase, and it should then return a proper fd set */ int (*domore_getsock)(struct connectdata *conn, - curl_socket_t *socks); + curl_socket_t *socks); /* Called from the multi interface during the DO_DONE, PERFORM and WAITPERFORM phases, and it should then return a proper fd set. Not setting this will make libcurl use the generic default one. */ int (*perform_getsock)(const struct connectdata *conn, - curl_socket_t *socks); + curl_socket_t *socks); /* This function *MAY* be set to a protocol-dependent function that is run * by the curl_disconnect(), as a step in the disconnection. If the handler @@ -832,8 +832,8 @@ struct http_connect_state { BIT(close_connection); }; -struct ldapconninfo; - +struct ldapconninfo; + /* for the (SOCKS) connect state machine */ enum connect_t { CONNECT_INIT, @@ -890,10 +890,10 @@ struct connectdata { void *closesocket_client; /* This is used by the connection cache logic. If this returns TRUE, this - handle is still used by one or more easy handles and can only used by any + handle is still used by one or more easy handles and can only used by any other easy handle without careful consideration (== only for - multiplexing) and it cannot be used by another multi handle! */ -#define CONN_INUSE(c) ((c)->easyq.size) + multiplexing) and it cannot be used by another multi handle! */ +#define CONN_INUSE(c) ((c)->easyq.size) /**** Fields set when inited and not modified again */ long connection_id; /* Contains a unique number to make it easier to @@ -918,17 +918,17 @@ struct connectdata { unsigned int scope_id; /* Scope id for IPv6 */ - enum { - TRNSPRT_TCP = 3, - TRNSPRT_UDP = 4, - TRNSPRT_QUIC = 5 - } transport; - -#ifdef ENABLE_QUIC - struct quicsocket hequic[2]; /* two, for happy eyeballs! */ - struct quicsocket *quic; -#endif - + enum { + TRNSPRT_TCP = 3, + TRNSPRT_UDP = 4, + TRNSPRT_QUIC = 5 + } transport; + +#ifdef ENABLE_QUIC + struct quicsocket hequic[2]; /* two, for happy eyeballs! */ + struct quicsocket *quic; +#endif + struct hostname host; char *hostname_resolve; /* host name to resolve to address, allocated */ char *secondaryhostname; /* secondary socket host name (ftp) */ @@ -966,14 +966,14 @@ struct connectdata { char *passwd; /* password string, allocated */ char *options; /* options string, allocated */ - char *sasl_authzid; /* authorisation identity string, allocated */ + char *sasl_authzid; /* authorisation identity string, allocated */ int httpversion; /* the HTTP version*10 reported by the server */ int rtspversion; /* the RTSP version*10 reported by the server */ struct curltime now; /* "current" time */ struct curltime created; /* creation time */ - struct curltime lastused; /* when returned to the connection cache */ + struct curltime lastused; /* when returned to the connection cache */ curl_socket_t sock[2]; /* two sockets, the second is used for the data transfer when doing FTP */ curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */ @@ -1048,28 +1048,28 @@ struct connectdata { void *seek_client; /* pointer to pass to the seek() above */ /*************** Request - specific items ************/ -#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) - CtxtHandle *sslContext; -#endif +#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) + CtxtHandle *sslContext; +#endif #if defined(USE_NTLM) - curlntlm http_ntlm_state; - curlntlm proxy_ntlm_state; - + curlntlm http_ntlm_state; + curlntlm proxy_ntlm_state; + struct ntlmdata ntlm; /* NTLM differs from other authentication schemes because it authenticates connections, not single requests! */ struct ntlmdata proxyntlm; /* NTLM data for proxy */ #endif -#ifdef USE_SPNEGO - curlnegotiate http_negotiate_state; - curlnegotiate proxy_negotiate_state; - - struct negotiatedata negotiate; /* state data for host Negotiate auth */ - struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ -#endif - +#ifdef USE_SPNEGO + curlnegotiate http_negotiate_state; + curlnegotiate proxy_negotiate_state; + + struct negotiatedata negotiate; /* state data for host Negotiate auth */ + struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ +#endif + /* data used for the asynch name resolve callback */ struct Curl_async async; @@ -1086,8 +1086,8 @@ struct connectdata { struct smtp_conn smtpc; struct rtsp_conn rtspc; struct smb_conn smbc; - void *rtmp; - struct ldapconninfo *ldapc; + void *rtmp; + struct ldapconninfo *ldapc; struct mqtt_conn mqtt; } proto; @@ -1126,14 +1126,14 @@ struct PureInfo { int httpversion; /* the http version number X.Y = X*10+Y */ time_t filetime; /* If requested, this is might get set. Set to -1 if the time was unretrievable. */ - curl_off_t header_size; /* size of read header(s) in bytes */ - curl_off_t request_size; /* the amount of bytes sent in the request(s) */ + curl_off_t header_size; /* size of read header(s) in bytes */ + curl_off_t request_size; /* the amount of bytes sent in the request(s) */ unsigned long proxyauthavail; /* what proxy auth types were announced */ unsigned long httpauthavail; /* what host auth types were announced */ long numconnects; /* how many new connection did libcurl created */ char *contenttype; /* the content type of the object */ char *wouldredirect; /* URL this would've been redirected to if asked to */ - curl_off_t retry_after; /* info from Retry-After: header */ + curl_off_t retry_after; /* info from Retry-After: header */ /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip' and, 'conn_local_port' are copied over from the connectdata struct in @@ -1150,9 +1150,9 @@ struct PureInfo { const char *conn_scheme; unsigned int conn_protocol; struct curl_certinfo certs; /* info about the certs, only populated in - OpenSSL, GnuTLS, Schannel, NSS and GSKit - builds. Asked for with CURLOPT_CERTINFO - / CURLINFO_CERTINFO */ + OpenSSL, GnuTLS, Schannel, NSS and GSKit + builds. Asked for with CURLOPT_CERTINFO + / CURLINFO_CERTINFO */ CURLproxycode pxcode; BIT(timecond); /* set to TRUE if the time condition didn't match, which thus made the document NOT get fetched */ @@ -1172,17 +1172,17 @@ struct Progress { int width; /* screen width at download start */ int flags; /* see progress.h */ - timediff_t timespent; + timediff_t timespent; curl_off_t dlspeed; curl_off_t ulspeed; - timediff_t t_nslookup; - timediff_t t_connect; - timediff_t t_appconnect; - timediff_t t_pretransfer; - timediff_t t_starttransfer; - timediff_t t_redirect; + timediff_t t_nslookup; + timediff_t t_connect; + timediff_t t_appconnect; + timediff_t t_pretransfer; + timediff_t t_starttransfer; + timediff_t t_redirect; struct curltime start; struct curltime t_startsingle; @@ -1270,26 +1270,26 @@ typedef enum { EXPIRE_CONNECTTIMEOUT, EXPIRE_DNS_PER_NAME, /* family1 */ EXPIRE_DNS_PER_NAME2, /* family2 */ - EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */ + EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */ EXPIRE_HAPPY_EYEBALLS, EXPIRE_MULTI_PENDING, EXPIRE_RUN_NOW, EXPIRE_SPEEDCHECK, EXPIRE_TIMEOUT, EXPIRE_TOOFAST, - EXPIRE_QUIC, + EXPIRE_QUIC, EXPIRE_LAST /* not an actual timer, used as a marker only */ } expire_id; - -typedef enum { - TRAILERS_NONE, - TRAILERS_INITIALIZED, - TRAILERS_SENDING, - TRAILERS_DONE -} trailers_state; - - + +typedef enum { + TRAILERS_NONE, + TRAILERS_INITIALIZED, + TRAILERS_SENDING, + TRAILERS_DONE +} trailers_state; + + /* * One instance for each timeout an easy handle can set. */ @@ -1396,16 +1396,16 @@ struct UrlState { struct Curl_easy *stream_depends_on; int stream_weight; - CURLU *uh; /* URL handle for the current parsed URL */ - struct urlpieces up; + CURLU *uh; /* URL handle for the current parsed URL */ + struct urlpieces up; Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ -#ifndef CURL_DISABLE_HTTP - size_t trailers_bytes_sent; +#ifndef CURL_DISABLE_HTTP + size_t trailers_bytes_sent; struct dynbuf trailers_buf; /* a buffer containing the compiled trailing headers */ -#endif - trailers_state trailers_state; /* whether we are sending trailers - and what stage are we at */ +#endif + trailers_state trailers_state; /* whether we are sending trailers + and what stage are we at */ /* Dynamically allocated strings, MUST be freed before this struct is killed. */ @@ -1425,20 +1425,20 @@ struct UrlState { #ifdef CURLDEBUG BIT(conncache_lock); #endif - /* when curl_easy_perform() is called, the multi handle is "owned" by - the easy handle so curl_easy_cleanup() on such an easy handle will - also close the multi handle! */ + /* when curl_easy_perform() is called, the multi handle is "owned" by + the easy handle so curl_easy_cleanup() on such an easy handle will + also close the multi handle! */ BIT(multi_owned_by_easy); - + BIT(this_is_a_follow); /* this is a followed Location: request */ BIT(refused_stream); /* this was refused, try again */ BIT(errorbuf); /* Set to TRUE if the error buffer is already filled in. - This must be set to FALSE every time _easy_perform() is - called. */ + This must be set to FALSE every time _easy_perform() is + called. */ BIT(allow_port); /* Is set.use_port allowed to take effect or not. This - is always set TRUE when curl_easy_perform() is called. */ + is always set TRUE when curl_easy_perform() is called. */ BIT(authproblem); /* TRUE if there's some problem authenticating */ - /* set after initial USER failure, to prevent an authentication loop */ + /* set after initial USER failure, to prevent an authentication loop */ BIT(ftp_trying_alternative); BIT(wildcardmatch); /* enable wildcard matching */ BIT(expect100header); /* TRUE if we added Expect: 100-continue */ @@ -1447,8 +1447,8 @@ struct UrlState { BIT(use_range); BIT(rangestringalloc); /* the range string is malloc()'ed */ BIT(done); /* set to FALSE when Curl_init_do() is called and set to TRUE - when multi_done() is called, to prevent multi_done() to get - invoked twice when the multi interface is used. */ + when multi_done() is called, to prevent multi_done() to get + invoked twice when the multi interface is used. */ BIT(stream_depends_e); /* set or don't set the Exclusive bit */ BIT(previouslypending); /* this transfer WAS in the multi->pending queue */ BIT(cookie_engine); @@ -1472,7 +1472,7 @@ struct DynamicStatic { BIT(url_alloc); /* URL string is malloc()'ed */ BIT(referer_alloc); /* referer string is malloc()ed */ BIT(wildcard_resolve); /* Set to true if any resolve change is a - wildcard */ + wildcard */ }; /* @@ -1566,10 +1566,10 @@ enum dupstring { STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */ STRING_TARGET, /* CURLOPT_REQUEST_TARGET */ STRING_DOH, /* CURLOPT_DOH_URL */ - STRING_ALTSVC, /* CURLOPT_ALTSVC */ + STRING_ALTSVC, /* CURLOPT_ALTSVC */ STRING_HSTS, /* CURLOPT_HSTS */ - STRING_SASL_AUTHZID, /* CURLOPT_SASL_AUTHZID */ - STRING_TEMP_URL, /* temp URL storage for proxy use */ + STRING_SASL_AUTHZID, /* CURLOPT_SASL_AUTHZID */ + STRING_TEMP_URL, /* temp URL storage for proxy use */ STRING_DNS_SERVERS, STRING_DNS_INTERFACE, STRING_DNS_LOCAL_IP4, @@ -1671,8 +1671,8 @@ struct UserDefined { long accepttimeout; /* in milliseconds, 0 means no timeout */ long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */ long server_response_timeout; /* in milliseconds, 0 means no timeout */ - long maxage_conn; /* in seconds, max idle time to allow a connection that - is to be reused */ + long maxage_conn; /* in seconds, max idle time to allow a connection that + is to be reused */ long tftp_blksize; /* in bytes, 0 means use default */ curl_off_t filesize; /* size of file to upload, -1 means unknown */ long low_speed_limit; /* bytes/second */ @@ -1718,11 +1718,11 @@ struct UserDefined { long ipver; /* the CURL_IPRESOLVE_* defines in the public header file 0 - whatever, 1 - v2, 2 - v6 */ curl_off_t max_filesize; /* Maximum file size to download */ -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */ - curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ - curl_ftpccc ftp_ccc; /* FTP CCC options */ -#endif + curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ + curl_ftpccc ftp_ccc; /* FTP CCC options */ +#endif int ftp_create_missing_dirs; /* 1 - create directories that don't exist 2 - the same but also allow MKD to fail once */ @@ -1734,7 +1734,7 @@ struct UserDefined { IMAP or POP3 or others! */ long new_file_perms; /* Permissions to use when creating remote files */ long new_directory_perms; /* Permissions to use when creating remote dirs */ - long ssh_auth_types; /* allowed SSH auth types */ + long ssh_auth_types; /* allowed SSH auth types */ char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */ struct curl_blob *blobs[BLOB_LAST]; unsigned int scope_id; /* Scope id for IPv6 */ @@ -1758,7 +1758,7 @@ struct UserDefined { long tcp_keepidle; /* seconds in idle before sending keepalive probe */ long tcp_keepintvl; /* seconds between TCP keepalive probes */ - size_t maxconnects; /* Max idle connections in the connection cache */ + size_t maxconnects; /* Max idle connections in the connection cache */ long expect_100_timeout; /* in milliseconds */ struct Curl_easy *stream_depends_on; @@ -1772,35 +1772,35 @@ struct UserDefined { multidone_func fmultidone; struct Curl_easy *dohfor; /* this is a DoH request for that transfer */ CURLU *uh; /* URL handle for the current parsed URL */ - void *trailer_data; /* pointer to pass to trailer data callback */ - curl_trailer_callback trailer_callback; /* trailing data callback */ + void *trailer_data; /* pointer to pass to trailer data callback */ + curl_trailer_callback trailer_callback; /* trailing data callback */ BIT(is_fread_set); /* has read callback been set to non-NULL? */ BIT(is_fwrite_set); /* has write callback been set to non-NULL? */ BIT(free_referer); /* set TRUE if 'referer' points to a string we - allocated */ + allocated */ BIT(tftp_no_options); /* do not send TFTP options requests */ BIT(sep_headers); /* handle host and proxy headers separately */ BIT(cookiesession); /* new cookie session? */ BIT(crlf); /* convert crlf on ftp upload(?) */ BIT(strip_path_slash); /* strip off initial slash from path */ BIT(ssh_compression); /* enable SSH compression */ - -/* Here follows boolean settings that define how to behave during - this session. They are STATIC, set by libcurl users or at least initially - and they don't change during operations. */ + +/* Here follows boolean settings that define how to behave during + this session. They are STATIC, set by libcurl users or at least initially + and they don't change during operations. */ BIT(get_filetime); /* get the time and get of the remote file */ BIT(tunnel_thru_httpproxy); /* use CONNECT through a HTTP proxy */ BIT(prefer_ascii); /* ASCII rather than binary */ BIT(ftp_append); /* append, not overwrite, on upload */ BIT(ftp_list_only); /* switch FTP command for listing directories */ -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP BIT(ftp_use_port); /* use the FTP PORT command */ BIT(ftp_use_epsv); /* if EPSV is to be attempted or not */ BIT(ftp_use_eprt); /* if EPRT is to be attempted or not */ BIT(ftp_use_pret); /* if PRET is to be used before PASV or not */ BIT(ftp_skip_ip); /* skip the IP address the FTP server passes on to - us */ -#endif + us */ +#endif BIT(hide_progress); /* don't use the progress meter */ BIT(http_fail_on_error); /* fail on HTTP error codes >= 400 */ BIT(http_keep_sending_on_error); /* for HTTP status codes >= 300 */ @@ -1827,9 +1827,9 @@ struct UserDefined { content-encoded (chunked, compressed) */ BIT(proxy_transfer_mode); /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */ -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) BIT(socks5_gssapi_nec); /* Flag to support NEC SOCKS5 server */ -#endif +#endif BIT(sasl_ir); /* Enable/disable SASL initial response */ BIT(wildcard_enabled); /* enable wildcard matching */ BIT(tcp_keepalive); /* use TCP keepalives */ @@ -1878,7 +1878,7 @@ struct Curl_easy { struct Curl_easy *next; struct Curl_easy *prev; - struct connectdata *conn; + struct connectdata *conn; struct Curl_llist_element connect_queue; struct Curl_llist_element conn_queue; /* list per connectdata */ @@ -1892,8 +1892,8 @@ struct Curl_easy { the state etc are also kept. This array is mostly used to detect when a socket is to be removed from the hash. See singlesocket(). */ curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE]; - int actions[MAX_SOCKSPEREASYHANDLE]; /* action for each socket in - sockets[] */ + int actions[MAX_SOCKSPEREASYHANDLE]; /* action for each socket in + sockets[] */ int numsocks; struct Names dns; @@ -1918,14 +1918,14 @@ struct Curl_easy { struct hsts *hsts; #endif #ifndef CURL_DISABLE_ALTSVC - struct altsvcinfo *asi; /* the alt-svc cache */ -#endif + struct altsvcinfo *asi; /* the alt-svc cache */ +#endif struct Progress progress; /* for all the progress meter data */ struct UrlState state; /* struct for fields used for state info and other dynamic purposes */ -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP struct WildcardData wildcard; /* wildcard download state info */ -#endif +#endif struct PureInfo info; /* stats, reports and info data */ struct curl_tlssessioninfo tsi; /* Information about the TLS session, only valid after a client has asked for it */ diff --git a/contrib/libs/curl/lib/vauth/cleartext.c b/contrib/libs/curl/lib/vauth/cleartext.c index 476919cd24..620dba03ef 100644 --- a/contrib/libs/curl/lib/vauth/cleartext.c +++ b/contrib/libs/curl/lib/vauth/cleartext.c @@ -25,9 +25,9 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_POP3) - +#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_POP3) + #include <curl/curl.h> #include "urldata.h" @@ -52,9 +52,9 @@ * Parameters: * * data [in] - The session handle. - * authzid [in] - The authorization identity. - * authcid [in] - The authentication identity. - * passwd [in] - The password. + * authzid [in] - The authorization identity. + * authcid [in] - The authentication identity. + * passwd [in] - The password. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. * outlen [out] - The length of the output message. @@ -62,41 +62,41 @@ * Returns CURLE_OK on success. */ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, - const char *authzid, - const char *authcid, - const char *passwd, + const char *authzid, + const char *authcid, + const char *passwd, char **outptr, size_t *outlen) { CURLcode result; char *plainauth; - size_t zlen; - size_t clen; + size_t zlen; + size_t clen; size_t plen; size_t plainlen; *outlen = 0; *outptr = NULL; - zlen = (authzid == NULL ? 0 : strlen(authzid)); - clen = strlen(authcid); - plen = strlen(passwd); + zlen = (authzid == NULL ? 0 : strlen(authzid)); + clen = strlen(authcid); + plen = strlen(passwd); /* Compute binary message length. Check for overflows. */ if((zlen > SIZE_T_MAX/4) || (clen > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2))) return CURLE_OUT_OF_MEMORY; - plainlen = zlen + clen + plen + 2; + plainlen = zlen + clen + plen + 2; plainauth = malloc(plainlen); if(!plainauth) return CURLE_OUT_OF_MEMORY; /* Calculate the reply */ - if(zlen != 0) - memcpy(plainauth, authzid, zlen); - plainauth[zlen] = '\0'; - memcpy(plainauth + zlen + 1, authcid, clen); - plainauth[zlen + clen + 1] = '\0'; - memcpy(plainauth + zlen + clen + 2, passwd, plen); + if(zlen != 0) + memcpy(plainauth, authzid, zlen); + plainauth[zlen] = '\0'; + memcpy(plainauth + zlen + 1, authcid, clen); + plainauth[zlen + clen + 1] = '\0'; + memcpy(plainauth + zlen + clen + 2, passwd, plen); /* Base64 encode the reply */ result = Curl_base64_encode(data, plainauth, plainlen, outptr, outlen); @@ -166,5 +166,5 @@ CURLcode Curl_auth_create_external_message(struct Curl_easy *data, /* This is the same formatting as the login message */ return Curl_auth_create_login_message(data, user, outptr, outlen); } - -#endif /* if no users */ + +#endif /* if no users */ diff --git a/contrib/libs/curl/lib/vauth/digest.c b/contrib/libs/curl/lib/vauth/digest.c index 324ca46a62..5fc9285263 100644 --- a/contrib/libs/curl/lib/vauth/digest.c +++ b/contrib/libs/curl/lib/vauth/digest.c @@ -376,12 +376,12 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, char *spn = NULL; /* Decode the challenge message */ - CURLcode result = auth_decode_digest_md5_message(chlg64, nonce, - sizeof(nonce), realm, - sizeof(realm), algorithm, - sizeof(algorithm), - qop_options, - sizeof(qop_options)); + CURLcode result = auth_decode_digest_md5_message(chlg64, nonce, + sizeof(nonce), realm, + sizeof(realm), algorithm, + sizeof(algorithm), + qop_options, + sizeof(qop_options)); if(result) return result; @@ -786,7 +786,7 @@ static CURLcode auth_create_digest_http_message( return CURLE_OUT_OF_MEMORY; if(digest->qop && strcasecompare(digest->qop, "auth-int")) { - /* We don't support auth-int for PUT or POST */ + /* We don't support auth-int for PUT or POST */ char hashed[65]; char *hashthis2; diff --git a/contrib/libs/curl/lib/vauth/digest_sspi.c b/contrib/libs/curl/lib/vauth/digest_sspi.c index 07350d81ae..91d18c992b 100644 --- a/contrib/libs/curl/lib/vauth/digest_sspi.c +++ b/contrib/libs/curl/lib/vauth/digest_sspi.c @@ -61,11 +61,11 @@ bool Curl_auth_is_digest_supported(void) status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), &SecurityPackage); - /* Release the package buffer as it is not required anymore */ - if(status == SEC_E_OK) { - s_pSecFn->FreeContextBuffer(SecurityPackage); - } - + /* Release the package buffer as it is not required anymore */ + if(status == SEC_E_OK) { + s_pSecFn->FreeContextBuffer(SecurityPackage); + } + return (status == SEC_E_OK ? TRUE : FALSE); } @@ -152,7 +152,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, } /* Generate our SPN */ - spn = Curl_auth_build_spn(service, data->conn->host.name, NULL); + spn = Curl_auth_build_spn(service, data->conn->host.name, NULL); if(!spn) { free(output_token); free(input_token); @@ -226,10 +226,10 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, free(output_token); free(input_token); - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; + if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + + return CURLE_AUTH_ERROR; } /* Base64 encode the response */ @@ -618,10 +618,10 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, Curl_safefree(digest->http_context); - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; + if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + + return CURLE_AUTH_ERROR; } output_token_len = resp_buf.cbBuffer; diff --git a/contrib/libs/curl/lib/vauth/krb5_gssapi.c b/contrib/libs/curl/lib/vauth/krb5_gssapi.c index 6b496f302b..0412815e93 100644 --- a/contrib/libs/curl/lib/vauth/krb5_gssapi.c +++ b/contrib/libs/curl/lib/vauth/krb5_gssapi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>. + * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>. * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which @@ -121,7 +121,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, free(spn); - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } free(spn); @@ -168,7 +168,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, Curl_gss_log_error(data, "gss_init_sec_context() failed: ", major_status, minor_status); - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } if(output_token.value && output_token.length) { @@ -252,7 +252,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, free(chlg); - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } /* Convert the username from internal format to a displayable token */ @@ -264,7 +264,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, free(chlg); - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } /* Setup the challenge "input" security buffer */ @@ -355,7 +355,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, free(message); - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } /* Base64 encode the response */ @@ -372,7 +372,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, } /* - * Curl_auth_cleanup_gssapi() + * Curl_auth_cleanup_gssapi() * * This is used to clean up the GSSAPI (Kerberos V5) specific data. * @@ -381,7 +381,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, * krb5 [in/out] - The Kerberos 5 data struct being cleaned up. * */ -void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) +void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) { OM_uint32 minor_status; diff --git a/contrib/libs/curl/lib/vauth/krb5_sspi.c b/contrib/libs/curl/lib/vauth/krb5_sspi.c index ce7bac261b..8e56a82409 100644 --- a/contrib/libs/curl/lib/vauth/krb5_sspi.c +++ b/contrib/libs/curl/lib/vauth/krb5_sspi.c @@ -58,11 +58,11 @@ bool Curl_auth_is_gssapi_supported(void) TEXT(SP_NAME_KERBEROS), &SecurityPackage); - /* Release the package buffer as it is not required anymore */ - if(status == SEC_E_OK) { - s_pSecFn->FreeContextBuffer(SecurityPackage); - } - + /* Release the package buffer as it is not required anymore */ + if(status == SEC_E_OK) { + s_pSecFn->FreeContextBuffer(SecurityPackage); + } + return (status == SEC_E_OK ? TRUE : FALSE); } @@ -223,12 +223,12 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, /* Free the decoded challenge as it is not required anymore */ free(chlg); - if(status == SEC_E_INSUFFICIENT_MEMORY) { - return CURLE_OUT_OF_MEMORY; - } - + if(status == SEC_E_INSUFFICIENT_MEMORY) { + return CURLE_OUT_OF_MEMORY; + } + if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } if(memcmp(&context, krb5->context, sizeof(context))) { @@ -319,10 +319,10 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, if(status != SEC_E_OK) { free(chlg); - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; + if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + + return CURLE_AUTH_ERROR; } /* Get the fully qualified username back from the context */ @@ -332,10 +332,10 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, if(status != SEC_E_OK) { free(chlg); - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; + if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + + return CURLE_AUTH_ERROR; } /* Setup the "input" security buffer */ @@ -454,10 +454,10 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, free(message); free(trailer); - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; + if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + + return CURLE_AUTH_ERROR; } /* Allocate the encryption (wrap) buffer */ @@ -493,7 +493,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, } /* - * Curl_auth_cleanup_gssapi() + * Curl_auth_cleanup_gssapi() * * This is used to clean up the GSSAPI (Kerberos V5) specific data. * @@ -502,7 +502,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, * krb5 [in/out] - The Kerberos 5 data struct being cleaned up. * */ -void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) +void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) { /* Free our security context */ if(krb5->context) { diff --git a/contrib/libs/curl/lib/vauth/ntlm.c b/contrib/libs/curl/lib/vauth/ntlm.c index 89e2823b15..a3117f3fee 100644 --- a/contrib/libs/curl/lib/vauth/ntlm.c +++ b/contrib/libs/curl/lib/vauth/ntlm.c @@ -183,11 +183,11 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, target_info_len = Curl_read16_le(&buffer[40]); target_info_offset = Curl_read32_le(&buffer[44]); if(target_info_len > 0) { - if((target_info_offset >= size) || - ((target_info_offset + target_info_len) > size) || + if((target_info_offset >= size) || + ((target_info_offset + target_info_len) > size) || (target_info_offset < 48)) { infof(data, "NTLM handshake failure (bad type-2 message). " - "Target Info Offset Len is set incorrect by the peer\n"); + "Target Info Offset Len is set incorrect by the peer\n"); return CURLE_BAD_CONTENT_ENCODING; } @@ -405,7 +405,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, (void)hostname, /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_cleanup_ntlm(ntlm); + Curl_auth_cleanup_ntlm(ntlm); #if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION) #define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY @@ -564,7 +564,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, } #if defined(USE_NTRESPONSES) && defined(USE_NTLM_V2) - if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { + if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { unsigned char ntbuffer[0x18]; unsigned char entropy[8]; unsigned char ntlmv2hash[0x18]; @@ -604,7 +604,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, #define CURL_MD5_DIGEST_LENGTH 16 /* fixed size */ /* We don't support NTLM2 if we don't have USE_NTRESPONSES */ - if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) { + if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) { unsigned char ntbuffer[0x18]; unsigned char tmp[0x18]; unsigned char md5sum[CURL_MD5_DIGEST_LENGTH]; @@ -636,9 +636,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp); /* End of NTLM2 Session code */ - /* NTLM v2 session security is a misnomer because it is not NTLM v2. - It is NTLM v1 using the extended session security that is also - in NTLM v2 */ + /* NTLM v2 session security is a misnomer because it is not NTLM v2. + It is NTLM v1 using the extended session security that is also + in NTLM v2 */ } else #endif @@ -783,14 +783,14 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, }); #ifdef USE_NTRESPONSES - /* ntresplen + size should not be risking an integer overflow here */ - if(ntresplen + size > sizeof(ntlmbuf)) { - failf(data, "incoming NTLM message too big"); - return CURLE_OUT_OF_MEMORY; + /* ntresplen + size should not be risking an integer overflow here */ + if(ntresplen + size > sizeof(ntlmbuf)) { + failf(data, "incoming NTLM message too big"); + return CURLE_OUT_OF_MEMORY; } - DEBUGASSERT(size == (size_t)ntrespoff); - memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); - size += ntresplen; + DEBUGASSERT(size == (size_t)ntrespoff); + memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); + size += ntresplen; DEBUG_OUT({ fprintf(stderr, "\n ntresp="); @@ -848,22 +848,22 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, /* Return with binary blob encoded into base64 */ result = Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen); - Curl_auth_cleanup_ntlm(ntlm); + Curl_auth_cleanup_ntlm(ntlm); return result; } /* - * Curl_auth_cleanup_ntlm() - * - * This is used to clean up the NTLM specific data. - * - * Parameters: - * - * ntlm [in/out] - The NTLM data struct being cleaned up. - * - */ -void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) + * Curl_auth_cleanup_ntlm() + * + * This is used to clean up the NTLM specific data. + * + * Parameters: + * + * ntlm [in/out] - The NTLM data struct being cleaned up. + * + */ +void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) { /* Free the target info */ Curl_safefree(ntlm->target_info); diff --git a/contrib/libs/curl/lib/vauth/ntlm_sspi.c b/contrib/libs/curl/lib/vauth/ntlm_sspi.c index 28a94577c9..28bc3efdaa 100644 --- a/contrib/libs/curl/lib/vauth/ntlm_sspi.c +++ b/contrib/libs/curl/lib/vauth/ntlm_sspi.c @@ -56,11 +56,11 @@ bool Curl_auth_is_ntlm_supported(void) status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), &SecurityPackage); - /* Release the package buffer as it is not required anymore */ - if(status == SEC_E_OK) { - s_pSecFn->FreeContextBuffer(SecurityPackage); - } - + /* Release the package buffer as it is not required anymore */ + if(status == SEC_E_OK) { + s_pSecFn->FreeContextBuffer(SecurityPackage); + } + return (status == SEC_E_OK ? TRUE : FALSE); } @@ -100,7 +100,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_cleanup_ntlm(ntlm); + Curl_auth_cleanup_ntlm(ntlm); /* Query the security package for NTLM */ status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), @@ -176,10 +176,10 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, if(status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc); - else if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; + else if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; /* Base64 encode the response */ return Curl_base64_encode(data, (char *) ntlm->output_token, @@ -258,7 +258,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, char **outptr, size_t *outlen) { CURLcode result = CURLE_OK; - SecBuffer type_2_bufs[2]; + SecBuffer type_2_bufs[2]; SecBuffer type_3_buf; SecBufferDesc type_2_desc; SecBufferDesc type_3_desc; @@ -270,40 +270,40 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, (void) userp; /* Setup the type-2 "input" security buffer */ - type_2_desc.ulVersion = SECBUFFER_VERSION; - type_2_desc.cBuffers = 1; - type_2_desc.pBuffers = &type_2_bufs[0]; - type_2_bufs[0].BufferType = SECBUFFER_TOKEN; - type_2_bufs[0].pvBuffer = ntlm->input_token; - type_2_bufs[0].cbBuffer = curlx_uztoul(ntlm->input_token_len); - -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - /* ssl context comes from schannel. - * When extended protection is used in IIS server, - * we have to pass a second SecBuffer to the SecBufferDesc - * otherwise IIS will not pass the authentication (401 response). - * Minimum supported version is Windows 7. - * https://docs.microsoft.com/en-us/security-updates - * /SecurityAdvisories/2009/973811 - */ - if(ntlm->sslContext) { - SEC_CHANNEL_BINDINGS channelBindings; - SecPkgContext_Bindings pkgBindings; - pkgBindings.Bindings = &channelBindings; - status = s_pSecFn->QueryContextAttributes( - ntlm->sslContext, - SECPKG_ATTR_ENDPOINT_BINDINGS, - &pkgBindings - ); - if(status == SEC_E_OK) { - type_2_desc.cBuffers++; - type_2_bufs[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; - type_2_bufs[1].cbBuffer = pkgBindings.BindingsLength; - type_2_bufs[1].pvBuffer = pkgBindings.Bindings; - } - } -#endif - + type_2_desc.ulVersion = SECBUFFER_VERSION; + type_2_desc.cBuffers = 1; + type_2_desc.pBuffers = &type_2_bufs[0]; + type_2_bufs[0].BufferType = SECBUFFER_TOKEN; + type_2_bufs[0].pvBuffer = ntlm->input_token; + type_2_bufs[0].cbBuffer = curlx_uztoul(ntlm->input_token_len); + +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + /* ssl context comes from schannel. + * When extended protection is used in IIS server, + * we have to pass a second SecBuffer to the SecBufferDesc + * otherwise IIS will not pass the authentication (401 response). + * Minimum supported version is Windows 7. + * https://docs.microsoft.com/en-us/security-updates + * /SecurityAdvisories/2009/973811 + */ + if(ntlm->sslContext) { + SEC_CHANNEL_BINDINGS channelBindings; + SecPkgContext_Bindings pkgBindings; + pkgBindings.Bindings = &channelBindings; + status = s_pSecFn->QueryContextAttributes( + ntlm->sslContext, + SECPKG_ATTR_ENDPOINT_BINDINGS, + &pkgBindings + ); + if(status == SEC_E_OK) { + type_2_desc.cBuffers++; + type_2_bufs[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; + type_2_bufs[1].cbBuffer = pkgBindings.BindingsLength; + type_2_bufs[1].pvBuffer = pkgBindings.Bindings; + } + } +#endif + /* Setup the type-3 "output" security buffer */ type_3_desc.ulVersion = SECBUFFER_VERSION; type_3_desc.cBuffers = 1; @@ -325,23 +325,23 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, infof(data, "NTLM handshake failure (type-3 message): Status=%x\n", status); - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; + if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + + return CURLE_AUTH_ERROR; } /* Base64 encode the response */ result = Curl_base64_encode(data, (char *) ntlm->output_token, type_3_buf.cbBuffer, outptr, outlen); - Curl_auth_cleanup_ntlm(ntlm); + Curl_auth_cleanup_ntlm(ntlm); return result; } /* - * Curl_auth_cleanup_ntlm() + * Curl_auth_cleanup_ntlm() * * This is used to clean up the NTLM specific data. * @@ -350,7 +350,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, * ntlm [in/out] - The NTLM data struct being cleaned up. * */ -void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) +void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) { /* Free our security context */ if(ntlm->context) { diff --git a/contrib/libs/curl/lib/vauth/oauth2.c b/contrib/libs/curl/lib/vauth/oauth2.c index 848c474da4..ca5842a7c0 100644 --- a/contrib/libs/curl/lib/vauth/oauth2.c +++ b/contrib/libs/curl/lib/vauth/oauth2.c @@ -24,9 +24,9 @@ #include "curl_setup.h" -#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_POP3) - +#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_POP3) + #include <curl/curl.h> #include "urldata.h" @@ -49,8 +49,8 @@ * * data[in] - The session handle. * user[in] - The user name. - * host[in] - The host name. - * port[in] - The port(when not Port 80). + * host[in] - The host name. + * port[in] - The port(when not Port 80). * bearer[in] - The bearer token. * outptr[in / out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. @@ -69,11 +69,11 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data, char *oauth = NULL; /* Generate the message */ - if(port == 0 || port == 80) - oauth = aprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1", user, host, + if(port == 0 || port == 80) + oauth = aprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1", user, host, bearer); else - oauth = aprintf("n,a=%s,\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user, + oauth = aprintf("n,a=%s,\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user, host, port, bearer); if(!oauth) return CURLE_OUT_OF_MEMORY; @@ -85,42 +85,42 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data, return result; } - -/* - * Curl_auth_create_xoauth_bearer_message() - * - * This is used to generate an already encoded XOAuth 2.0 message ready for - * sending to the recipient. - * - * Parameters: - * - * data[in] - The session handle. - * user[in] - The user name. - * bearer[in] - The bearer token. - * outptr[in / out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen[out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data, - const char *user, - const char *bearer, - char **outptr, size_t *outlen) -{ - CURLcode result = CURLE_OK; - - /* Generate the message */ - char *xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer); - if(!xoauth) - return CURLE_OUT_OF_MEMORY; - - /* Base64 encode the reply */ - result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen); - - free(xoauth); - - return result; -} -#endif /* disabled, no users */ - + +/* + * Curl_auth_create_xoauth_bearer_message() + * + * This is used to generate an already encoded XOAuth 2.0 message ready for + * sending to the recipient. + * + * Parameters: + * + * data[in] - The session handle. + * user[in] - The user name. + * bearer[in] - The bearer token. + * outptr[in / out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen[out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data, + const char *user, + const char *bearer, + char **outptr, size_t *outlen) +{ + CURLcode result = CURLE_OK; + + /* Generate the message */ + char *xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer); + if(!xoauth) + return CURLE_OUT_OF_MEMORY; + + /* Base64 encode the reply */ + result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen); + + free(xoauth); + + return result; +} +#endif /* disabled, no users */ + diff --git a/contrib/libs/curl/lib/vauth/spnego_gssapi.c b/contrib/libs/curl/lib/vauth/spnego_gssapi.c index 8eaa6f89d5..120925ff33 100644 --- a/contrib/libs/curl/lib/vauth/spnego_gssapi.c +++ b/contrib/libs/curl/lib/vauth/spnego_gssapi.c @@ -97,7 +97,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, /* We finished successfully our part of authentication, but server * rejected it (since we're again here). Exit with an error since we * can't invent anything better */ - Curl_auth_cleanup_spnego(nego); + Curl_auth_cleanup_spnego(nego); return CURLE_LOGIN_DENIED; } @@ -121,7 +121,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, free(spn); - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } free(spn); @@ -170,14 +170,14 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, Curl_gss_log_error(data, "gss_init_sec_context() failed: ", major_status, minor_status); - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } if(!output_token.value || !output_token.length) { if(output_token.value) gss_release_buffer(&unused_status, &output_token); - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; } /* Free previous token */ @@ -238,7 +238,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data, } /* - * Curl_auth_cleanup_spnego() + * Curl_auth_cleanup_spnego() * * This is used to clean up the SPNEGO (Negotiate) specific data. * @@ -247,7 +247,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data, * nego [in/out] - The Negotiate data struct being cleaned up. * */ -void Curl_auth_cleanup_spnego(struct negotiatedata *nego) +void Curl_auth_cleanup_spnego(struct negotiatedata *nego) { OM_uint32 minor_status; @@ -273,10 +273,10 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego) /* Reset any variables */ nego->status = 0; - nego->noauthpersist = FALSE; - nego->havenoauthpersist = FALSE; - nego->havenegdata = FALSE; - nego->havemultiplerequests = FALSE; + nego->noauthpersist = FALSE; + nego->havenoauthpersist = FALSE; + nego->havenegdata = FALSE; + nego->havemultiplerequests = FALSE; } #endif /* HAVE_GSSAPI && USE_SPNEGO */ diff --git a/contrib/libs/curl/lib/vauth/spnego_sspi.c b/contrib/libs/curl/lib/vauth/spnego_sspi.c index 4df80d804f..e7482a43e2 100644 --- a/contrib/libs/curl/lib/vauth/spnego_sspi.c +++ b/contrib/libs/curl/lib/vauth/spnego_sspi.c @@ -59,12 +59,12 @@ bool Curl_auth_is_spnego_supported(void) TEXT(SP_NAME_NEGOTIATE), &SecurityPackage); - /* Release the package buffer as it is not required anymore */ - if(status == SEC_E_OK) { - s_pSecFn->FreeContextBuffer(SecurityPackage); - } - - + /* Release the package buffer as it is not required anymore */ + if(status == SEC_E_OK) { + s_pSecFn->FreeContextBuffer(SecurityPackage); + } + + return (status == SEC_E_OK ? TRUE : FALSE); } @@ -98,7 +98,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, size_t chlglen = 0; unsigned char *chlg = NULL; PSecPkgInfo SecurityPackage; - SecBuffer chlg_buf[2]; + SecBuffer chlg_buf[2]; SecBuffer resp_buf; SecBufferDesc chlg_desc; SecBufferDesc resp_desc; @@ -113,7 +113,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, /* We finished successfully our part of authentication, but server * rejected it (since we're again here). Exit with an error since we * can't invent anything better */ - Curl_auth_cleanup_spnego(nego); + Curl_auth_cleanup_spnego(nego); return CURLE_LOGIN_DENIED; } @@ -173,7 +173,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, nego->p_identity, NULL, NULL, nego->credentials, &expiry); if(nego->status != SEC_E_OK) - return CURLE_AUTH_ERROR; + return CURLE_AUTH_ERROR; /* Allocate our new context handle */ nego->context = calloc(1, sizeof(CtxtHandle)); @@ -197,39 +197,39 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, } /* Setup the challenge "input" security buffer */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 1; - chlg_desc.pBuffers = &chlg_buf[0]; - chlg_buf[0].BufferType = SECBUFFER_TOKEN; - chlg_buf[0].pvBuffer = chlg; - chlg_buf[0].cbBuffer = curlx_uztoul(chlglen); - -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - /* ssl context comes from Schannel. - * When extended protection is used in IIS server, - * we have to pass a second SecBuffer to the SecBufferDesc - * otherwise IIS will not pass the authentication (401 response). - * Minimum supported version is Windows 7. - * https://docs.microsoft.com/en-us/security-updates - * /SecurityAdvisories/2009/973811 - */ - if(nego->sslContext) { - SEC_CHANNEL_BINDINGS channelBindings; - SecPkgContext_Bindings pkgBindings; - pkgBindings.Bindings = &channelBindings; - nego->status = s_pSecFn->QueryContextAttributes( - nego->sslContext, - SECPKG_ATTR_ENDPOINT_BINDINGS, - &pkgBindings - ); - if(nego->status == SEC_E_OK) { - chlg_desc.cBuffers++; - chlg_buf[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; - chlg_buf[1].cbBuffer = pkgBindings.BindingsLength; - chlg_buf[1].pvBuffer = pkgBindings.Bindings; - } - } -#endif + chlg_desc.ulVersion = SECBUFFER_VERSION; + chlg_desc.cBuffers = 1; + chlg_desc.pBuffers = &chlg_buf[0]; + chlg_buf[0].BufferType = SECBUFFER_TOKEN; + chlg_buf[0].pvBuffer = chlg; + chlg_buf[0].cbBuffer = curlx_uztoul(chlglen); + +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + /* ssl context comes from Schannel. + * When extended protection is used in IIS server, + * we have to pass a second SecBuffer to the SecBufferDesc + * otherwise IIS will not pass the authentication (401 response). + * Minimum supported version is Windows 7. + * https://docs.microsoft.com/en-us/security-updates + * /SecurityAdvisories/2009/973811 + */ + if(nego->sslContext) { + SEC_CHANNEL_BINDINGS channelBindings; + SecPkgContext_Bindings pkgBindings; + pkgBindings.Bindings = &channelBindings; + nego->status = s_pSecFn->QueryContextAttributes( + nego->sslContext, + SECPKG_ATTR_ENDPOINT_BINDINGS, + &pkgBindings + ); + if(nego->status == SEC_E_OK) { + chlg_desc.cBuffers++; + chlg_buf[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; + chlg_buf[1].cbBuffer = pkgBindings.BindingsLength; + chlg_buf[1].pvBuffer = pkgBindings.Bindings; + } + } +#endif } /* Setup the response "output" security buffer */ @@ -256,28 +256,28 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, free(chlg); if(GSS_ERROR(nego->status)) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "InitializeSecurityContext failed: %s", - Curl_sspi_strerror(nego->status, buffer, sizeof(buffer))); - - if(nego->status == (DWORD)SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; + Curl_sspi_strerror(nego->status, buffer, sizeof(buffer))); + + if(nego->status == (DWORD)SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + + return CURLE_AUTH_ERROR; } if(nego->status == SEC_I_COMPLETE_NEEDED || nego->status == SEC_I_COMPLETE_AND_CONTINUE) { nego->status = s_pSecFn->CompleteAuthToken(nego->context, &resp_desc); if(GSS_ERROR(nego->status)) { - char buffer[STRERROR_LEN]; - failf(data, "CompleteAuthToken failed: %s", - Curl_sspi_strerror(nego->status, buffer, sizeof(buffer))); - - if(nego->status == (DWORD)SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; + char buffer[STRERROR_LEN]; + failf(data, "CompleteAuthToken failed: %s", + Curl_sspi_strerror(nego->status, buffer, sizeof(buffer))); + + if(nego->status == (DWORD)SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + + return CURLE_AUTH_ERROR; } } @@ -326,7 +326,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data, } /* - * Curl_auth_cleanup_spnego() + * Curl_auth_cleanup_spnego() * * This is used to clean up the SPNEGO (Negotiate) specific data. * @@ -335,7 +335,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data, * nego [in/out] - The Negotiate data struct being cleaned up. * */ -void Curl_auth_cleanup_spnego(struct negotiatedata *nego) +void Curl_auth_cleanup_spnego(struct negotiatedata *nego) { /* Free our security context */ if(nego->context) { @@ -362,10 +362,10 @@ void Curl_auth_cleanup_spnego(struct negotiatedata *nego) /* Reset any variables */ nego->status = 0; nego->token_max = 0; - nego->noauthpersist = FALSE; - nego->havenoauthpersist = FALSE; - nego->havenegdata = FALSE; - nego->havemultiplerequests = FALSE; + nego->noauthpersist = FALSE; + nego->havenoauthpersist = FALSE; + nego->havenegdata = FALSE; + nego->havemultiplerequests = FALSE; } #endif /* USE_WINDOWS_SSPI && USE_SPNEGO */ diff --git a/contrib/libs/curl/lib/vauth/vauth.c b/contrib/libs/curl/lib/vauth/vauth.c index f3eb636fc4..129b8f8b57 100644 --- a/contrib/libs/curl/lib/vauth/vauth.c +++ b/contrib/libs/curl/lib/vauth/vauth.c @@ -105,26 +105,26 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host, #endif /* USE_WINDOWS_SSPI */ /* - * Curl_auth_user_contains_domain() - * - * This is used to test if the specified user contains a Windows domain name as - * follows: - * - * Domain\User (Down-level Logon Name) - * Domain/User (curl Down-level format - for compatibility with existing code) - * User@Domain (User Principal Name) - * - * Note: The user name may be empty when using a GSS-API library or Windows - * SSPI as the user and domain are either obtained from the credentials cache - * when using GSS-API or via the currently logged in user's credentials when - * using Windows SSPI. - * - * Parameters: - * - * user [in] - The user name. - * - * Returns TRUE on success; otherwise FALSE. - */ + * Curl_auth_user_contains_domain() + * + * This is used to test if the specified user contains a Windows domain name as + * follows: + * + * Domain\User (Down-level Logon Name) + * Domain/User (curl Down-level format - for compatibility with existing code) + * User@Domain (User Principal Name) + * + * Note: The user name may be empty when using a GSS-API library or Windows + * SSPI as the user and domain are either obtained from the credentials cache + * when using GSS-API or via the currently logged in user's credentials when + * using Windows SSPI. + * + * Parameters: + * + * user [in] - The user name. + * + * Returns TRUE on success; otherwise FALSE. + */ bool Curl_auth_user_contains_domain(const char *user) { bool valid = FALSE; diff --git a/contrib/libs/curl/lib/vauth/vauth.h b/contrib/libs/curl/lib/vauth/vauth.h index ee05e183fc..f25cfc329f 100644 --- a/contrib/libs/curl/lib/vauth/vauth.h +++ b/contrib/libs/curl/lib/vauth/vauth.h @@ -60,9 +60,9 @@ bool Curl_auth_user_contains_domain(const char *user); /* This is used to generate a base64 encoded PLAIN cleartext message */ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, - const char *authzid, - const char *authcid, - const char *passwd, + const char *authzid, + const char *authcid, + const char *passwd, char **outptr, size_t *outlen); /* This is used to generate a base64 encoded LOGIN cleartext message */ @@ -142,7 +142,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, char **outptr, size_t *outlen); /* This is used to clean up the NTLM specific data */ -void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm); +void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm); #endif /* USE_NTLM */ /* This is used to generate a base64 encoded OAuth 2.0 message */ @@ -152,13 +152,13 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data, const long port, const char *bearer, char **outptr, size_t *outlen); - -/* This is used to generate a base64 encoded XOAuth 2.0 message */ -CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data, - const char *user, - const char *bearer, - char **outptr, size_t *outlen); - + +/* This is used to generate a base64 encoded XOAuth 2.0 message */ +CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data, + const char *user, + const char *bearer, + char **outptr, size_t *outlen); + #if defined(USE_KERBEROS5) /* This is used to evaluate if GSSAPI (Kerberos V5) is supported */ bool Curl_auth_is_gssapi_supported(void); @@ -184,7 +184,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, size_t *outlen); /* This is used to clean up the GSSAPI specific data */ -void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5); +void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5); #endif /* USE_KERBEROS5 */ #if defined(USE_SPNEGO) @@ -208,7 +208,7 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data, char **outptr, size_t *outlen); /* This is used to clean up the SPNEGO specifiec data */ -void Curl_auth_cleanup_spnego(struct negotiatedata *nego); +void Curl_auth_cleanup_spnego(struct negotiatedata *nego); #endif /* USE_SPNEGO */ diff --git a/contrib/libs/curl/lib/version.c b/contrib/libs/curl/lib/version.c index 0875783880..5e8512ef05 100644 --- a/contrib/libs/curl/lib/version.c +++ b/contrib/libs/curl/lib/version.c @@ -27,7 +27,7 @@ #include "vtls/vtls.h" #include "http2.h" #include "vssh/ssh.h" -#include "quic.h" +#include "quic.h" #include "curl_printf.h" #ifdef USE_ARES @@ -200,15 +200,15 @@ char *curl_version(void) #endif /* _LIBICONV_VERSION */ src[i++] = iconv_version; #endif -#ifdef USE_SSH +#ifdef USE_SSH Curl_ssh_version(ssh_version, sizeof(ssh_version)); src[i++] = ssh_version; #endif -#ifdef USE_NGHTTP2 +#ifdef USE_NGHTTP2 Curl_http2_ver(h2_version, sizeof(h2_version)); src[i++] = h2_version; #endif -#ifdef ENABLE_QUIC +#ifdef ENABLE_QUIC Curl_quic_ver(h3_version, sizeof(h3_version)); src[i++] = h3_version; #endif @@ -397,9 +397,9 @@ static curl_version_info_data version_info = { #if defined(USE_NGHTTP2) | CURL_VERSION_HTTP2 #endif -#if defined(ENABLE_QUIC) - | CURL_VERSION_HTTP3 -#endif +#if defined(ENABLE_QUIC) + | CURL_VERSION_HTTP3 +#endif #if defined(USE_UNIX_SOCKETS) | CURL_VERSION_UNIX_SOCKETS #endif @@ -416,8 +416,8 @@ static curl_version_info_data version_info = { | CURL_VERSION_ZSTD #endif #ifndef CURL_DISABLE_ALTSVC - | CURL_VERSION_ALTSVC -#endif + | CURL_VERSION_ALTSVC +#endif #if defined(USE_HSTS) | CURL_VERSION_HSTS #endif @@ -433,8 +433,8 @@ static curl_version_info_data version_info = { NULL, /* ssh lib version */ 0, /* brotli_ver_num */ NULL, /* brotli version */ - 0, /* nghttp2 version number */ - NULL, /* nghttp2 version string */ + 0, /* nghttp2 version number */ + NULL, /* nghttp2 version string */ NULL, /* quic library string */ #ifdef CURL_CA_BUNDLE CURL_CA_BUNDLE, /* cainfo */ @@ -452,16 +452,16 @@ static curl_version_info_data version_info = { curl_version_info_data *curl_version_info(CURLversion stamp) { -#if defined(USE_SSH) +#if defined(USE_SSH) static char ssh_buffer[80]; #endif #ifdef USE_SSL -#ifdef CURL_WITH_MULTI_SSL - static char ssl_buffer[200]; -#else +#ifdef CURL_WITH_MULTI_SSL + static char ssl_buffer[200]; +#else static char ssl_buffer[80]; #endif -#endif +#endif #ifdef HAVE_BROTLI static char brotli_buffer[80]; #endif @@ -511,8 +511,8 @@ curl_version_info_data *curl_version_info(CURLversion stamp) #endif /* _LIBICONV_VERSION */ #endif -#if defined(USE_SSH) - Curl_ssh_version(ssh_buffer, sizeof(ssh_buffer)); +#if defined(USE_SSH) + Curl_ssh_version(ssh_buffer, sizeof(ssh_buffer)); version_info.libssh_version = ssh_buffer; #endif @@ -528,22 +528,22 @@ curl_version_info_data *curl_version_info(CURLversion stamp) version_info.zstd_version = zstd_buffer; #endif -#ifdef USE_NGHTTP2 - { - nghttp2_info *h2 = nghttp2_version(0); - version_info.nghttp2_ver_num = h2->version_num; - version_info.nghttp2_version = h2->version_str; - } -#endif - -#ifdef ENABLE_QUIC - { - static char quicbuffer[80]; - Curl_quic_ver(quicbuffer, sizeof(quicbuffer)); - version_info.quic_version = quicbuffer; - } -#endif - +#ifdef USE_NGHTTP2 + { + nghttp2_info *h2 = nghttp2_version(0); + version_info.nghttp2_ver_num = h2->version_num; + version_info.nghttp2_version = h2->version_str; + } +#endif + +#ifdef ENABLE_QUIC + { + static char quicbuffer[80]; + Curl_quic_ver(quicbuffer, sizeof(quicbuffer)); + version_info.quic_version = quicbuffer; + } +#endif + (void)stamp; /* avoid compiler warnings, we don't use this */ return &version_info; } diff --git a/contrib/libs/curl/lib/vquic/ngtcp2.c b/contrib/libs/curl/lib/vquic/ngtcp2.c index 81002acaa2..17c419d3e4 100644 --- a/contrib/libs/curl/lib/vquic/ngtcp2.c +++ b/contrib/libs/curl/lib/vquic/ngtcp2.c @@ -1,136 +1,136 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_NGTCP2 -#error #include <ngtcp2/ngtcp2.h> -#error #include <ngtcp2/ngtcp2_crypto.h> -#error #include <nghttp3/nghttp3.h> + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_NGTCP2 +#error #include <ngtcp2/ngtcp2.h> +#error #include <ngtcp2/ngtcp2_crypto.h> +#error #include <nghttp3/nghttp3.h> #ifdef USE_OPENSSL -#include <openssl/err.h> +#include <openssl/err.h> #endif -#include "urldata.h" -#include "sendf.h" -#include "strdup.h" -#include "rand.h" -#error #include "ngtcp2.h" -#include "multiif.h" -#include "strcase.h" -#include "connect.h" -#include "strerror.h" +#include "urldata.h" +#include "sendf.h" +#include "strdup.h" +#include "rand.h" +#error #include "ngtcp2.h" +#include "multiif.h" +#include "strcase.h" +#include "connect.h" +#include "strerror.h" #include "dynbuf.h" #error #include "vquic.h" #include "vtls/keylog.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* #define DEBUG_NGTCP2 */ + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* #define DEBUG_NGTCP2 */ #ifdef CURLDEBUG -#define DEBUG_HTTP3 +#define DEBUG_HTTP3 #endif -#ifdef DEBUG_HTTP3 -#define H3BUGF(x) x -#else +#ifdef DEBUG_HTTP3 +#define H3BUGF(x) x +#else #define H3BUGF(x) do { } while(0) -#endif - -/* - * This holds outgoing HTTP/3 stream data that is used by nghttp3 until acked. - * It is used as a circular buffer. Add new bytes at the end until it reaches - * the far end, then start over at index 0 again. - */ - -#define H3_SEND_SIZE (20*1024) -struct h3out { - uint8_t buf[H3_SEND_SIZE]; - size_t used; /* number of bytes used in the buffer */ - size_t windex; /* index in the buffer where to start writing the next - data block */ -}; - -#define QUIC_MAX_STREAMS (256*1024) -#define QUIC_MAX_DATA (1*1024*1024) -#define QUIC_IDLE_TIMEOUT 60000 /* milliseconds */ +#endif + +/* + * This holds outgoing HTTP/3 stream data that is used by nghttp3 until acked. + * It is used as a circular buffer. Add new bytes at the end until it reaches + * the far end, then start over at index 0 again. + */ + +#define H3_SEND_SIZE (20*1024) +struct h3out { + uint8_t buf[H3_SEND_SIZE]; + size_t used; /* number of bytes used in the buffer */ + size_t windex; /* index in the buffer where to start writing the next + data block */ +}; + +#define QUIC_MAX_STREAMS (256*1024) +#define QUIC_MAX_DATA (1*1024*1024) +#define QUIC_IDLE_TIMEOUT 60000 /* milliseconds */ #ifdef USE_OPENSSL -#define QUIC_CIPHERS \ - "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \ - "POLY1305_SHA256:TLS_AES_128_CCM_SHA256" -#define QUIC_GROUPS "P-256:X25519:P-384:P-521" +#define QUIC_CIPHERS \ + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \ + "POLY1305_SHA256:TLS_AES_128_CCM_SHA256" +#define QUIC_GROUPS "P-256:X25519:P-384:P-521" #elif defined(USE_GNUTLS) #define QUIC_PRIORITY \ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \ "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \ "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1" #endif - -static CURLcode ng_process_ingress(struct connectdata *conn, - curl_socket_t sockfd, - struct quicsocket *qs); -static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd, - struct quicsocket *qs); -static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, - size_t datalen, void *user_data, - void *stream_user_data); - -static ngtcp2_tstamp timestamp(void) -{ - struct curltime ct = Curl_now(); - return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS; -} - -#ifdef DEBUG_NGTCP2 -static void quic_printf(void *user_data, const char *fmt, ...) -{ - va_list ap; - (void)user_data; /* TODO, use this to do infof() instead long-term */ - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); -} -#endif - + +static CURLcode ng_process_ingress(struct connectdata *conn, + curl_socket_t sockfd, + struct quicsocket *qs); +static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd, + struct quicsocket *qs); +static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, + size_t datalen, void *user_data, + void *stream_user_data); + +static ngtcp2_tstamp timestamp(void) +{ + struct curltime ct = Curl_now(); + return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS; +} + +#ifdef DEBUG_NGTCP2 +static void quic_printf(void *user_data, const char *fmt, ...) +{ + va_list ap; + (void)user_data; /* TODO, use this to do infof() instead long-term */ + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); +} +#endif + #ifdef USE_OPENSSL -static ngtcp2_crypto_level -quic_from_ossl_level(OSSL_ENCRYPTION_LEVEL ossl_level) -{ - switch(ossl_level) { - case ssl_encryption_initial: - return NGTCP2_CRYPTO_LEVEL_INITIAL; - case ssl_encryption_early_data: - return NGTCP2_CRYPTO_LEVEL_EARLY; - case ssl_encryption_handshake: - return NGTCP2_CRYPTO_LEVEL_HANDSHAKE; - case ssl_encryption_application: +static ngtcp2_crypto_level +quic_from_ossl_level(OSSL_ENCRYPTION_LEVEL ossl_level) +{ + switch(ossl_level) { + case ssl_encryption_initial: + return NGTCP2_CRYPTO_LEVEL_INITIAL; + case ssl_encryption_early_data: + return NGTCP2_CRYPTO_LEVEL_EARLY; + case ssl_encryption_handshake: + return NGTCP2_CRYPTO_LEVEL_HANDSHAKE; + case ssl_encryption_application: return NGTCP2_CRYPTO_LEVEL_APPLICATION; - default: - assert(0); - } -} + default: + assert(0); + } +} #elif defined(USE_GNUTLS) static ngtcp2_crypto_level quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level) @@ -149,10 +149,10 @@ quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level) } } #endif - + static void qlog_callback(void *user_data, uint32_t flags, const void *data, size_t datalen) -{ +{ struct quicsocket *qs = (struct quicsocket *)user_data; (void)flags; if(qs->qlogfd != -1) { @@ -163,20 +163,20 @@ static void qlog_callback(void *user_data, uint32_t flags, qs->qlogfd = -1; } } - -} - + +} + static void quic_settings(struct quicsocket *qs, - uint64_t stream_buffer_size) -{ + uint64_t stream_buffer_size) +{ ngtcp2_settings *s = &qs->settings; - ngtcp2_settings_default(s); -#ifdef DEBUG_NGTCP2 - s->log_printf = quic_printf; -#else - s->log_printf = NULL; -#endif - s->initial_ts = timestamp(); + ngtcp2_settings_default(s); +#ifdef DEBUG_NGTCP2 + s->log_printf = quic_printf; +#else + s->log_printf = NULL; +#endif + s->initial_ts = timestamp(); s->transport_params.initial_max_stream_data_bidi_local = stream_buffer_size; s->transport_params.initial_max_stream_data_bidi_remote = QUIC_MAX_STREAMS; s->transport_params.initial_max_stream_data_uni = QUIC_MAX_STREAMS; @@ -187,66 +187,66 @@ static void quic_settings(struct quicsocket *qs, if(qs->qlogfd != -1) { s->qlog.write = qlog_callback; } -} - +} + #ifdef USE_OPENSSL -static void keylog_callback(const SSL *ssl, const char *line) -{ - (void)ssl; +static void keylog_callback(const SSL *ssl, const char *line) +{ + (void)ssl; Curl_tls_keylog_write_line(line); -} +} #elif defined(USE_GNUTLS) static int keylog_callback(gnutls_session_t session, const char *label, const gnutls_datum_t *secret) -{ +{ gnutls_datum_t crandom; gnutls_datum_t srandom; - + gnutls_session_get_random(session, &crandom, &srandom); if(crandom.size != 32) { return -1; } - + Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size); return 0; -} +} #endif - + static int init_ngh3_conn(struct quicsocket *qs); static int write_client_handshake(struct quicsocket *qs, ngtcp2_crypto_level level, const uint8_t *data, size_t len) -{ - struct quic_handshake *crypto_data; - int rv; - +{ + struct quic_handshake *crypto_data; + int rv; + crypto_data = &qs->crypto_data[level]; - if(crypto_data->buf == NULL) { - crypto_data->buf = malloc(4096); + if(crypto_data->buf == NULL) { + crypto_data->buf = malloc(4096); if(!crypto_data->buf) return 0; - crypto_data->alloclen = 4096; - } - - /* TODO Just pretend that handshake does not grow more than 4KiB for - now */ - assert(crypto_data->len + len <= crypto_data->alloclen); - - memcpy(&crypto_data->buf[crypto_data->len], data, len); - crypto_data->len += len; - - rv = ngtcp2_conn_submit_crypto_data( + crypto_data->alloclen = 4096; + } + + /* TODO Just pretend that handshake does not grow more than 4KiB for + now */ + assert(crypto_data->len + len <= crypto_data->alloclen); + + memcpy(&crypto_data->buf[crypto_data->len], data, len); + crypto_data->len += len; + + rv = ngtcp2_conn_submit_crypto_data( qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len), len); - if(rv) { + if(rv) { H3BUGF(fprintf(stderr, "write_client_handshake failed\n")); - } - assert(0 == rv); - - return 1; -} - + } + assert(0 == rv); + + return 1; +} + #ifdef USE_OPENSSL static int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level, @@ -282,82 +282,82 @@ static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level, return write_client_handshake(qs, level, data, len); } -static int quic_flush_flight(SSL *ssl) -{ - (void)ssl; - return 1; -} - -static int quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level, - uint8_t alert) -{ - struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl); - (void)level; - - qs->tls_alert = alert; - return 1; -} - -static SSL_QUIC_METHOD quic_method = {quic_set_encryption_secrets, - quic_add_handshake_data, - quic_flush_flight, quic_send_alert}; - -static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data) -{ - SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method()); - - SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION); - SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION); - - SSL_CTX_set_default_verify_paths(ssl_ctx); - - if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) { +static int quic_flush_flight(SSL *ssl) +{ + (void)ssl; + return 1; +} + +static int quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level, + uint8_t alert) +{ + struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl); + (void)level; + + qs->tls_alert = alert; + return 1; +} + +static SSL_QUIC_METHOD quic_method = {quic_set_encryption_secrets, + quic_add_handshake_data, + quic_flush_flight, quic_send_alert}; + +static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data) +{ + SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method()); + + SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION); + SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION); + + SSL_CTX_set_default_verify_paths(ssl_ctx); + + if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) { char error_buffer[256]; ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer)); failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer); - return NULL; - } - - if(SSL_CTX_set1_groups_list(ssl_ctx, QUIC_GROUPS) != 1) { - failf(data, "SSL_CTX_set1_groups_list failed"); - return NULL; - } - - SSL_CTX_set_quic_method(ssl_ctx, &quic_method); - + return NULL; + } + + if(SSL_CTX_set1_groups_list(ssl_ctx, QUIC_GROUPS) != 1) { + failf(data, "SSL_CTX_set1_groups_list failed"); + return NULL; + } + + SSL_CTX_set_quic_method(ssl_ctx, &quic_method); + /* Open the file if a TLS or QUIC backend has not done this before. */ Curl_tls_keylog_open(); if(Curl_tls_keylog_enabled()) { SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback); - } - - return ssl_ctx; -} - -/** SSL callbacks ***/ - -static int quic_init_ssl(struct quicsocket *qs) -{ - const uint8_t *alpn = NULL; - size_t alpnlen = 0; - /* this will need some attention when HTTPS proxy over QUIC get fixed */ - const char * const hostname = qs->conn->host.name; - + } + + return ssl_ctx; +} + +/** SSL callbacks ***/ + +static int quic_init_ssl(struct quicsocket *qs) +{ + const uint8_t *alpn = NULL; + size_t alpnlen = 0; + /* this will need some attention when HTTPS proxy over QUIC get fixed */ + const char * const hostname = qs->conn->host.name; + DEBUGASSERT(!qs->ssl); - qs->ssl = SSL_new(qs->sslctx); - - SSL_set_app_data(qs->ssl, qs); - SSL_set_connect_state(qs->ssl); - + qs->ssl = SSL_new(qs->sslctx); + + SSL_set_app_data(qs->ssl, qs); + SSL_set_connect_state(qs->ssl); + alpn = (const uint8_t *)NGHTTP3_ALPN_H3; alpnlen = sizeof(NGHTTP3_ALPN_H3) - 1; - if(alpn) - SSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen); - - /* set SNI */ - SSL_set_tlsext_host_name(qs->ssl, hostname); - return 0; -} + if(alpn) + SSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen); + + /* set SNI */ + SSL_set_tlsext_host_name(qs->ssl, hostname); + return 0; +} #elif defined(USE_GNUTLS) static int secret_func(gnutls_session_t ssl, gnutls_record_encryption_level_t gtls_level, @@ -366,7 +366,7 @@ static int secret_func(gnutls_session_t ssl, { struct quicsocket *qs = gnutls_session_get_ptr(ssl); int level = quic_from_gtls_level(gtls_level); - + if(level != NGTCP2_CRYPTO_LEVEL_EARLY && ngtcp2_crypto_derive_and_install_rx_key( qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0) @@ -388,21 +388,21 @@ static int read_func(gnutls_session_t ssl, gnutls_record_encryption_level_t gtls_level, gnutls_handshake_description_t htype, const void *data, size_t len) -{ +{ struct quicsocket *qs = gnutls_session_get_ptr(ssl); ngtcp2_crypto_level level = quic_from_gtls_level(gtls_level); int rv; - + if(htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC) return 0; - + rv = write_client_handshake(qs, level, data, len); if(rv == 0) return -1; - return 0; -} - + return 0; +} + static int alert_read_func(gnutls_session_t ssl, gnutls_record_encryption_level_t gtls_level, gnutls_alert_level_t alert_level, @@ -538,31 +538,31 @@ static int quic_init_ssl(struct quicsocket *qs) } #endif -static int -cb_recv_crypto_data(ngtcp2_conn *tconn, ngtcp2_crypto_level crypto_level, - uint64_t offset, - const uint8_t *data, size_t datalen, - void *user_data) -{ - (void)offset; +static int +cb_recv_crypto_data(ngtcp2_conn *tconn, ngtcp2_crypto_level crypto_level, + uint64_t offset, + const uint8_t *data, size_t datalen, + void *user_data) +{ + (void)offset; (void)user_data; - + if(ngtcp2_crypto_read_write_crypto_data(tconn, crypto_level, data, - datalen) != 0) - return NGTCP2_ERR_CRYPTO; - - return 0; -} - -static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data) -{ - struct quicsocket *qs = (struct quicsocket *)user_data; - (void)tconn; - infof(qs->conn->data, "QUIC handshake is completed\n"); - - return 0; -} - + datalen) != 0) + return NGTCP2_ERR_CRYPTO; + + return 0; +} + +static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data) +{ + struct quicsocket *qs = (struct quicsocket *)user_data; + (void)tconn; + infof(qs->conn->data, "QUIC handshake is completed\n"); + + return 0; +} + static void extend_stream_window(ngtcp2_conn *tconn, struct HTTP *stream) { @@ -575,298 +575,298 @@ static void extend_stream_window(ngtcp2_conn *tconn, static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags, int64_t stream_id, uint64_t offset, - const uint8_t *buf, size_t buflen, - void *user_data, void *stream_user_data) -{ - struct quicsocket *qs = (struct quicsocket *)user_data; - ssize_t nconsumed; + const uint8_t *buf, size_t buflen, + void *user_data, void *stream_user_data) +{ + struct quicsocket *qs = (struct quicsocket *)user_data; + ssize_t nconsumed; int fin = flags & NGTCP2_STREAM_DATA_FLAG_FIN ? 1 : 0; - (void)offset; - (void)stream_user_data; - - nconsumed = - nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin); - if(nconsumed < 0) { - failf(qs->conn->data, "nghttp3_conn_read_stream returned error: %s\n", - nghttp3_strerror((int)nconsumed)); - return NGTCP2_ERR_CALLBACK_FAILURE; - } - + (void)offset; + (void)stream_user_data; + + nconsumed = + nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin); + if(nconsumed < 0) { + failf(qs->conn->data, "nghttp3_conn_read_stream returned error: %s\n", + nghttp3_strerror((int)nconsumed)); + return NGTCP2_ERR_CALLBACK_FAILURE; + } + /* number of bytes inside buflen which consists of framing overhead * including QPACK HEADERS. In other words, it does not consume payload of * DATA frame. */ - ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed); - ngtcp2_conn_extend_max_offset(tconn, nconsumed); - - return 0; -} - -static int -cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t offset, size_t datalen, void *user_data, - void *stream_user_data) -{ - struct quicsocket *qs = (struct quicsocket *)user_data; - int rv; - (void)stream_id; - (void)tconn; - (void)offset; - (void)datalen; - (void)stream_user_data; - - rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen); - if(rv != 0) { - failf(qs->conn->data, "nghttp3_conn_add_ack_offset returned error: %s\n", - nghttp3_strerror(rv)); - return NGTCP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t app_error_code, - void *user_data, void *stream_user_data) -{ - struct quicsocket *qs = (struct quicsocket *)user_data; - int rv; - (void)tconn; - (void)stream_user_data; - /* stream is closed... */ - - rv = nghttp3_conn_close_stream(qs->h3conn, stream_id, - app_error_code); - if(rv != 0) { - failf(qs->conn->data, "nghttp3_conn_close_stream returned error: %s\n", - nghttp3_strerror(rv)); - return NGTCP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t final_size, uint64_t app_error_code, - void *user_data, void *stream_user_data) -{ - struct quicsocket *qs = (struct quicsocket *)user_data; - int rv; - (void)tconn; - (void)final_size; - (void)app_error_code; - (void)stream_user_data; - - rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id); - if(rv != 0) { - failf(qs->conn->data, "nghttp3_conn_reset_stream returned error: %s\n", - nghttp3_strerror(rv)); - return NGTCP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn, - uint64_t max_streams, - void *user_data) -{ - (void)tconn; - (void)max_streams; - (void)user_data; - - return 0; -} - -static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t max_data, void *user_data, - void *stream_user_data) -{ - struct quicsocket *qs = (struct quicsocket *)user_data; - int rv; - (void)tconn; - (void)max_data; - (void)stream_user_data; - - rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id); - if(rv != 0) { - failf(qs->conn->data, "nghttp3_conn_unblock_stream returned error: %s\n", - nghttp3_strerror(rv)); - return NGTCP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid, - uint8_t *token, size_t cidlen, - void *user_data) -{ - struct quicsocket *qs = (struct quicsocket *)user_data; - CURLcode result; - (void)tconn; - - result = Curl_rand(qs->conn->data, cid->data, cidlen); - if(result) - return NGTCP2_ERR_CALLBACK_FAILURE; - cid->datalen = cidlen; - - result = Curl_rand(qs->conn->data, token, NGTCP2_STATELESS_RESET_TOKENLEN); - if(result) - return NGTCP2_ERR_CALLBACK_FAILURE; - - return 0; -} - -static ngtcp2_conn_callbacks ng_callbacks = { + ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed); + ngtcp2_conn_extend_max_offset(tconn, nconsumed); + + return 0; +} + +static int +cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id, + uint64_t offset, size_t datalen, void *user_data, + void *stream_user_data) +{ + struct quicsocket *qs = (struct quicsocket *)user_data; + int rv; + (void)stream_id; + (void)tconn; + (void)offset; + (void)datalen; + (void)stream_user_data; + + rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen); + if(rv != 0) { + failf(qs->conn->data, "nghttp3_conn_add_ack_offset returned error: %s\n", + nghttp3_strerror(rv)); + return NGTCP2_ERR_CALLBACK_FAILURE; + } + + return 0; +} + +static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id, + uint64_t app_error_code, + void *user_data, void *stream_user_data) +{ + struct quicsocket *qs = (struct quicsocket *)user_data; + int rv; + (void)tconn; + (void)stream_user_data; + /* stream is closed... */ + + rv = nghttp3_conn_close_stream(qs->h3conn, stream_id, + app_error_code); + if(rv != 0) { + failf(qs->conn->data, "nghttp3_conn_close_stream returned error: %s\n", + nghttp3_strerror(rv)); + return NGTCP2_ERR_CALLBACK_FAILURE; + } + + return 0; +} + +static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id, + uint64_t final_size, uint64_t app_error_code, + void *user_data, void *stream_user_data) +{ + struct quicsocket *qs = (struct quicsocket *)user_data; + int rv; + (void)tconn; + (void)final_size; + (void)app_error_code; + (void)stream_user_data; + + rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id); + if(rv != 0) { + failf(qs->conn->data, "nghttp3_conn_reset_stream returned error: %s\n", + nghttp3_strerror(rv)); + return NGTCP2_ERR_CALLBACK_FAILURE; + } + + return 0; +} + +static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn, + uint64_t max_streams, + void *user_data) +{ + (void)tconn; + (void)max_streams; + (void)user_data; + + return 0; +} + +static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id, + uint64_t max_data, void *user_data, + void *stream_user_data) +{ + struct quicsocket *qs = (struct quicsocket *)user_data; + int rv; + (void)tconn; + (void)max_data; + (void)stream_user_data; + + rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id); + if(rv != 0) { + failf(qs->conn->data, "nghttp3_conn_unblock_stream returned error: %s\n", + nghttp3_strerror(rv)); + return NGTCP2_ERR_CALLBACK_FAILURE; + } + + return 0; +} + +static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid, + uint8_t *token, size_t cidlen, + void *user_data) +{ + struct quicsocket *qs = (struct quicsocket *)user_data; + CURLcode result; + (void)tconn; + + result = Curl_rand(qs->conn->data, cid->data, cidlen); + if(result) + return NGTCP2_ERR_CALLBACK_FAILURE; + cid->datalen = cidlen; + + result = Curl_rand(qs->conn->data, token, NGTCP2_STATELESS_RESET_TOKENLEN); + if(result) + return NGTCP2_ERR_CALLBACK_FAILURE; + + return 0; +} + +static ngtcp2_conn_callbacks ng_callbacks = { ngtcp2_crypto_client_initial_cb, - NULL, /* recv_client_initial */ - cb_recv_crypto_data, - cb_handshake_completed, - NULL, /* recv_version_negotiation */ - ngtcp2_crypto_encrypt_cb, - ngtcp2_crypto_decrypt_cb, - ngtcp2_crypto_hp_mask_cb, - cb_recv_stream_data, - NULL, /* acked_crypto_offset */ - cb_acked_stream_data_offset, - NULL, /* stream_open */ - cb_stream_close, - NULL, /* recv_stateless_reset */ + NULL, /* recv_client_initial */ + cb_recv_crypto_data, + cb_handshake_completed, + NULL, /* recv_version_negotiation */ + ngtcp2_crypto_encrypt_cb, + ngtcp2_crypto_decrypt_cb, + ngtcp2_crypto_hp_mask_cb, + cb_recv_stream_data, + NULL, /* acked_crypto_offset */ + cb_acked_stream_data_offset, + NULL, /* stream_open */ + cb_stream_close, + NULL, /* recv_stateless_reset */ ngtcp2_crypto_recv_retry_cb, - cb_extend_max_local_streams_bidi, - NULL, /* extend_max_local_streams_uni */ - NULL, /* rand */ - cb_get_new_connection_id, - NULL, /* remove_connection_id */ + cb_extend_max_local_streams_bidi, + NULL, /* extend_max_local_streams_uni */ + NULL, /* rand */ + cb_get_new_connection_id, + NULL, /* remove_connection_id */ ngtcp2_crypto_update_key_cb, /* update_key */ - NULL, /* path_validation */ - NULL, /* select_preferred_addr */ - cb_stream_reset, - NULL, /* extend_max_remote_streams_bidi */ - NULL, /* extend_max_remote_streams_uni */ - cb_extend_max_stream_data, + NULL, /* path_validation */ + NULL, /* select_preferred_addr */ + cb_stream_reset, + NULL, /* extend_max_remote_streams_bidi */ + NULL, /* extend_max_remote_streams_uni */ + cb_extend_max_stream_data, NULL, /* dcid_status */ NULL, /* handshake_confirmed */ NULL, /* recv_new_token */ ngtcp2_crypto_delete_crypto_aead_ctx_cb, ngtcp2_crypto_delete_crypto_cipher_ctx_cb -}; - -/* - * Might be called twice for happy eyeballs. - */ -CURLcode Curl_quic_connect(struct connectdata *conn, - curl_socket_t sockfd, - int sockindex, - const struct sockaddr *addr, - socklen_t addrlen) -{ - int rc; - int rv; - CURLcode result; - ngtcp2_path path; /* TODO: this must be initialized properly */ - struct Curl_easy *data = conn->data; - struct quicsocket *qs = &conn->hequic[sockindex]; - char ipbuf[40]; - long port; +}; + +/* + * Might be called twice for happy eyeballs. + */ +CURLcode Curl_quic_connect(struct connectdata *conn, + curl_socket_t sockfd, + int sockindex, + const struct sockaddr *addr, + socklen_t addrlen) +{ + int rc; + int rv; + CURLcode result; + ngtcp2_path path; /* TODO: this must be initialized properly */ + struct Curl_easy *data = conn->data; + struct quicsocket *qs = &conn->hequic[sockindex]; + char ipbuf[40]; + long port; int qfd; - + if(qs->conn) Curl_quic_disconnect(conn, sockindex); - qs->conn = conn; - - /* extract the used address as a string */ - if(!Curl_addr2string((struct sockaddr*)addr, addrlen, ipbuf, &port)) { - char buffer[STRERROR_LEN]; - failf(data, "ssrem inet_ntop() failed with errno %d: %s", + qs->conn = conn; + + /* extract the used address as a string */ + if(!Curl_addr2string((struct sockaddr*)addr, addrlen, ipbuf, &port)) { + char buffer[STRERROR_LEN]; + failf(data, "ssrem inet_ntop() failed with errno %d: %s", SOCKERRNO, Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - infof(data, "Connect socket %d over QUIC to %s:%ld\n", - sockfd, ipbuf, port); - + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + infof(data, "Connect socket %d over QUIC to %s:%ld\n", + sockfd, ipbuf, port); + qs->version = NGTCP2_PROTO_VER_MAX; #ifdef USE_OPENSSL - qs->sslctx = quic_ssl_ctx(data); - if(!qs->sslctx) + qs->sslctx = quic_ssl_ctx(data); + if(!qs->sslctx) return CURLE_QUIC_CONNECT_ERROR; #endif - - if(quic_init_ssl(qs)) + + if(quic_init_ssl(qs)) return CURLE_QUIC_CONNECT_ERROR; - - qs->dcid.datalen = NGTCP2_MAX_CIDLEN; - result = Curl_rand(data, qs->dcid.data, NGTCP2_MAX_CIDLEN); - if(result) - return result; - - qs->scid.datalen = NGTCP2_MAX_CIDLEN; - result = Curl_rand(data, qs->scid.data, NGTCP2_MAX_CIDLEN); - if(result) - return result; - + + qs->dcid.datalen = NGTCP2_MAX_CIDLEN; + result = Curl_rand(data, qs->dcid.data, NGTCP2_MAX_CIDLEN); + if(result) + return result; + + qs->scid.datalen = NGTCP2_MAX_CIDLEN; + result = Curl_rand(data, qs->scid.data, NGTCP2_MAX_CIDLEN); + if(result) + return result; + (void)Curl_qlogdir(data, qs->scid.data, NGTCP2_MAX_CIDLEN, &qfd); qs->qlogfd = qfd; /* -1 if failure above */ quic_settings(qs, data->set.buffer_size); - - qs->local_addrlen = sizeof(qs->local_addr); - rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr, - &qs->local_addrlen); - if(rv == -1) + + qs->local_addrlen = sizeof(qs->local_addr); + rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr, + &qs->local_addrlen); + if(rv == -1) return CURLE_QUIC_CONNECT_ERROR; - + ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr, qs->local_addrlen, NULL); ngtcp2_addr_init(&path.remote, addr, addrlen, NULL); - + rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, NGTCP2_PROTO_VER_MIN, &ng_callbacks, &qs->settings, NULL, qs); - if(rc) + if(rc) return CURLE_QUIC_CONNECT_ERROR; - + ngtcp2_conn_set_tls_native_handle(qs->qconn, qs->ssl); - - return CURLE_OK; -} - -/* - * Store ngtp2 version info in this buffer, Prefix with a space. Return total - * length written. - */ -int Curl_quic_ver(char *p, size_t len) -{ - ngtcp2_info *ng2 = ngtcp2_version(0); - nghttp3_info *ht3 = nghttp3_version(0); + + return CURLE_OK; +} + +/* + * Store ngtp2 version info in this buffer, Prefix with a space. Return total + * length written. + */ +int Curl_quic_ver(char *p, size_t len) +{ + ngtcp2_info *ng2 = ngtcp2_version(0); + nghttp3_info *ht3 = nghttp3_version(0); return msnprintf(p, len, "ngtcp2/%s nghttp3/%s", - ng2->version_str, ht3->version_str); -} - -static int ng_getsock(struct connectdata *conn, curl_socket_t *socks) -{ - struct SingleRequest *k = &conn->data->req; - int bitmap = GETSOCK_BLANK; - - socks[0] = conn->sock[FIRSTSOCKET]; - - /* in a HTTP/2 connection we can basically always get a frame so we should - always be ready for one */ - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - - /* we're still uploading or the HTTP/2 layer wants to send data */ - if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - return bitmap; -} - -static int ng_perform_getsock(const struct connectdata *conn, - curl_socket_t *socks) -{ - return ng_getsock((struct connectdata *)conn, socks); -} - + ng2->version_str, ht3->version_str); +} + +static int ng_getsock(struct connectdata *conn, curl_socket_t *socks) +{ + struct SingleRequest *k = &conn->data->req; + int bitmap = GETSOCK_BLANK; + + socks[0] = conn->sock[FIRSTSOCKET]; + + /* in a HTTP/2 connection we can basically always get a frame so we should + always be ready for one */ + bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); + + /* we're still uploading or the HTTP/2 layer wants to send data */ + if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) + bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); + + return bitmap; +} + +static int ng_perform_getsock(const struct connectdata *conn, + curl_socket_t *socks) +{ + return ng_getsock((struct connectdata *)conn, socks); +} + static void qs_disconnect(struct quicsocket *qs) { int i; @@ -904,65 +904,65 @@ void Curl_quic_disconnect(struct connectdata *conn, qs_disconnect(&conn->hequic[tempindex]); } -static CURLcode ng_disconnect(struct connectdata *conn, - bool dead_connection) -{ - (void)dead_connection; +static CURLcode ng_disconnect(struct connectdata *conn, + bool dead_connection) +{ + (void)dead_connection; Curl_quic_disconnect(conn, 0); Curl_quic_disconnect(conn, 1); - return CURLE_OK; -} - -static unsigned int ng_conncheck(struct connectdata *conn, - unsigned int checks_to_perform) -{ - (void)conn; - (void)checks_to_perform; - return CONNRESULT_NONE; -} - -static const struct Curl_handler Curl_handler_http3 = { - "HTTPS", /* scheme */ - ZERO_NULL, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ng_getsock, /* proto_getsock */ - ng_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ng_perform_getsock, /* perform_getsock */ - ng_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - ng_conncheck, /* connection_check */ - PORT_HTTP, /* defport */ - CURLPROTO_HTTPS, /* protocol */ + return CURLE_OK; +} + +static unsigned int ng_conncheck(struct connectdata *conn, + unsigned int checks_to_perform) +{ + (void)conn; + (void)checks_to_perform; + return CONNRESULT_NONE; +} + +static const struct Curl_handler Curl_handler_http3 = { + "HTTPS", /* scheme */ + ZERO_NULL, /* setup_connection */ + Curl_http, /* do_it */ + Curl_http_done, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ng_getsock, /* proto_getsock */ + ng_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ng_perform_getsock, /* perform_getsock */ + ng_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ng_conncheck, /* connection_check */ + PORT_HTTP, /* defport */ + CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ - PROTOPT_SSL | PROTOPT_STREAM /* flags */ -}; - -static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, - uint64_t app_error_code, void *user_data, - void *stream_user_data) -{ - struct Curl_easy *data = stream_user_data; + PROTOPT_SSL | PROTOPT_STREAM /* flags */ +}; + +static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, + uint64_t app_error_code, void *user_data, + void *stream_user_data) +{ + struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.p.http; - (void)conn; - (void)stream_id; - (void)app_error_code; - (void)user_data; + (void)conn; + (void)stream_id; + (void)app_error_code; + (void)user_data; H3BUGF(infof(data, "cb_h3_stream_close CALLED\n")); - - stream->closed = TRUE; - Curl_expire(data, 0, EXPIRE_QUIC); + + stream->closed = TRUE; + Curl_expire(data, 0, EXPIRE_QUIC); /* make sure that ngh3_stream_recv is called again to complete the transfer even if there are no more packets to be received from the server. */ data->state.drain = 1; - return 0; -} - + return 0; +} + /* * write_data() copies data to the stream's receive buffer. If not enough * space is available in the receive buffer, it copies the rest to the @@ -989,116 +989,116 @@ static CURLcode write_data(struct HTTP *stream, const void *mem, size_t memlen) return result; } -static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id, - const uint8_t *buf, size_t buflen, - void *user_data, void *stream_user_data) -{ - struct Curl_easy *data = stream_user_data; +static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id, + const uint8_t *buf, size_t buflen, + void *user_data, void *stream_user_data) +{ + struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.p.http; CURLcode result = CURLE_OK; - (void)conn; - + (void)conn; + result = write_data(stream, buf, buflen); if(result) { return -1; - } + } stream->unacked_window += buflen; (void)stream_id; (void)user_data; - return 0; -} - -static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream_id, - size_t consumed, void *user_data, - void *stream_user_data) -{ - struct quicsocket *qs = user_data; - (void)conn; - (void)stream_user_data; + return 0; +} + +static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream_id, + size_t consumed, void *user_data, + void *stream_user_data) +{ + struct quicsocket *qs = user_data; + (void)conn; + (void)stream_user_data; (void)stream_id; - - ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, consumed); - ngtcp2_conn_extend_max_offset(qs->qconn, consumed); - return 0; -} - -/* Decode HTTP status code. Returns -1 if no valid status code was - decoded. (duplicate from http2.c) */ -static int decode_status_code(const uint8_t *value, size_t len) -{ - int i; - int res; - - if(len != 3) { - return -1; - } - - res = 0; - - for(i = 0; i < 3; ++i) { - char c = value[i]; - - if(c < '0' || c > '9') { - return -1; - } - - res *= 10; - res += c - '0'; - } - - return res; -} - -static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id, - void *user_data, void *stream_user_data) -{ - struct Curl_easy *data = stream_user_data; + + ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, consumed); + ngtcp2_conn_extend_max_offset(qs->qconn, consumed); + return 0; +} + +/* Decode HTTP status code. Returns -1 if no valid status code was + decoded. (duplicate from http2.c) */ +static int decode_status_code(const uint8_t *value, size_t len) +{ + int i; + int res; + + if(len != 3) { + return -1; + } + + res = 0; + + for(i = 0; i < 3; ++i) { + char c = value[i]; + + if(c < '0' || c > '9') { + return -1; + } + + res *= 10; + res += c - '0'; + } + + return res; +} + +static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id, + void *user_data, void *stream_user_data) +{ + struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.p.http; CURLcode result = CURLE_OK; - (void)conn; - (void)stream_id; - (void)user_data; - + (void)conn; + (void)stream_id; + (void)user_data; + /* add a CRLF only if we've received some headers */ if(stream->firstheader) { result = write_data(stream, "\r\n", 2); if(result) { return -1; } - } - return 0; -} - -static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, - int32_t token, nghttp3_rcbuf *name, - nghttp3_rcbuf *value, uint8_t flags, - void *user_data, void *stream_user_data) -{ - nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name); - nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value); - struct Curl_easy *data = stream_user_data; + } + return 0; +} + +static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, + int32_t token, nghttp3_rcbuf *name, + nghttp3_rcbuf *value, uint8_t flags, + void *user_data, void *stream_user_data) +{ + nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name); + nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value); + struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.p.http; CURLcode result = CURLE_OK; - (void)conn; - (void)stream_id; - (void)token; - (void)flags; - (void)user_data; - - if(h3name.len == sizeof(":status") - 1 && - !memcmp(":status", h3name.base, h3name.len)) { + (void)conn; + (void)stream_id; + (void)token; + (void)flags; + (void)user_data; + + if(h3name.len == sizeof(":status") - 1 && + !memcmp(":status", h3name.base, h3name.len)) { char line[14]; /* status line is always 13 characters long */ size_t ncopy; - int status = decode_status_code(h3val.base, h3val.len); - DEBUGASSERT(status != -1); + int status = decode_status_code(h3val.base, h3val.len); + DEBUGASSERT(status != -1); ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", status); result = write_data(stream, line, ncopy); if(result) { return -1; } - } - else { - /* store as a HTTP1-style header */ + } + else { + /* store as a HTTP1-style header */ result = write_data(stream, h3name.base, h3name.len); if(result) { return -1; @@ -1115,109 +1115,109 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, if(result) { return -1; } - } - + } + stream->firstheader = TRUE; - return 0; -} - -static int cb_h3_send_stop_sending(nghttp3_conn *conn, int64_t stream_id, - uint64_t app_error_code, - void *user_data, - void *stream_user_data) -{ - (void)conn; - (void)stream_id; - (void)app_error_code; - (void)user_data; - (void)stream_user_data; - return 0; -} - -static nghttp3_conn_callbacks ngh3_callbacks = { - cb_h3_acked_stream_data, /* acked_stream_data */ - cb_h3_stream_close, - cb_h3_recv_data, - cb_h3_deferred_consume, - NULL, /* begin_headers */ - cb_h3_recv_header, - cb_h3_end_headers, - NULL, /* begin_trailers */ - cb_h3_recv_header, - NULL, /* end_trailers */ - NULL, /* http_begin_push_promise */ - NULL, /* http_recv_push_promise */ - NULL, /* http_end_push_promise */ - NULL, /* http_cancel_push */ - cb_h3_send_stop_sending, - NULL, /* push_stream */ - NULL, /* end_stream */ + return 0; +} + +static int cb_h3_send_stop_sending(nghttp3_conn *conn, int64_t stream_id, + uint64_t app_error_code, + void *user_data, + void *stream_user_data) +{ + (void)conn; + (void)stream_id; + (void)app_error_code; + (void)user_data; + (void)stream_user_data; + return 0; +} + +static nghttp3_conn_callbacks ngh3_callbacks = { + cb_h3_acked_stream_data, /* acked_stream_data */ + cb_h3_stream_close, + cb_h3_recv_data, + cb_h3_deferred_consume, + NULL, /* begin_headers */ + cb_h3_recv_header, + cb_h3_end_headers, + NULL, /* begin_trailers */ + cb_h3_recv_header, + NULL, /* end_trailers */ + NULL, /* http_begin_push_promise */ + NULL, /* http_recv_push_promise */ + NULL, /* http_end_push_promise */ + NULL, /* http_cancel_push */ + cb_h3_send_stop_sending, + NULL, /* push_stream */ + NULL, /* end_stream */ NULL, /* reset_stream */ -}; - -static int init_ngh3_conn(struct quicsocket *qs) -{ - CURLcode result; - int rc; - int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id; - - if(ngtcp2_conn_get_max_local_streams_uni(qs->qconn) < 3) { - failf(qs->conn->data, "too few available QUIC streams"); +}; + +static int init_ngh3_conn(struct quicsocket *qs) +{ + CURLcode result; + int rc; + int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id; + + if(ngtcp2_conn_get_max_local_streams_uni(qs->qconn) < 3) { + failf(qs->conn->data, "too few available QUIC streams"); return CURLE_QUIC_CONNECT_ERROR; - } - - nghttp3_conn_settings_default(&qs->h3settings); - - rc = nghttp3_conn_client_new(&qs->h3conn, - &ngh3_callbacks, - &qs->h3settings, - nghttp3_mem_default(), - qs); - if(rc) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - rc = ngtcp2_conn_open_uni_stream(qs->qconn, &ctrl_stream_id, NULL); - if(rc) { + } + + nghttp3_conn_settings_default(&qs->h3settings); + + rc = nghttp3_conn_client_new(&qs->h3conn, + &ngh3_callbacks, + &qs->h3settings, + nghttp3_mem_default(), + qs); + if(rc) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + rc = ngtcp2_conn_open_uni_stream(qs->qconn, &ctrl_stream_id, NULL); + if(rc) { result = CURLE_QUIC_CONNECT_ERROR; - goto fail; - } - - rc = nghttp3_conn_bind_control_stream(qs->h3conn, ctrl_stream_id); - if(rc) { + goto fail; + } + + rc = nghttp3_conn_bind_control_stream(qs->h3conn, ctrl_stream_id); + if(rc) { result = CURLE_QUIC_CONNECT_ERROR; - goto fail; - } - - rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_enc_stream_id, NULL); - if(rc) { + goto fail; + } + + rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_enc_stream_id, NULL); + if(rc) { result = CURLE_QUIC_CONNECT_ERROR; - goto fail; - } - - rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_dec_stream_id, NULL); - if(rc) { + goto fail; + } + + rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_dec_stream_id, NULL); + if(rc) { result = CURLE_QUIC_CONNECT_ERROR; - goto fail; - } - - rc = nghttp3_conn_bind_qpack_streams(qs->h3conn, qpack_enc_stream_id, - qpack_dec_stream_id); - if(rc) { + goto fail; + } + + rc = nghttp3_conn_bind_qpack_streams(qs->h3conn, qpack_enc_stream_id, + qpack_dec_stream_id); + if(rc) { result = CURLE_QUIC_CONNECT_ERROR; - goto fail; - } - - return CURLE_OK; - fail: - - return result; -} - -static Curl_recv ngh3_stream_recv; -static Curl_send ngh3_stream_send; - + goto fail; + } + + return CURLE_OK; + fail: + + return result; +} + +static Curl_recv ngh3_stream_recv; +static Curl_send ngh3_stream_send; + static size_t drain_overflow_buffer(struct HTTP *stream) { size_t overlen = Curl_dyn_len(&stream->overflow); @@ -1234,46 +1234,46 @@ static size_t drain_overflow_buffer(struct HTTP *stream) return ncopy; } -/* incoming data frames on the h3 stream */ -static ssize_t ngh3_stream_recv(struct connectdata *conn, - int sockindex, - char *buf, - size_t buffersize, - CURLcode *curlcode) -{ - curl_socket_t sockfd = conn->sock[sockindex]; +/* incoming data frames on the h3 stream */ +static ssize_t ngh3_stream_recv(struct connectdata *conn, + int sockindex, + char *buf, + size_t buffersize, + CURLcode *curlcode) +{ + curl_socket_t sockfd = conn->sock[sockindex]; struct HTTP *stream = conn->data->req.p.http; - struct quicsocket *qs = conn->quic; - - if(!stream->memlen) { - /* remember where to store incoming data for this stream and how big the - buffer is */ - stream->mem = buf; - stream->len = buffersize; - } - /* else, there's data in the buffer already */ - + struct quicsocket *qs = conn->quic; + + if(!stream->memlen) { + /* remember where to store incoming data for this stream and how big the + buffer is */ + stream->mem = buf; + stream->len = buffersize; + } + /* else, there's data in the buffer already */ + /* if there's data in the overflow buffer from a previous call, copy as much as possible to the receive buffer before receiving more */ drain_overflow_buffer(stream); - if(ng_process_ingress(conn, sockfd, qs)) { - *curlcode = CURLE_RECV_ERROR; - return -1; - } - if(ng_flush_egress(conn, sockfd, qs)) { - *curlcode = CURLE_SEND_ERROR; - return -1; - } - - if(stream->memlen) { - ssize_t memlen = stream->memlen; - /* data arrived */ - *curlcode = CURLE_OK; - /* reset to allow more data to come */ - stream->memlen = 0; - stream->mem = buf; - stream->len = buffersize; + if(ng_process_ingress(conn, sockfd, qs)) { + *curlcode = CURLE_RECV_ERROR; + return -1; + } + if(ng_flush_egress(conn, sockfd, qs)) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } + + if(stream->memlen) { + ssize_t memlen = stream->memlen; + /* data arrived */ + *curlcode = CURLE_OK; + /* reset to allow more data to come */ + stream->memlen = 0; + stream->mem = buf; + stream->len = buffersize; /* extend the stream window with the data we're consuming and send out any additional packets to tell the server that we can receive more */ extend_stream_window(qs->qconn, stream); @@ -1281,632 +1281,632 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn, *curlcode = CURLE_SEND_ERROR; return -1; } - return memlen; - } - - if(stream->closed) { - *curlcode = CURLE_OK; - return 0; - } - - infof(conn->data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n"); - *curlcode = CURLE_AGAIN; - return -1; -} - -/* this amount of data has now been acked on this stream */ -static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, - size_t datalen, void *user_data, - void *stream_user_data) -{ - struct Curl_easy *data = stream_user_data; + return memlen; + } + + if(stream->closed) { + *curlcode = CURLE_OK; + return 0; + } + + infof(conn->data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n"); + *curlcode = CURLE_AGAIN; + return -1; +} + +/* this amount of data has now been acked on this stream */ +static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, + size_t datalen, void *user_data, + void *stream_user_data) +{ + struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.p.http; - (void)conn; - (void)stream_id; - (void)user_data; - - if(!data->set.postfields) { - stream->h3out->used -= datalen; + (void)conn; + (void)stream_id; + (void)user_data; + + if(!data->set.postfields) { + stream->h3out->used -= datalen; H3BUGF(infof(data, "cb_h3_acked_stream_data, %zd bytes, %zd left unacked\n", datalen, stream->h3out->used)); - DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE); - } - return 0; -} - + DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE); + } + return 0; +} + static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id, nghttp3_vec *vec, size_t veccnt, uint32_t *pflags, void *user_data, void *stream_user_data) -{ - struct Curl_easy *data = stream_user_data; - size_t nread; +{ + struct Curl_easy *data = stream_user_data; + size_t nread; struct HTTP *stream = data->req.p.http; - (void)conn; - (void)stream_id; - (void)user_data; + (void)conn; + (void)stream_id; + (void)user_data; (void)veccnt; - - if(data->set.postfields) { + + if(data->set.postfields) { vec[0].base = data->set.postfields; vec[0].len = data->state.infilesize; - *pflags = NGHTTP3_DATA_FLAG_EOF; + *pflags = NGHTTP3_DATA_FLAG_EOF; return 1; - } - - nread = CURLMIN(stream->upload_len, H3_SEND_SIZE - stream->h3out->used); - if(nread > 0) { - /* nghttp3 wants us to hold on to the data until it tells us it is okay to - delete it. Append the data at the end of the h3out buffer. Since we can - only return consecutive data, copy the amount that fits and the next - part comes in next invoke. */ - struct h3out *out = stream->h3out; - if(nread + out->windex > H3_SEND_SIZE) - nread = H3_SEND_SIZE - out->windex; - - memcpy(&out->buf[out->windex], stream->upload_mem, nread); - out->windex += nread; - out->used += nread; - - /* that's the chunk we return to nghttp3 */ + } + + nread = CURLMIN(stream->upload_len, H3_SEND_SIZE - stream->h3out->used); + if(nread > 0) { + /* nghttp3 wants us to hold on to the data until it tells us it is okay to + delete it. Append the data at the end of the h3out buffer. Since we can + only return consecutive data, copy the amount that fits and the next + part comes in next invoke. */ + struct h3out *out = stream->h3out; + if(nread + out->windex > H3_SEND_SIZE) + nread = H3_SEND_SIZE - out->windex; + + memcpy(&out->buf[out->windex], stream->upload_mem, nread); + out->windex += nread; + out->used += nread; + + /* that's the chunk we return to nghttp3 */ vec[0].base = &out->buf[out->windex]; vec[0].len = nread; - - if(out->windex == H3_SEND_SIZE) - out->windex = 0; /* wrap */ - stream->upload_mem += nread; - stream->upload_len -= nread; - if(data->state.infilesize != -1) { - stream->upload_left -= nread; - if(!stream->upload_left) - *pflags = NGHTTP3_DATA_FLAG_EOF; - } + + if(out->windex == H3_SEND_SIZE) + out->windex = 0; /* wrap */ + stream->upload_mem += nread; + stream->upload_len -= nread; + if(data->state.infilesize != -1) { + stream->upload_left -= nread; + if(!stream->upload_left) + *pflags = NGHTTP3_DATA_FLAG_EOF; + } H3BUGF(infof(data, "cb_h3_readfunction %zd bytes%s (at %zd unacked)\n", nread, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"", out->used)); - } - if(stream->upload_done && !stream->upload_len && - (stream->upload_left <= 0)) { - H3BUGF(infof(data, "!!!!!!!!! cb_h3_readfunction sets EOF\n")); - *pflags = NGHTTP3_DATA_FLAG_EOF; + } + if(stream->upload_done && !stream->upload_len && + (stream->upload_left <= 0)) { + H3BUGF(infof(data, "!!!!!!!!! cb_h3_readfunction sets EOF\n")); + *pflags = NGHTTP3_DATA_FLAG_EOF; return 0; - } - else if(!nread) { - return NGHTTP3_ERR_WOULDBLOCK; - } + } + else if(!nread) { + return NGHTTP3_ERR_WOULDBLOCK; + } return 1; -} - -/* Index where :authority header field will appear in request header - field list. */ -#define AUTHORITY_DST_IDX 3 - -static CURLcode http_request(struct connectdata *conn, const void *mem, - size_t len) -{ +} + +/* Index where :authority header field will appear in request header + field list. */ +#define AUTHORITY_DST_IDX 3 + +static CURLcode http_request(struct connectdata *conn, const void *mem, + size_t len) +{ struct HTTP *stream = conn->data->req.p.http; - size_t nheader; - size_t i; - size_t authority_idx; - char *hdbuf = (char *)mem; - char *end, *line_end; - struct quicsocket *qs = conn->quic; - CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - nghttp3_nv *nva = NULL; - int64_t stream3_id; - int rc; - struct h3out *h3out = NULL; - - rc = ngtcp2_conn_open_bidi_stream(qs->qconn, &stream3_id, NULL); - if(rc) { - failf(conn->data, "can get bidi streams"); - result = CURLE_SEND_ERROR; - goto fail; - } - - stream->stream3_id = stream3_id; - stream->h3req = TRUE; /* senf off! */ + size_t nheader; + size_t i; + size_t authority_idx; + char *hdbuf = (char *)mem; + char *end, *line_end; + struct quicsocket *qs = conn->quic; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + nghttp3_nv *nva = NULL; + int64_t stream3_id; + int rc; + struct h3out *h3out = NULL; + + rc = ngtcp2_conn_open_bidi_stream(qs->qconn, &stream3_id, NULL); + if(rc) { + failf(conn->data, "can get bidi streams"); + result = CURLE_SEND_ERROR; + goto fail; + } + + stream->stream3_id = stream3_id; + stream->h3req = TRUE; /* senf off! */ Curl_dyn_init(&stream->overflow, CURL_MAX_READ_SIZE); - - /* Calculate number of headers contained in [mem, mem + len). Assumes a - correctly generated HTTP header field block. */ - nheader = 0; - for(i = 1; i < len; ++i) { - if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') { - ++nheader; - ++i; - } - } - if(nheader < 2) - goto fail; - - /* We counted additional 2 \r\n in the first and last line. We need 3 - new headers: :method, :path and :scheme. Therefore we need one - more space. */ - nheader += 1; - nva = malloc(sizeof(nghttp3_nv) * nheader); - if(!nva) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - /* Extract :method, :path from request line - We do line endings with CRLF so checking for CR is enough */ - line_end = memchr(hdbuf, '\r', len); - if(!line_end) { - result = CURLE_BAD_FUNCTION_ARGUMENT; /* internal error */ - goto fail; - } - - /* Method does not contain spaces */ - end = memchr(hdbuf, ' ', line_end - hdbuf); - if(!end || end == hdbuf) - goto fail; - nva[0].name = (unsigned char *)":method"; - nva[0].namelen = strlen((char *)nva[0].name); - nva[0].value = (unsigned char *)hdbuf; - nva[0].valuelen = (size_t)(end - hdbuf); - nva[0].flags = NGHTTP3_NV_FLAG_NONE; - - hdbuf = end + 1; - - /* Path may contain spaces so scan backwards */ - end = NULL; - for(i = (size_t)(line_end - hdbuf); i; --i) { - if(hdbuf[i - 1] == ' ') { - end = &hdbuf[i - 1]; - break; - } - } - if(!end || end == hdbuf) - goto fail; - nva[1].name = (unsigned char *)":path"; - nva[1].namelen = strlen((char *)nva[1].name); - nva[1].value = (unsigned char *)hdbuf; - nva[1].valuelen = (size_t)(end - hdbuf); - nva[1].flags = NGHTTP3_NV_FLAG_NONE; - - nva[2].name = (unsigned char *)":scheme"; - nva[2].namelen = strlen((char *)nva[2].name); - if(conn->handler->flags & PROTOPT_SSL) - nva[2].value = (unsigned char *)"https"; - else - nva[2].value = (unsigned char *)"http"; - nva[2].valuelen = strlen((char *)nva[2].value); - nva[2].flags = NGHTTP3_NV_FLAG_NONE; - - - authority_idx = 0; - i = 3; - while(i < nheader) { - size_t hlen; - - hdbuf = line_end + 2; - - /* check for next CR, but only within the piece of data left in the given - buffer */ - line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem)); - if(!line_end || (line_end == hdbuf)) - goto fail; - - /* header continuation lines are not supported */ - if(*hdbuf == ' ' || *hdbuf == '\t') - goto fail; - - for(end = hdbuf; end < line_end && *end != ':'; ++end) - ; - if(end == hdbuf || end == line_end) - goto fail; - hlen = end - hdbuf; - - if(hlen == 4 && strncasecompare("host", hdbuf, 4)) { - authority_idx = i; - nva[i].name = (unsigned char *)":authority"; - nva[i].namelen = strlen((char *)nva[i].name); - } - else { + + /* Calculate number of headers contained in [mem, mem + len). Assumes a + correctly generated HTTP header field block. */ + nheader = 0; + for(i = 1; i < len; ++i) { + if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') { + ++nheader; + ++i; + } + } + if(nheader < 2) + goto fail; + + /* We counted additional 2 \r\n in the first and last line. We need 3 + new headers: :method, :path and :scheme. Therefore we need one + more space. */ + nheader += 1; + nva = malloc(sizeof(nghttp3_nv) * nheader); + if(!nva) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + /* Extract :method, :path from request line + We do line endings with CRLF so checking for CR is enough */ + line_end = memchr(hdbuf, '\r', len); + if(!line_end) { + result = CURLE_BAD_FUNCTION_ARGUMENT; /* internal error */ + goto fail; + } + + /* Method does not contain spaces */ + end = memchr(hdbuf, ' ', line_end - hdbuf); + if(!end || end == hdbuf) + goto fail; + nva[0].name = (unsigned char *)":method"; + nva[0].namelen = strlen((char *)nva[0].name); + nva[0].value = (unsigned char *)hdbuf; + nva[0].valuelen = (size_t)(end - hdbuf); + nva[0].flags = NGHTTP3_NV_FLAG_NONE; + + hdbuf = end + 1; + + /* Path may contain spaces so scan backwards */ + end = NULL; + for(i = (size_t)(line_end - hdbuf); i; --i) { + if(hdbuf[i - 1] == ' ') { + end = &hdbuf[i - 1]; + break; + } + } + if(!end || end == hdbuf) + goto fail; + nva[1].name = (unsigned char *)":path"; + nva[1].namelen = strlen((char *)nva[1].name); + nva[1].value = (unsigned char *)hdbuf; + nva[1].valuelen = (size_t)(end - hdbuf); + nva[1].flags = NGHTTP3_NV_FLAG_NONE; + + nva[2].name = (unsigned char *)":scheme"; + nva[2].namelen = strlen((char *)nva[2].name); + if(conn->handler->flags & PROTOPT_SSL) + nva[2].value = (unsigned char *)"https"; + else + nva[2].value = (unsigned char *)"http"; + nva[2].valuelen = strlen((char *)nva[2].value); + nva[2].flags = NGHTTP3_NV_FLAG_NONE; + + + authority_idx = 0; + i = 3; + while(i < nheader) { + size_t hlen; + + hdbuf = line_end + 2; + + /* check for next CR, but only within the piece of data left in the given + buffer */ + line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem)); + if(!line_end || (line_end == hdbuf)) + goto fail; + + /* header continuation lines are not supported */ + if(*hdbuf == ' ' || *hdbuf == '\t') + goto fail; + + for(end = hdbuf; end < line_end && *end != ':'; ++end) + ; + if(end == hdbuf || end == line_end) + goto fail; + hlen = end - hdbuf; + + if(hlen == 4 && strncasecompare("host", hdbuf, 4)) { + authority_idx = i; + nva[i].name = (unsigned char *)":authority"; + nva[i].namelen = strlen((char *)nva[i].name); + } + else { nva[i].namelen = (size_t)(end - hdbuf); /* Lower case the header name for HTTP/3 */ Curl_strntolower((char *)hdbuf, hdbuf, nva[i].namelen); - nva[i].name = (unsigned char *)hdbuf; - } - nva[i].flags = NGHTTP3_NV_FLAG_NONE; - hdbuf = end + 1; - while(*hdbuf == ' ' || *hdbuf == '\t') - ++hdbuf; - end = line_end; - -#if 0 /* This should probably go in more or less like this */ - switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf, - end - hdbuf)) { - case HEADERINST_IGNORE: - /* skip header fields prohibited by HTTP/2 specification. */ - --nheader; - continue; - case HEADERINST_TE_TRAILERS: - nva[i].value = (uint8_t*)"trailers"; - nva[i].value_len = sizeof("trailers") - 1; - break; - default: - nva[i].value = (unsigned char *)hdbuf; - nva[i].value_len = (size_t)(end - hdbuf); - } -#endif - nva[i].value = (unsigned char *)hdbuf; - nva[i].valuelen = (size_t)(end - hdbuf); - nva[i].flags = NGHTTP3_NV_FLAG_NONE; - - ++i; - } - - /* :authority must come before non-pseudo header fields */ - if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { - nghttp3_nv authority = nva[authority_idx]; - for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { - nva[i] = nva[i - 1]; - } - nva[i] = authority; - } - - /* Warn stream may be rejected if cumulative length of headers is too - large. */ -#define MAX_ACC 60000 /* <64KB to account for some overhead */ - { - size_t acc = 0; - for(i = 0; i < nheader; ++i) - acc += nva[i].namelen + nva[i].valuelen; - - if(acc > MAX_ACC) { - infof(data, "http_request: Warning: The cumulative length of all " + nva[i].name = (unsigned char *)hdbuf; + } + nva[i].flags = NGHTTP3_NV_FLAG_NONE; + hdbuf = end + 1; + while(*hdbuf == ' ' || *hdbuf == '\t') + ++hdbuf; + end = line_end; + +#if 0 /* This should probably go in more or less like this */ + switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf, + end - hdbuf)) { + case HEADERINST_IGNORE: + /* skip header fields prohibited by HTTP/2 specification. */ + --nheader; + continue; + case HEADERINST_TE_TRAILERS: + nva[i].value = (uint8_t*)"trailers"; + nva[i].value_len = sizeof("trailers") - 1; + break; + default: + nva[i].value = (unsigned char *)hdbuf; + nva[i].value_len = (size_t)(end - hdbuf); + } +#endif + nva[i].value = (unsigned char *)hdbuf; + nva[i].valuelen = (size_t)(end - hdbuf); + nva[i].flags = NGHTTP3_NV_FLAG_NONE; + + ++i; + } + + /* :authority must come before non-pseudo header fields */ + if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { + nghttp3_nv authority = nva[authority_idx]; + for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { + nva[i] = nva[i - 1]; + } + nva[i] = authority; + } + + /* Warn stream may be rejected if cumulative length of headers is too + large. */ +#define MAX_ACC 60000 /* <64KB to account for some overhead */ + { + size_t acc = 0; + for(i = 0; i < nheader; ++i) + acc += nva[i].namelen + nva[i].valuelen; + + if(acc > MAX_ACC) { + infof(data, "http_request: Warning: The cumulative length of all " "headers exceeds %d bytes and that could cause the " - "stream to be rejected.\n", MAX_ACC); - } - } - + "stream to be rejected.\n", MAX_ACC); + } + } + switch(data->state.httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - case HTTPREQ_PUT: { - nghttp3_data_reader data_reader; - if(data->state.infilesize != -1) - stream->upload_left = data->state.infilesize; - else - /* data sending without specifying the data amount up front */ - stream->upload_left = -1; /* unknown, but not zero */ - - data_reader.read_data = cb_h3_readfunction; - - h3out = calloc(sizeof(struct h3out), 1); - if(!h3out) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - stream->h3out = h3out; - - rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id, - nva, nheader, &data_reader, - conn->data); - if(rc) { - result = CURLE_SEND_ERROR; - goto fail; - } - break; - } - default: - stream->upload_left = 0; /* nothing left to send */ - rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id, - nva, nheader, - NULL, /* no body! */ - conn->data); - if(rc) { - result = CURLE_SEND_ERROR; - goto fail; - } - break; - } - - Curl_safefree(nva); - - infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n", - stream3_id, (void *)data); - - return CURLE_OK; - -fail: - free(nva); - return result; -} -static ssize_t ngh3_stream_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - ssize_t sent; - struct quicsocket *qs = conn->quic; - curl_socket_t sockfd = conn->sock[sockindex]; + case HTTPREQ_POST: + case HTTPREQ_POST_FORM: + case HTTPREQ_POST_MIME: + case HTTPREQ_PUT: { + nghttp3_data_reader data_reader; + if(data->state.infilesize != -1) + stream->upload_left = data->state.infilesize; + else + /* data sending without specifying the data amount up front */ + stream->upload_left = -1; /* unknown, but not zero */ + + data_reader.read_data = cb_h3_readfunction; + + h3out = calloc(sizeof(struct h3out), 1); + if(!h3out) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + stream->h3out = h3out; + + rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id, + nva, nheader, &data_reader, + conn->data); + if(rc) { + result = CURLE_SEND_ERROR; + goto fail; + } + break; + } + default: + stream->upload_left = 0; /* nothing left to send */ + rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id, + nva, nheader, + NULL, /* no body! */ + conn->data); + if(rc) { + result = CURLE_SEND_ERROR; + goto fail; + } + break; + } + + Curl_safefree(nva); + + infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n", + stream3_id, (void *)data); + + return CURLE_OK; + +fail: + free(nva); + return result; +} +static ssize_t ngh3_stream_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + ssize_t sent; + struct quicsocket *qs = conn->quic; + curl_socket_t sockfd = conn->sock[sockindex]; struct HTTP *stream = conn->data->req.p.http; - - if(!stream->h3req) { - CURLcode result = http_request(conn, mem, len); - if(result) { - *curlcode = CURLE_SEND_ERROR; - return -1; - } - sent = len; - } - else { + + if(!stream->h3req) { + CURLcode result = http_request(conn, mem, len); + if(result) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } + sent = len; + } + else { H3BUGF(infof(conn->data, "ngh3_stream_send() wants to send %zd bytes\n", len)); - if(!stream->upload_len) { - stream->upload_mem = mem; - stream->upload_len = len; - (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id); - sent = len; - } - else { - *curlcode = CURLE_AGAIN; - return -1; - } - } - - if(ng_flush_egress(conn, sockfd, qs)) { - *curlcode = CURLE_SEND_ERROR; - return -1; - } - - *curlcode = CURLE_OK; - return sent; -} - -static void ng_has_connected(struct connectdata *conn, int tempindex) -{ - conn->recv[FIRSTSOCKET] = ngh3_stream_recv; - conn->send[FIRSTSOCKET] = ngh3_stream_send; - conn->handler = &Curl_handler_http3; - conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ - conn->httpversion = 30; - conn->bundle->multiuse = BUNDLE_MULTIPLEX; - conn->quic = &conn->hequic[tempindex]; - DEBUGF(infof(conn->data, "ngtcp2 established connection!\n")); -} - -/* - * There can be multiple connection attempts going on in parallel. - */ -CURLcode Curl_quic_is_connected(struct connectdata *conn, - int sockindex, - bool *done) -{ - CURLcode result; - struct quicsocket *qs = &conn->hequic[sockindex]; - curl_socket_t sockfd = conn->tempsock[sockindex]; - - result = ng_process_ingress(conn, sockfd, qs); - if(result) + if(!stream->upload_len) { + stream->upload_mem = mem; + stream->upload_len = len; + (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id); + sent = len; + } + else { + *curlcode = CURLE_AGAIN; + return -1; + } + } + + if(ng_flush_egress(conn, sockfd, qs)) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } + + *curlcode = CURLE_OK; + return sent; +} + +static void ng_has_connected(struct connectdata *conn, int tempindex) +{ + conn->recv[FIRSTSOCKET] = ngh3_stream_recv; + conn->send[FIRSTSOCKET] = ngh3_stream_send; + conn->handler = &Curl_handler_http3; + conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ + conn->httpversion = 30; + conn->bundle->multiuse = BUNDLE_MULTIPLEX; + conn->quic = &conn->hequic[tempindex]; + DEBUGF(infof(conn->data, "ngtcp2 established connection!\n")); +} + +/* + * There can be multiple connection attempts going on in parallel. + */ +CURLcode Curl_quic_is_connected(struct connectdata *conn, + int sockindex, + bool *done) +{ + CURLcode result; + struct quicsocket *qs = &conn->hequic[sockindex]; + curl_socket_t sockfd = conn->tempsock[sockindex]; + + result = ng_process_ingress(conn, sockfd, qs); + if(result) goto error; - - result = ng_flush_egress(conn, sockfd, qs); - if(result) + + result = ng_flush_egress(conn, sockfd, qs); + if(result) goto error; - - if(ngtcp2_conn_get_handshake_completed(qs->qconn)) { - *done = TRUE; - ng_has_connected(conn, sockindex); - } - - return result; + + if(ngtcp2_conn_get_handshake_completed(qs->qconn)) { + *done = TRUE; + ng_has_connected(conn, sockindex); + } + + return result; error: (void)qs_disconnect(qs); return result; -} - +} + static CURLcode ng_process_ingress(struct connectdata *conn, curl_socket_t sockfd, - struct quicsocket *qs) -{ - ssize_t recvd; - int rv; - uint8_t buf[65536]; - size_t bufsize = sizeof(buf); - struct sockaddr_storage remote_addr; - socklen_t remote_addrlen; - ngtcp2_path path; - ngtcp2_tstamp ts = timestamp(); + struct quicsocket *qs) +{ + ssize_t recvd; + int rv; + uint8_t buf[65536]; + size_t bufsize = sizeof(buf); + struct sockaddr_storage remote_addr; + socklen_t remote_addrlen; + ngtcp2_path path; + ngtcp2_tstamp ts = timestamp(); ngtcp2_pkt_info pi = { 0 }; - - for(;;) { - remote_addrlen = sizeof(remote_addr); + + for(;;) { + remote_addrlen = sizeof(remote_addr); while((recvd = recvfrom(sockfd, (char *)buf, bufsize, 0, - (struct sockaddr *)&remote_addr, - &remote_addrlen)) == -1 && + (struct sockaddr *)&remote_addr, + &remote_addrlen)) == -1 && SOCKERRNO == EINTR) - ; - if(recvd == -1) { + ; + if(recvd == -1) { if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) - break; - + break; + failf(conn->data, "ngtcp2: recvfrom() unexpectedly returned %zd", recvd); - return CURLE_RECV_ERROR; - } - + return CURLE_RECV_ERROR; + } + ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr, - qs->local_addrlen, NULL); + qs->local_addrlen, NULL); ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr, remote_addrlen, NULL); - + rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts); - if(rv != 0) { - /* TODO Send CONNECTION_CLOSE if possible */ - return CURLE_RECV_ERROR; - } - } - - return CURLE_OK; -} - -static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd, - struct quicsocket *qs) -{ - int rv; - ssize_t sent; - ssize_t outlen; - uint8_t out[NGTCP2_MAX_PKTLEN_IPV4]; - size_t pktlen; - ngtcp2_path_storage ps; - ngtcp2_tstamp ts = timestamp(); - struct sockaddr_storage remote_addr; - ngtcp2_tstamp expiry; - ngtcp2_duration timeout; - int64_t stream_id; - ssize_t veccnt; - int fin; - nghttp3_vec vec[16]; - ssize_t ndatalen; - - switch(qs->local_addr.ss_family) { - case AF_INET: - pktlen = NGTCP2_MAX_PKTLEN_IPV4; - break; + if(rv != 0) { + /* TODO Send CONNECTION_CLOSE if possible */ + return CURLE_RECV_ERROR; + } + } + + return CURLE_OK; +} + +static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd, + struct quicsocket *qs) +{ + int rv; + ssize_t sent; + ssize_t outlen; + uint8_t out[NGTCP2_MAX_PKTLEN_IPV4]; + size_t pktlen; + ngtcp2_path_storage ps; + ngtcp2_tstamp ts = timestamp(); + struct sockaddr_storage remote_addr; + ngtcp2_tstamp expiry; + ngtcp2_duration timeout; + int64_t stream_id; + ssize_t veccnt; + int fin; + nghttp3_vec vec[16]; + ssize_t ndatalen; + + switch(qs->local_addr.ss_family) { + case AF_INET: + pktlen = NGTCP2_MAX_PKTLEN_IPV4; + break; #ifdef ENABLE_IPV6 - case AF_INET6: - pktlen = NGTCP2_MAX_PKTLEN_IPV6; - break; + case AF_INET6: + pktlen = NGTCP2_MAX_PKTLEN_IPV6; + break; #endif - default: - assert(0); - } - - rv = ngtcp2_conn_handle_expiry(qs->qconn, ts); - if(rv != 0) { - failf(conn->data, "ngtcp2_conn_handle_expiry returned error: %s\n", - ngtcp2_strerror(rv)); - return CURLE_SEND_ERROR; - } - - ngtcp2_path_storage_zero(&ps); - - for(;;) { - outlen = -1; - if(qs->h3conn && ngtcp2_conn_get_max_data_left(qs->qconn)) { - veccnt = nghttp3_conn_writev_stream(qs->h3conn, &stream_id, &fin, vec, - sizeof(vec) / sizeof(vec[0])); - if(veccnt < 0) { - failf(conn->data, "nghttp3_conn_writev_stream returned error: %s\n", - nghttp3_strerror((int)veccnt)); - return CURLE_SEND_ERROR; - } - else if(veccnt > 0) { + default: + assert(0); + } + + rv = ngtcp2_conn_handle_expiry(qs->qconn, ts); + if(rv != 0) { + failf(conn->data, "ngtcp2_conn_handle_expiry returned error: %s\n", + ngtcp2_strerror(rv)); + return CURLE_SEND_ERROR; + } + + ngtcp2_path_storage_zero(&ps); + + for(;;) { + outlen = -1; + if(qs->h3conn && ngtcp2_conn_get_max_data_left(qs->qconn)) { + veccnt = nghttp3_conn_writev_stream(qs->h3conn, &stream_id, &fin, vec, + sizeof(vec) / sizeof(vec[0])); + if(veccnt < 0) { + failf(conn->data, "nghttp3_conn_writev_stream returned error: %s\n", + nghttp3_strerror((int)veccnt)); + return CURLE_SEND_ERROR; + } + else if(veccnt > 0) { uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE | (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0); - outlen = + outlen = ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL, - out, pktlen, &ndatalen, + out, pktlen, &ndatalen, flags, stream_id, - (const ngtcp2_vec *)vec, veccnt, ts); - if(outlen == 0) { - break; - } - if(outlen < 0) { - if(outlen == NGTCP2_ERR_STREAM_DATA_BLOCKED || - outlen == NGTCP2_ERR_STREAM_SHUT_WR) { + (const ngtcp2_vec *)vec, veccnt, ts); + if(outlen == 0) { + break; + } + if(outlen < 0) { + if(outlen == NGTCP2_ERR_STREAM_DATA_BLOCKED || + outlen == NGTCP2_ERR_STREAM_SHUT_WR) { assert(ndatalen == -1); - rv = nghttp3_conn_block_stream(qs->h3conn, stream_id); - if(rv != 0) { - failf(conn->data, - "nghttp3_conn_block_stream returned error: %s\n", - nghttp3_strerror(rv)); - return CURLE_SEND_ERROR; - } - continue; - } + rv = nghttp3_conn_block_stream(qs->h3conn, stream_id); + if(rv != 0) { + failf(conn->data, + "nghttp3_conn_block_stream returned error: %s\n", + nghttp3_strerror(rv)); + return CURLE_SEND_ERROR; + } + continue; + } else if(outlen == NGTCP2_ERR_WRITE_MORE) { - assert(ndatalen > 0); - rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, - ndatalen); - if(rv != 0) { - failf(conn->data, - "nghttp3_conn_add_write_offset returned error: %s\n", - nghttp3_strerror(rv)); - return CURLE_SEND_ERROR; - } - continue; - } - else { + assert(ndatalen > 0); + rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, + ndatalen); + if(rv != 0) { + failf(conn->data, + "nghttp3_conn_add_write_offset returned error: %s\n", + nghttp3_strerror(rv)); + return CURLE_SEND_ERROR; + } + continue; + } + else { assert(ndatalen == -1); - failf(conn->data, "ngtcp2_conn_writev_stream returned error: %s\n", - ngtcp2_strerror((int)outlen)); - return CURLE_SEND_ERROR; - } - } + failf(conn->data, "ngtcp2_conn_writev_stream returned error: %s\n", + ngtcp2_strerror((int)outlen)); + return CURLE_SEND_ERROR; + } + } else { assert(ndatalen == -1); - } - } - } - if(outlen < 0) { + } + } + } + if(outlen < 0) { outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, NULL, out, pktlen, ts); - if(outlen < 0) { - failf(conn->data, "ngtcp2_conn_write_pkt returned error: %s\n", - ngtcp2_strerror((int)outlen)); - return CURLE_SEND_ERROR; - } - if(outlen == 0) - break; - } - - memcpy(&remote_addr, ps.path.remote.addr, ps.path.remote.addrlen); + if(outlen < 0) { + failf(conn->data, "ngtcp2_conn_write_pkt returned error: %s\n", + ngtcp2_strerror((int)outlen)); + return CURLE_SEND_ERROR; + } + if(outlen == 0) + break; + } + + memcpy(&remote_addr, ps.path.remote.addr, ps.path.remote.addrlen); while((sent = send(sockfd, (const char *)out, outlen, 0)) == -1 && SOCKERRNO == EINTR) - ; - - if(sent == -1) { + ; + + if(sent == -1) { if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - /* TODO Cache packet */ - break; - } - else { + /* TODO Cache packet */ + break; + } + else { failf(conn->data, "send() returned %zd (errno %d)\n", sent, - SOCKERRNO); - return CURLE_SEND_ERROR; - } - } - } - - expiry = ngtcp2_conn_get_expiry(qs->qconn); - if(expiry != UINT64_MAX) { - if(expiry <= ts) { - timeout = NGTCP2_MILLISECONDS; - } - else { - timeout = expiry - ts; - } - Curl_expire(conn->data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC); - } - - return CURLE_OK; -} - -/* - * Called from transfer.c:done_sending when we stop HTTP/3 uploading. - */ -CURLcode Curl_quic_done_sending(struct connectdata *conn) -{ - if(conn->handler == &Curl_handler_http3) { - /* only for HTTP/3 transfers */ + SOCKERRNO); + return CURLE_SEND_ERROR; + } + } + } + + expiry = ngtcp2_conn_get_expiry(qs->qconn); + if(expiry != UINT64_MAX) { + if(expiry <= ts) { + timeout = NGTCP2_MILLISECONDS; + } + else { + timeout = expiry - ts; + } + Curl_expire(conn->data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC); + } + + return CURLE_OK; +} + +/* + * Called from transfer.c:done_sending when we stop HTTP/3 uploading. + */ +CURLcode Curl_quic_done_sending(struct connectdata *conn) +{ + if(conn->handler == &Curl_handler_http3) { + /* only for HTTP/3 transfers */ struct HTTP *stream = conn->data->req.p.http; - struct quicsocket *qs = conn->quic; - stream->upload_done = TRUE; - (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id); - } - - return CURLE_OK; -} + struct quicsocket *qs = conn->quic; + stream->upload_done = TRUE; + (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id); + } + + return CURLE_OK; +} /* * Called from http.c:Curl_http_done when a request completes. @@ -1935,4 +1935,4 @@ bool Curl_quic_data_pending(const struct Curl_easy *data) return Curl_dyn_len(&stream->overflow) > 0; } -#endif +#endif diff --git a/contrib/libs/curl/lib/vquic/quiche.c b/contrib/libs/curl/lib/vquic/quiche.c index 87abdf40ec..c50cccd4b3 100644 --- a/contrib/libs/curl/lib/vquic/quiche.c +++ b/contrib/libs/curl/lib/vquic/quiche.c @@ -1,94 +1,94 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_QUICHE -#error #include <quiche.h> -#include <openssl/err.h> -#include "urldata.h" -#include "sendf.h" -#include "strdup.h" -#include "rand.h" -#include "quic.h" -#include "strcase.h" -#include "multiif.h" -#include "connect.h" -#include "strerror.h" + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_QUICHE +#error #include <quiche.h> +#include <openssl/err.h> +#include "urldata.h" +#include "sendf.h" +#include "strdup.h" +#include "rand.h" +#include "quic.h" +#include "strcase.h" +#include "multiif.h" +#include "connect.h" +#include "strerror.h" #error #include "vquic.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#define DEBUG_HTTP3 -/* #define DEBUG_QUICHE */ -#ifdef DEBUG_HTTP3 -#define H3BUGF(x) x -#else + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define DEBUG_HTTP3 +/* #define DEBUG_QUICHE */ +#ifdef DEBUG_HTTP3 +#define H3BUGF(x) x +#else #define H3BUGF(x) do { } while(0) -#endif - -#define QUIC_MAX_STREAMS (256*1024) -#define QUIC_MAX_DATA (1*1024*1024) +#endif + +#define QUIC_MAX_STREAMS (256*1024) +#define QUIC_MAX_DATA (1*1024*1024) #define QUIC_IDLE_TIMEOUT (60 * 1000) /* milliseconds */ - -static CURLcode process_ingress(struct connectdata *conn, - curl_socket_t sockfd, - struct quicsocket *qs); - -static CURLcode flush_egress(struct connectdata *conn, curl_socket_t sockfd, - struct quicsocket *qs); - -static CURLcode http_request(struct connectdata *conn, const void *mem, - size_t len); -static Curl_recv h3_stream_recv; -static Curl_send h3_stream_send; - -static int quiche_getsock(struct connectdata *conn, curl_socket_t *socks) -{ - struct SingleRequest *k = &conn->data->req; - int bitmap = GETSOCK_BLANK; - - socks[0] = conn->sock[FIRSTSOCKET]; - - /* in a HTTP/2 connection we can basically always get a frame so we should - always be ready for one */ - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - - /* we're still uploading or the HTTP/2 layer wants to send data */ - if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - return bitmap; -} - -static int quiche_perform_getsock(const struct connectdata *conn, - curl_socket_t *socks) -{ - return quiche_getsock((struct connectdata *)conn, socks); -} - + +static CURLcode process_ingress(struct connectdata *conn, + curl_socket_t sockfd, + struct quicsocket *qs); + +static CURLcode flush_egress(struct connectdata *conn, curl_socket_t sockfd, + struct quicsocket *qs); + +static CURLcode http_request(struct connectdata *conn, const void *mem, + size_t len); +static Curl_recv h3_stream_recv; +static Curl_send h3_stream_send; + +static int quiche_getsock(struct connectdata *conn, curl_socket_t *socks) +{ + struct SingleRequest *k = &conn->data->req; + int bitmap = GETSOCK_BLANK; + + socks[0] = conn->sock[FIRSTSOCKET]; + + /* in a HTTP/2 connection we can basically always get a frame so we should + always be ready for one */ + bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); + + /* we're still uploading or the HTTP/2 layer wants to send data */ + if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) + bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); + + return bitmap; +} + +static int quiche_perform_getsock(const struct connectdata *conn, + curl_socket_t *socks) +{ + return quiche_getsock((struct connectdata *)conn, socks); +} + static CURLcode qs_disconnect(struct connectdata *conn, struct quicsocket *qs) { @@ -111,14 +111,14 @@ static CURLcode qs_disconnect(struct connectdata *conn, return CURLE_OK; } -static CURLcode quiche_disconnect(struct connectdata *conn, - bool dead_connection) -{ - struct quicsocket *qs = conn->quic; - (void)dead_connection; +static CURLcode quiche_disconnect(struct connectdata *conn, + bool dead_connection) +{ + struct quicsocket *qs = conn->quic; + (void)dead_connection; return qs_disconnect(conn, qs); -} - +} + void Curl_quic_disconnect(struct connectdata *conn, int tempindex) { @@ -126,109 +126,109 @@ void Curl_quic_disconnect(struct connectdata *conn, qs_disconnect(conn, &conn->hequic[tempindex]); } -static unsigned int quiche_conncheck(struct connectdata *conn, - unsigned int checks_to_perform) -{ - (void)conn; - (void)checks_to_perform; - return CONNRESULT_NONE; -} - -static CURLcode quiche_do(struct connectdata *conn, bool *done) -{ +static unsigned int quiche_conncheck(struct connectdata *conn, + unsigned int checks_to_perform) +{ + (void)conn; + (void)checks_to_perform; + return CONNRESULT_NONE; +} + +static CURLcode quiche_do(struct connectdata *conn, bool *done) +{ struct HTTP *stream = conn->data->req.p.http; - stream->h3req = FALSE; /* not sent */ - return Curl_http(conn, done); -} - -static const struct Curl_handler Curl_handler_http3 = { - "HTTPS", /* scheme */ - ZERO_NULL, /* setup_connection */ - quiche_do, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - quiche_getsock, /* proto_getsock */ - quiche_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - quiche_perform_getsock, /* perform_getsock */ - quiche_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - quiche_conncheck, /* connection_check */ - PORT_HTTP, /* defport */ - CURLPROTO_HTTPS, /* protocol */ + stream->h3req = FALSE; /* not sent */ + return Curl_http(conn, done); +} + +static const struct Curl_handler Curl_handler_http3 = { + "HTTPS", /* scheme */ + ZERO_NULL, /* setup_connection */ + quiche_do, /* do_it */ + Curl_http_done, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + quiche_getsock, /* proto_getsock */ + quiche_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + quiche_perform_getsock, /* perform_getsock */ + quiche_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + quiche_conncheck, /* connection_check */ + PORT_HTTP, /* defport */ + CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ - PROTOPT_SSL | PROTOPT_STREAM /* flags */ -}; - -#ifdef DEBUG_QUICHE -static void quiche_debug_log(const char *line, void *argp) -{ - (void)argp; - fprintf(stderr, "%s\n", line); -} -#endif - -CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd, - int sockindex, - const struct sockaddr *addr, socklen_t addrlen) -{ - CURLcode result; - struct quicsocket *qs = &conn->hequic[sockindex]; - struct Curl_easy *data = conn->data; + PROTOPT_SSL | PROTOPT_STREAM /* flags */ +}; + +#ifdef DEBUG_QUICHE +static void quiche_debug_log(const char *line, void *argp) +{ + (void)argp; + fprintf(stderr, "%s\n", line); +} +#endif + +CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd, + int sockindex, + const struct sockaddr *addr, socklen_t addrlen) +{ + CURLcode result; + struct quicsocket *qs = &conn->hequic[sockindex]; + struct Curl_easy *data = conn->data; char *keylog_file = NULL; - -#ifdef DEBUG_QUICHE - /* initialize debug log callback only once */ - static int debug_log_init = 0; - if(!debug_log_init) { - quiche_enable_debug_logging(quiche_debug_log, NULL); - debug_log_init = 1; - } -#endif - - (void)addr; - (void)addrlen; - + +#ifdef DEBUG_QUICHE + /* initialize debug log callback only once */ + static int debug_log_init = 0; + if(!debug_log_init) { + quiche_enable_debug_logging(quiche_debug_log, NULL); + debug_log_init = 1; + } +#endif + + (void)addr; + (void)addrlen; + qs->sockfd = sockfd; - qs->cfg = quiche_config_new(QUICHE_PROTOCOL_VERSION); - if(!qs->cfg) { - failf(data, "can't create quiche config"); - return CURLE_FAILED_INIT; - } - + qs->cfg = quiche_config_new(QUICHE_PROTOCOL_VERSION); + if(!qs->cfg) { + failf(data, "can't create quiche config"); + return CURLE_FAILED_INIT; + } + quiche_config_set_max_idle_timeout(qs->cfg, QUIC_IDLE_TIMEOUT); - quiche_config_set_initial_max_data(qs->cfg, QUIC_MAX_DATA); - quiche_config_set_initial_max_stream_data_bidi_local(qs->cfg, QUIC_MAX_DATA); - quiche_config_set_initial_max_stream_data_bidi_remote(qs->cfg, - QUIC_MAX_DATA); - quiche_config_set_initial_max_stream_data_uni(qs->cfg, QUIC_MAX_DATA); - quiche_config_set_initial_max_streams_bidi(qs->cfg, QUIC_MAX_STREAMS); - quiche_config_set_initial_max_streams_uni(qs->cfg, QUIC_MAX_STREAMS); - quiche_config_set_application_protos(qs->cfg, - (uint8_t *) - QUICHE_H3_APPLICATION_PROTOCOL, - sizeof(QUICHE_H3_APPLICATION_PROTOCOL) - - 1); - - result = Curl_rand(data, qs->scid, sizeof(qs->scid)); - if(result) - return result; - + quiche_config_set_initial_max_data(qs->cfg, QUIC_MAX_DATA); + quiche_config_set_initial_max_stream_data_bidi_local(qs->cfg, QUIC_MAX_DATA); + quiche_config_set_initial_max_stream_data_bidi_remote(qs->cfg, + QUIC_MAX_DATA); + quiche_config_set_initial_max_stream_data_uni(qs->cfg, QUIC_MAX_DATA); + quiche_config_set_initial_max_streams_bidi(qs->cfg, QUIC_MAX_STREAMS); + quiche_config_set_initial_max_streams_uni(qs->cfg, QUIC_MAX_STREAMS); + quiche_config_set_application_protos(qs->cfg, + (uint8_t *) + QUICHE_H3_APPLICATION_PROTOCOL, + sizeof(QUICHE_H3_APPLICATION_PROTOCOL) + - 1); + + result = Curl_rand(data, qs->scid, sizeof(qs->scid)); + if(result) + return result; + keylog_file = getenv("SSLKEYLOGFILE"); if(keylog_file) - quiche_config_log_keys(qs->cfg); - - qs->conn = quiche_connect(conn->host.name, (const uint8_t *) qs->scid, - sizeof(qs->scid), qs->cfg); - if(!qs->conn) { - failf(data, "can't create quiche connection"); - return CURLE_OUT_OF_MEMORY; - } - + quiche_config_log_keys(qs->cfg); + + qs->conn = quiche_connect(conn->host.name, (const uint8_t *) qs->scid, + sizeof(qs->scid), qs->cfg); + if(!qs->conn) { + failf(data, "can't create quiche connection"); + return CURLE_OUT_OF_MEMORY; + } + if(keylog_file) quiche_conn_set_keylog_path(qs->conn, keylog_file); @@ -243,28 +243,28 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd, } #endif - result = flush_egress(conn, sockfd, qs); - if(result) - return result; - - /* store the used address as a string */ + result = flush_egress(conn, sockfd, qs); + if(result) + return result; + + /* store the used address as a string */ if(!Curl_addr2string((struct sockaddr*)addr, addrlen, - conn->primary_ip, &conn->primary_port)) { - char buffer[STRERROR_LEN]; - failf(data, "ssrem inet_ntop() failed with errno %d: %s", + conn->primary_ip, &conn->primary_port)) { + char buffer[STRERROR_LEN]; + failf(data, "ssrem inet_ntop() failed with errno %d: %s", SOCKERRNO, Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); Curl_persistconninfo(conn); - /* for connection reuse purposes: */ - conn->ssl[FIRSTSOCKET].state = ssl_connection_complete; - + /* for connection reuse purposes: */ + conn->ssl[FIRSTSOCKET].state = ssl_connection_complete; + { unsigned char alpn_protocols[] = QUICHE_H3_APPLICATION_PROTOCOL; unsigned alpn_len, offset = 0; - + /* Replace each ALPN length prefix by a comma. */ while(offset < sizeof(alpn_protocols) - 1) { alpn_len = alpn_protocols[offset]; @@ -276,574 +276,574 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd, alpn_protocols + 1); } - return CURLE_OK; -} - -static CURLcode quiche_has_connected(struct connectdata *conn, - int sockindex, - int tempindex) -{ - CURLcode result; - struct quicsocket *qs = conn->quic = &conn->hequic[tempindex]; - - conn->recv[sockindex] = h3_stream_recv; - conn->send[sockindex] = h3_stream_send; - conn->handler = &Curl_handler_http3; - conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ - conn->httpversion = 30; - conn->bundle->multiuse = BUNDLE_MULTIPLEX; - + return CURLE_OK; +} + +static CURLcode quiche_has_connected(struct connectdata *conn, + int sockindex, + int tempindex) +{ + CURLcode result; + struct quicsocket *qs = conn->quic = &conn->hequic[tempindex]; + + conn->recv[sockindex] = h3_stream_recv; + conn->send[sockindex] = h3_stream_send; + conn->handler = &Curl_handler_http3; + conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ + conn->httpversion = 30; + conn->bundle->multiuse = BUNDLE_MULTIPLEX; + qs->h3config = quiche_h3_config_new(); - if(!qs->h3config) - return CURLE_OUT_OF_MEMORY; - - /* Create a new HTTP/3 connection on the QUIC connection. */ - qs->h3c = quiche_h3_conn_new_with_transport(qs->conn, qs->h3config); - if(!qs->h3c) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - if(conn->hequic[1-tempindex].cfg) { - qs = &conn->hequic[1-tempindex]; - quiche_config_free(qs->cfg); - quiche_conn_free(qs->conn); - qs->cfg = NULL; - qs->conn = NULL; - } - return CURLE_OK; - fail: - quiche_h3_config_free(qs->h3config); - quiche_h3_conn_free(qs->h3c); - return result; -} - -/* - * This function gets polled to check if this QUIC connection has connected. - */ -CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex, - bool *done) -{ - CURLcode result; - struct quicsocket *qs = &conn->hequic[sockindex]; - curl_socket_t sockfd = conn->tempsock[sockindex]; - - result = process_ingress(conn, sockfd, qs); - if(result) + if(!qs->h3config) + return CURLE_OUT_OF_MEMORY; + + /* Create a new HTTP/3 connection on the QUIC connection. */ + qs->h3c = quiche_h3_conn_new_with_transport(qs->conn, qs->h3config); + if(!qs->h3c) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + if(conn->hequic[1-tempindex].cfg) { + qs = &conn->hequic[1-tempindex]; + quiche_config_free(qs->cfg); + quiche_conn_free(qs->conn); + qs->cfg = NULL; + qs->conn = NULL; + } + return CURLE_OK; + fail: + quiche_h3_config_free(qs->h3config); + quiche_h3_conn_free(qs->h3c); + return result; +} + +/* + * This function gets polled to check if this QUIC connection has connected. + */ +CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex, + bool *done) +{ + CURLcode result; + struct quicsocket *qs = &conn->hequic[sockindex]; + curl_socket_t sockfd = conn->tempsock[sockindex]; + + result = process_ingress(conn, sockfd, qs); + if(result) goto error; - - result = flush_egress(conn, sockfd, qs); - if(result) + + result = flush_egress(conn, sockfd, qs); + if(result) goto error; - - if(quiche_conn_is_established(qs->conn)) { - *done = TRUE; - result = quiche_has_connected(conn, 0, sockindex); - DEBUGF(infof(conn->data, "quiche established connection!\n")); - } - - return result; + + if(quiche_conn_is_established(qs->conn)) { + *done = TRUE; + result = quiche_has_connected(conn, 0, sockindex); + DEBUGF(infof(conn->data, "quiche established connection!\n")); + } + + return result; error: qs_disconnect(conn, qs); return result; -} - -static CURLcode process_ingress(struct connectdata *conn, int sockfd, - struct quicsocket *qs) -{ - ssize_t recvd; - struct Curl_easy *data = conn->data; - uint8_t *buf = (uint8_t *)data->state.buffer; - size_t bufsize = data->set.buffer_size; - - /* in case the timeout expired */ - quiche_conn_on_timeout(qs->conn); - - do { - recvd = recv(sockfd, buf, bufsize, 0); +} + +static CURLcode process_ingress(struct connectdata *conn, int sockfd, + struct quicsocket *qs) +{ + ssize_t recvd; + struct Curl_easy *data = conn->data; + uint8_t *buf = (uint8_t *)data->state.buffer; + size_t bufsize = data->set.buffer_size; + + /* in case the timeout expired */ + quiche_conn_on_timeout(qs->conn); + + do { + recvd = recv(sockfd, buf, bufsize, 0); if((recvd < 0) && ((SOCKERRNO == EAGAIN) || (SOCKERRNO == EWOULDBLOCK))) - break; - - if(recvd < 0) { + break; + + if(recvd < 0) { failf(conn->data, "quiche: recv() unexpectedly returned %zd " - "(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd); - return CURLE_RECV_ERROR; - } - - recvd = quiche_conn_recv(qs->conn, buf, recvd); - if(recvd == QUICHE_ERR_DONE) - break; - - if(recvd < 0) { + "(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd); + return CURLE_RECV_ERROR; + } + + recvd = quiche_conn_recv(qs->conn, buf, recvd); + if(recvd == QUICHE_ERR_DONE) + break; + + if(recvd < 0) { failf(conn->data, "quiche_conn_recv() == %zd", recvd); - return CURLE_RECV_ERROR; - } - } while(1); - - return CURLE_OK; -} - -/* - * flush_egress drains the buffers and sends off data. - * Calls failf() on errors. - */ -static CURLcode flush_egress(struct connectdata *conn, int sockfd, - struct quicsocket *qs) -{ - ssize_t sent; + return CURLE_RECV_ERROR; + } + } while(1); + + return CURLE_OK; +} + +/* + * flush_egress drains the buffers and sends off data. + * Calls failf() on errors. + */ +static CURLcode flush_egress(struct connectdata *conn, int sockfd, + struct quicsocket *qs) +{ + ssize_t sent; uint8_t out[1200]; - int64_t timeout_ns; - - do { - sent = quiche_conn_send(qs->conn, out, sizeof(out)); - if(sent == QUICHE_ERR_DONE) - break; - - if(sent < 0) { - failf(conn->data, "quiche_conn_send returned %zd\n", - sent); - return CURLE_SEND_ERROR; - } - - sent = send(sockfd, out, sent, 0); - if(sent < 0) { - failf(conn->data, "send() returned %zd\n", sent); - return CURLE_SEND_ERROR; - } - } while(1); - - /* time until the next timeout event, as nanoseconds. */ - timeout_ns = quiche_conn_timeout_as_nanos(qs->conn); - if(timeout_ns) - /* expire uses milliseconds */ - Curl_expire(conn->data, (timeout_ns + 999999) / 1000000, EXPIRE_QUIC); - - return CURLE_OK; -} - -struct h3h1header { - char *dest; - size_t destlen; /* left to use */ - size_t nlen; /* used */ -}; - -static int cb_each_header(uint8_t *name, size_t name_len, - uint8_t *value, size_t value_len, - void *argp) -{ - struct h3h1header *headers = (struct h3h1header *)argp; - size_t olen = 0; - - if((name_len == 7) && !strncmp(":status", (char *)name, 7)) { - msnprintf(headers->dest, - headers->destlen, "HTTP/3 %.*s\n", - (int) value_len, value); - } + int64_t timeout_ns; + + do { + sent = quiche_conn_send(qs->conn, out, sizeof(out)); + if(sent == QUICHE_ERR_DONE) + break; + + if(sent < 0) { + failf(conn->data, "quiche_conn_send returned %zd\n", + sent); + return CURLE_SEND_ERROR; + } + + sent = send(sockfd, out, sent, 0); + if(sent < 0) { + failf(conn->data, "send() returned %zd\n", sent); + return CURLE_SEND_ERROR; + } + } while(1); + + /* time until the next timeout event, as nanoseconds. */ + timeout_ns = quiche_conn_timeout_as_nanos(qs->conn); + if(timeout_ns) + /* expire uses milliseconds */ + Curl_expire(conn->data, (timeout_ns + 999999) / 1000000, EXPIRE_QUIC); + + return CURLE_OK; +} + +struct h3h1header { + char *dest; + size_t destlen; /* left to use */ + size_t nlen; /* used */ +}; + +static int cb_each_header(uint8_t *name, size_t name_len, + uint8_t *value, size_t value_len, + void *argp) +{ + struct h3h1header *headers = (struct h3h1header *)argp; + size_t olen = 0; + + if((name_len == 7) && !strncmp(":status", (char *)name, 7)) { + msnprintf(headers->dest, + headers->destlen, "HTTP/3 %.*s\n", + (int) value_len, value); + } else if(!headers->nlen) { return CURLE_HTTP3; } - else { - msnprintf(headers->dest, - headers->destlen, "%.*s: %.*s\n", - (int)name_len, name, (int) value_len, value); - } - olen = strlen(headers->dest); - headers->destlen -= olen; - headers->nlen += olen; - headers->dest += olen; - return 0; -} - -static ssize_t h3_stream_recv(struct connectdata *conn, - int sockindex, - char *buf, - size_t buffersize, - CURLcode *curlcode) -{ - ssize_t recvd = -1; - ssize_t rcode; - struct quicsocket *qs = conn->quic; - curl_socket_t sockfd = conn->sock[sockindex]; - quiche_h3_event *ev; - int rc; - struct h3h1header headers; + else { + msnprintf(headers->dest, + headers->destlen, "%.*s: %.*s\n", + (int)name_len, name, (int) value_len, value); + } + olen = strlen(headers->dest); + headers->destlen -= olen; + headers->nlen += olen; + headers->dest += olen; + return 0; +} + +static ssize_t h3_stream_recv(struct connectdata *conn, + int sockindex, + char *buf, + size_t buffersize, + CURLcode *curlcode) +{ + ssize_t recvd = -1; + ssize_t rcode; + struct quicsocket *qs = conn->quic; + curl_socket_t sockfd = conn->sock[sockindex]; + quiche_h3_event *ev; + int rc; + struct h3h1header headers; struct Curl_easy *data = conn->data; struct HTTP *stream = data->req.p.http; - headers.dest = buf; - headers.destlen = buffersize; - headers.nlen = 0; - - if(process_ingress(conn, sockfd, qs)) { + headers.dest = buf; + headers.destlen = buffersize; + headers.nlen = 0; + + if(process_ingress(conn, sockfd, qs)) { infof(data, "h3_stream_recv returns on ingress\n"); - *curlcode = CURLE_RECV_ERROR; - return -1; - } - - while(recvd < 0) { - int64_t s = quiche_h3_conn_poll(qs->h3c, qs->conn, &ev); - if(s < 0) - /* nothing more to do */ - break; - - if(s != stream->stream3_id) { - /* another transfer, ignore for now */ + *curlcode = CURLE_RECV_ERROR; + return -1; + } + + while(recvd < 0) { + int64_t s = quiche_h3_conn_poll(qs->h3c, qs->conn, &ev); + if(s < 0) + /* nothing more to do */ + break; + + if(s != stream->stream3_id) { + /* another transfer, ignore for now */ infof(data, "Got h3 for stream %u, expects %u\n", - s, stream->stream3_id); - continue; - } - - switch(quiche_h3_event_type(ev)) { - case QUICHE_H3_EVENT_HEADERS: - rc = quiche_h3_event_for_each_header(ev, cb_each_header, &headers); - if(rc) { + s, stream->stream3_id); + continue; + } + + switch(quiche_h3_event_type(ev)) { + case QUICHE_H3_EVENT_HEADERS: + rc = quiche_h3_event_for_each_header(ev, cb_each_header, &headers); + if(rc) { *curlcode = rc; failf(data, "Error in HTTP/3 response header"); break; - } - recvd = headers.nlen; - break; - case QUICHE_H3_EVENT_DATA: - if(!stream->firstbody) { - /* add a header-body separator CRLF */ - buf[0] = '\r'; - buf[1] = '\n'; - buf += 2; - buffersize -= 2; - stream->firstbody = TRUE; - recvd = 2; /* two bytes already */ - } - else - recvd = 0; - rcode = quiche_h3_recv_body(qs->h3c, qs->conn, s, (unsigned char *)buf, - buffersize); - if(rcode <= 0) { - recvd = -1; - break; - } - recvd += rcode; - break; - - case QUICHE_H3_EVENT_FINISHED: + } + recvd = headers.nlen; + break; + case QUICHE_H3_EVENT_DATA: + if(!stream->firstbody) { + /* add a header-body separator CRLF */ + buf[0] = '\r'; + buf[1] = '\n'; + buf += 2; + buffersize -= 2; + stream->firstbody = TRUE; + recvd = 2; /* two bytes already */ + } + else + recvd = 0; + rcode = quiche_h3_recv_body(qs->h3c, qs->conn, s, (unsigned char *)buf, + buffersize); + if(rcode <= 0) { + recvd = -1; + break; + } + recvd += rcode; + break; + + case QUICHE_H3_EVENT_FINISHED: streamclose(conn, "End of stream"); - recvd = 0; /* end of stream */ - break; - default: - break; - } - - quiche_h3_event_free(ev); - } - if(flush_egress(conn, sockfd, qs)) { - *curlcode = CURLE_SEND_ERROR; - return -1; - } - - *curlcode = (-1 == recvd)? CURLE_AGAIN : CURLE_OK; - if(recvd >= 0) - /* Get this called again to drain the event queue */ + recvd = 0; /* end of stream */ + break; + default: + break; + } + + quiche_h3_event_free(ev); + } + if(flush_egress(conn, sockfd, qs)) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } + + *curlcode = (-1 == recvd)? CURLE_AGAIN : CURLE_OK; + if(recvd >= 0) + /* Get this called again to drain the event queue */ Curl_expire(data, 0, EXPIRE_QUIC); data->state.drain = (recvd >= 0) ? 1 : 0; - return recvd; -} - -static ssize_t h3_stream_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - ssize_t sent; - struct quicsocket *qs = conn->quic; - curl_socket_t sockfd = conn->sock[sockindex]; + return recvd; +} + +static ssize_t h3_stream_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + ssize_t sent; + struct quicsocket *qs = conn->quic; + curl_socket_t sockfd = conn->sock[sockindex]; struct HTTP *stream = conn->data->req.p.http; - - if(!stream->h3req) { - CURLcode result = http_request(conn, mem, len); - if(result) { - *curlcode = CURLE_SEND_ERROR; - return -1; - } - sent = len; - } - else { - H3BUGF(infof(conn->data, "Pass on %zd body bytes to quiche\n", - len)); - sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id, - (uint8_t *)mem, len, FALSE); - if(sent < 0) { - *curlcode = CURLE_SEND_ERROR; - return -1; - } - } - - if(flush_egress(conn, sockfd, qs)) { - *curlcode = CURLE_SEND_ERROR; - return -1; - } - - *curlcode = CURLE_OK; - return sent; -} - -/* - * Store quiche version info in this buffer, Prefix with a space. Return total - * length written. - */ -int Curl_quic_ver(char *p, size_t len) -{ + + if(!stream->h3req) { + CURLcode result = http_request(conn, mem, len); + if(result) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } + sent = len; + } + else { + H3BUGF(infof(conn->data, "Pass on %zd body bytes to quiche\n", + len)); + sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id, + (uint8_t *)mem, len, FALSE); + if(sent < 0) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } + } + + if(flush_egress(conn, sockfd, qs)) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } + + *curlcode = CURLE_OK; + return sent; +} + +/* + * Store quiche version info in this buffer, Prefix with a space. Return total + * length written. + */ +int Curl_quic_ver(char *p, size_t len) +{ return msnprintf(p, len, "quiche/%s", quiche_version()); -} - -/* Index where :authority header field will appear in request header - field list. */ -#define AUTHORITY_DST_IDX 3 - -static CURLcode http_request(struct connectdata *conn, const void *mem, - size_t len) -{ - /* - */ +} + +/* Index where :authority header field will appear in request header + field list. */ +#define AUTHORITY_DST_IDX 3 + +static CURLcode http_request(struct connectdata *conn, const void *mem, + size_t len) +{ + /* + */ struct HTTP *stream = conn->data->req.p.http; - size_t nheader; - size_t i; - size_t authority_idx; - char *hdbuf = (char *)mem; - char *end, *line_end; - int64_t stream3_id; - quiche_h3_header *nva = NULL; - struct quicsocket *qs = conn->quic; - CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - - stream->h3req = TRUE; /* senf off! */ - - /* Calculate number of headers contained in [mem, mem + len). Assumes a - correctly generated HTTP header field block. */ - nheader = 0; - for(i = 1; i < len; ++i) { - if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') { - ++nheader; - ++i; - } - } - if(nheader < 2) - goto fail; - - /* We counted additional 2 \r\n in the first and last line. We need 3 - new headers: :method, :path and :scheme. Therefore we need one - more space. */ - nheader += 1; - nva = malloc(sizeof(quiche_h3_header) * nheader); - if(!nva) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - /* Extract :method, :path from request line - We do line endings with CRLF so checking for CR is enough */ - line_end = memchr(hdbuf, '\r', len); - if(!line_end) { - result = CURLE_BAD_FUNCTION_ARGUMENT; /* internal error */ - goto fail; - } - - /* Method does not contain spaces */ - end = memchr(hdbuf, ' ', line_end - hdbuf); - if(!end || end == hdbuf) - goto fail; - nva[0].name = (unsigned char *)":method"; - nva[0].name_len = strlen((char *)nva[0].name); - nva[0].value = (unsigned char *)hdbuf; - nva[0].value_len = (size_t)(end - hdbuf); - - hdbuf = end + 1; - - /* Path may contain spaces so scan backwards */ - end = NULL; - for(i = (size_t)(line_end - hdbuf); i; --i) { - if(hdbuf[i - 1] == ' ') { - end = &hdbuf[i - 1]; - break; - } - } - if(!end || end == hdbuf) - goto fail; - nva[1].name = (unsigned char *)":path"; - nva[1].name_len = strlen((char *)nva[1].name); - nva[1].value = (unsigned char *)hdbuf; - nva[1].value_len = (size_t)(end - hdbuf); - - nva[2].name = (unsigned char *)":scheme"; - nva[2].name_len = strlen((char *)nva[2].name); - if(conn->handler->flags & PROTOPT_SSL) - nva[2].value = (unsigned char *)"https"; - else - nva[2].value = (unsigned char *)"http"; - nva[2].value_len = strlen((char *)nva[2].value); - - - authority_idx = 0; - i = 3; - while(i < nheader) { - size_t hlen; - - hdbuf = line_end + 2; - - /* check for next CR, but only within the piece of data left in the given - buffer */ - line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem)); - if(!line_end || (line_end == hdbuf)) - goto fail; - - /* header continuation lines are not supported */ - if(*hdbuf == ' ' || *hdbuf == '\t') - goto fail; - - for(end = hdbuf; end < line_end && *end != ':'; ++end) - ; - if(end == hdbuf || end == line_end) - goto fail; - hlen = end - hdbuf; - - if(hlen == 4 && strncasecompare("host", hdbuf, 4)) { - authority_idx = i; - nva[i].name = (unsigned char *)":authority"; - nva[i].name_len = strlen((char *)nva[i].name); - } - else { + size_t nheader; + size_t i; + size_t authority_idx; + char *hdbuf = (char *)mem; + char *end, *line_end; + int64_t stream3_id; + quiche_h3_header *nva = NULL; + struct quicsocket *qs = conn->quic; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + stream->h3req = TRUE; /* senf off! */ + + /* Calculate number of headers contained in [mem, mem + len). Assumes a + correctly generated HTTP header field block. */ + nheader = 0; + for(i = 1; i < len; ++i) { + if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') { + ++nheader; + ++i; + } + } + if(nheader < 2) + goto fail; + + /* We counted additional 2 \r\n in the first and last line. We need 3 + new headers: :method, :path and :scheme. Therefore we need one + more space. */ + nheader += 1; + nva = malloc(sizeof(quiche_h3_header) * nheader); + if(!nva) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + /* Extract :method, :path from request line + We do line endings with CRLF so checking for CR is enough */ + line_end = memchr(hdbuf, '\r', len); + if(!line_end) { + result = CURLE_BAD_FUNCTION_ARGUMENT; /* internal error */ + goto fail; + } + + /* Method does not contain spaces */ + end = memchr(hdbuf, ' ', line_end - hdbuf); + if(!end || end == hdbuf) + goto fail; + nva[0].name = (unsigned char *)":method"; + nva[0].name_len = strlen((char *)nva[0].name); + nva[0].value = (unsigned char *)hdbuf; + nva[0].value_len = (size_t)(end - hdbuf); + + hdbuf = end + 1; + + /* Path may contain spaces so scan backwards */ + end = NULL; + for(i = (size_t)(line_end - hdbuf); i; --i) { + if(hdbuf[i - 1] == ' ') { + end = &hdbuf[i - 1]; + break; + } + } + if(!end || end == hdbuf) + goto fail; + nva[1].name = (unsigned char *)":path"; + nva[1].name_len = strlen((char *)nva[1].name); + nva[1].value = (unsigned char *)hdbuf; + nva[1].value_len = (size_t)(end - hdbuf); + + nva[2].name = (unsigned char *)":scheme"; + nva[2].name_len = strlen((char *)nva[2].name); + if(conn->handler->flags & PROTOPT_SSL) + nva[2].value = (unsigned char *)"https"; + else + nva[2].value = (unsigned char *)"http"; + nva[2].value_len = strlen((char *)nva[2].value); + + + authority_idx = 0; + i = 3; + while(i < nheader) { + size_t hlen; + + hdbuf = line_end + 2; + + /* check for next CR, but only within the piece of data left in the given + buffer */ + line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem)); + if(!line_end || (line_end == hdbuf)) + goto fail; + + /* header continuation lines are not supported */ + if(*hdbuf == ' ' || *hdbuf == '\t') + goto fail; + + for(end = hdbuf; end < line_end && *end != ':'; ++end) + ; + if(end == hdbuf || end == line_end) + goto fail; + hlen = end - hdbuf; + + if(hlen == 4 && strncasecompare("host", hdbuf, 4)) { + authority_idx = i; + nva[i].name = (unsigned char *)":authority"; + nva[i].name_len = strlen((char *)nva[i].name); + } + else { nva[i].name_len = (size_t)(end - hdbuf); /* Lower case the header name for HTTP/3 */ Curl_strntolower((char *)hdbuf, hdbuf, nva[i].name_len); - nva[i].name = (unsigned char *)hdbuf; - } - hdbuf = end + 1; - while(*hdbuf == ' ' || *hdbuf == '\t') - ++hdbuf; - end = line_end; - -#if 0 /* This should probably go in more or less like this */ - switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf, - end - hdbuf)) { - case HEADERINST_IGNORE: - /* skip header fields prohibited by HTTP/2 specification. */ - --nheader; - continue; - case HEADERINST_TE_TRAILERS: - nva[i].value = (uint8_t*)"trailers"; - nva[i].value_len = sizeof("trailers") - 1; - break; - default: - nva[i].value = (unsigned char *)hdbuf; - nva[i].value_len = (size_t)(end - hdbuf); - } -#endif - nva[i].value = (unsigned char *)hdbuf; - nva[i].value_len = (size_t)(end - hdbuf); - - ++i; - } - - /* :authority must come before non-pseudo header fields */ - if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { - quiche_h3_header authority = nva[authority_idx]; - for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { - nva[i] = nva[i - 1]; - } - nva[i] = authority; - } - - /* Warn stream may be rejected if cumulative length of headers is too - large. */ -#define MAX_ACC 60000 /* <64KB to account for some overhead */ - { - size_t acc = 0; - - for(i = 0; i < nheader; ++i) { - acc += nva[i].name_len + nva[i].value_len; - - H3BUGF(infof(data, "h3 [%.*s: %.*s]\n", - nva[i].name_len, nva[i].name, - nva[i].value_len, nva[i].value)); - } - - if(acc > MAX_ACC) { - infof(data, "http_request: Warning: The cumulative length of all " + nva[i].name = (unsigned char *)hdbuf; + } + hdbuf = end + 1; + while(*hdbuf == ' ' || *hdbuf == '\t') + ++hdbuf; + end = line_end; + +#if 0 /* This should probably go in more or less like this */ + switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf, + end - hdbuf)) { + case HEADERINST_IGNORE: + /* skip header fields prohibited by HTTP/2 specification. */ + --nheader; + continue; + case HEADERINST_TE_TRAILERS: + nva[i].value = (uint8_t*)"trailers"; + nva[i].value_len = sizeof("trailers") - 1; + break; + default: + nva[i].value = (unsigned char *)hdbuf; + nva[i].value_len = (size_t)(end - hdbuf); + } +#endif + nva[i].value = (unsigned char *)hdbuf; + nva[i].value_len = (size_t)(end - hdbuf); + + ++i; + } + + /* :authority must come before non-pseudo header fields */ + if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { + quiche_h3_header authority = nva[authority_idx]; + for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { + nva[i] = nva[i - 1]; + } + nva[i] = authority; + } + + /* Warn stream may be rejected if cumulative length of headers is too + large. */ +#define MAX_ACC 60000 /* <64KB to account for some overhead */ + { + size_t acc = 0; + + for(i = 0; i < nheader; ++i) { + acc += nva[i].name_len + nva[i].value_len; + + H3BUGF(infof(data, "h3 [%.*s: %.*s]\n", + nva[i].name_len, nva[i].name, + nva[i].value_len, nva[i].value)); + } + + if(acc > MAX_ACC) { + infof(data, "http_request: Warning: The cumulative length of all " "headers exceeds %d bytes and that could cause the " - "stream to be rejected.\n", MAX_ACC); - } - } - + "stream to be rejected.\n", MAX_ACC); + } + } + switch(data->state.httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - case HTTPREQ_PUT: - if(data->state.infilesize != -1) - stream->upload_left = data->state.infilesize; - else - /* data sending without specifying the data amount up front */ - stream->upload_left = -1; /* unknown, but not zero */ - - stream3_id = quiche_h3_send_request(qs->h3c, qs->conn, nva, nheader, - stream->upload_left ? FALSE: TRUE); - if((stream3_id >= 0) && data->set.postfields) { - ssize_t sent = quiche_h3_send_body(qs->h3c, qs->conn, stream3_id, - (uint8_t *)data->set.postfields, - stream->upload_left, TRUE); - if(sent <= 0) { - failf(data, "quiche_h3_send_body failed!"); - result = CURLE_SEND_ERROR; - } - stream->upload_left = 0; /* nothing left to send */ - } - break; - default: - stream3_id = quiche_h3_send_request(qs->h3c, qs->conn, nva, nheader, - TRUE); - break; - } - - Curl_safefree(nva); - - if(stream3_id < 0) { - H3BUGF(infof(data, "quiche_h3_send_request returned %d\n", - stream3_id)); - result = CURLE_SEND_ERROR; - goto fail; - } - - infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n", - stream3_id, (void *)data); - stream->stream3_id = stream3_id; - - return CURLE_OK; - -fail: - free(nva); - return result; -} - -/* - * Called from transfer.c:done_sending when we stop HTTP/3 uploading. - */ -CURLcode Curl_quic_done_sending(struct connectdata *conn) -{ - if(conn->handler == &Curl_handler_http3) { - /* only for HTTP/3 transfers */ - ssize_t sent; + case HTTPREQ_POST: + case HTTPREQ_POST_FORM: + case HTTPREQ_POST_MIME: + case HTTPREQ_PUT: + if(data->state.infilesize != -1) + stream->upload_left = data->state.infilesize; + else + /* data sending without specifying the data amount up front */ + stream->upload_left = -1; /* unknown, but not zero */ + + stream3_id = quiche_h3_send_request(qs->h3c, qs->conn, nva, nheader, + stream->upload_left ? FALSE: TRUE); + if((stream3_id >= 0) && data->set.postfields) { + ssize_t sent = quiche_h3_send_body(qs->h3c, qs->conn, stream3_id, + (uint8_t *)data->set.postfields, + stream->upload_left, TRUE); + if(sent <= 0) { + failf(data, "quiche_h3_send_body failed!"); + result = CURLE_SEND_ERROR; + } + stream->upload_left = 0; /* nothing left to send */ + } + break; + default: + stream3_id = quiche_h3_send_request(qs->h3c, qs->conn, nva, nheader, + TRUE); + break; + } + + Curl_safefree(nva); + + if(stream3_id < 0) { + H3BUGF(infof(data, "quiche_h3_send_request returned %d\n", + stream3_id)); + result = CURLE_SEND_ERROR; + goto fail; + } + + infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n", + stream3_id, (void *)data); + stream->stream3_id = stream3_id; + + return CURLE_OK; + +fail: + free(nva); + return result; +} + +/* + * Called from transfer.c:done_sending when we stop HTTP/3 uploading. + */ +CURLcode Curl_quic_done_sending(struct connectdata *conn) +{ + if(conn->handler == &Curl_handler_http3) { + /* only for HTTP/3 transfers */ + ssize_t sent; struct HTTP *stream = conn->data->req.p.http; - struct quicsocket *qs = conn->quic; - fprintf(stderr, "!!! Curl_quic_done_sending\n"); - stream->upload_done = TRUE; - sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id, - NULL, 0, TRUE); - if(sent < 0) - return CURLE_SEND_ERROR; - } - - return CURLE_OK; -} - + struct quicsocket *qs = conn->quic; + fprintf(stderr, "!!! Curl_quic_done_sending\n"); + stream->upload_done = TRUE; + sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id, + NULL, 0, TRUE); + if(sent < 0) + return CURLE_SEND_ERROR; + } + + return CURLE_OK; +} + /* * Called from http.c:Curl_http_done when a request completes. */ @@ -863,4 +863,4 @@ bool Curl_quic_data_pending(const struct Curl_easy *data) return FALSE; } -#endif +#endif diff --git a/contrib/libs/curl/lib/vssh/libssh.c b/contrib/libs/curl/lib/vssh/libssh.c index 538bd61d30..87d6187544 100644 --- a/contrib/libs/curl/lib/vssh/libssh.c +++ b/contrib/libs/curl/lib/vssh/libssh.c @@ -1,102 +1,102 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 2017 - 2020 Red Hat, Inc. - * - * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek, - * Robert Kolcun, Andreas Schneider - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek, + * Robert Kolcun, Andreas Schneider + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_LIBSSH - -#include <limits.h> - -#error #include <libssh/libssh.h> -#error #include <libssh/sftp.h> - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_UTSNAME_H -#include <sys/utsname.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef __VMS -#include <in.h> -#include <inet.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include <curl/curl.h> -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "http.h" /* for HTTP proxy tunnel stuff */ -#include "ssh.h" -#include "url.h" -#include "speedcheck.h" -#include "getinfo.h" -#include "strdup.h" -#include "strcase.h" -#include "vtls/vtls.h" -#include "connect.h" -#include "strerror.h" -#include "inet_ntop.h" -#include "parsedate.h" /* for the week day and month names */ -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "strtoofft.h" -#include "multiif.h" -#include "select.h" -#include "warnless.h" - -/* for permission and open flags */ -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" -#include "curl_path.h" - -/* A recent macro provided by libssh. Or make our own. */ -#ifndef SSH_STRING_FREE_CHAR + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_LIBSSH + +#include <limits.h> + +#error #include <libssh/libssh.h> +#error #include <libssh/sftp.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_UTSNAME_H +#include <sys/utsname.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#ifdef __VMS +#include <in.h> +#include <inet.h> +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include <curl/curl.h> +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "ssh.h" +#include "url.h" +#include "speedcheck.h" +#include "getinfo.h" +#include "strdup.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "inet_ntop.h" +#include "parsedate.h" /* for the week day and month names */ +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "strtoofft.h" +#include "multiif.h" +#include "select.h" +#include "warnless.h" + +/* for permission and open flags */ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" +#include "curl_path.h" + +/* A recent macro provided by libssh. Or make our own. */ +#ifndef SSH_STRING_FREE_CHAR #define SSH_STRING_FREE_CHAR(x) \ do { \ if(x) { \ @@ -104,235 +104,235 @@ x = NULL; \ } \ } while(0) -#endif - -/* Local functions: */ -static CURLcode myssh_connect(struct connectdata *conn, bool *done); -static CURLcode myssh_multi_statemach(struct connectdata *conn, - bool *done); -static CURLcode myssh_do_it(struct connectdata *conn, bool *done); - -static CURLcode scp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done); -static CURLcode scp_disconnect(struct connectdata *conn, - bool dead_connection); - -static CURLcode sftp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode sftp_doing(struct connectdata *conn, - bool *dophase_done); -static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); -static -CURLcode sftp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done); - -static void sftp_quote(struct connectdata *conn); -static void sftp_quote_stat(struct connectdata *conn); -static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock); -static int myssh_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock); - -static CURLcode myssh_setup_connection(struct connectdata *conn); - -/* - * SCP protocol handler. - */ - -const struct Curl_handler Curl_handler_scp = { - "SCP", /* scheme */ - myssh_setup_connection, /* setup_connection */ - myssh_do_it, /* do_it */ - scp_done, /* done */ - ZERO_NULL, /* do_more */ - myssh_connect, /* connect_it */ - myssh_multi_statemach, /* connecting */ - scp_doing, /* doing */ - myssh_getsock, /* proto_getsock */ - myssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - myssh_perform_getsock, /* perform_getsock */ - scp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - ZERO_NULL, /* connection_check */ - PORT_SSH, /* defport */ - CURLPROTO_SCP, /* protocol */ +#endif + +/* Local functions: */ +static CURLcode myssh_connect(struct connectdata *conn, bool *done); +static CURLcode myssh_multi_statemach(struct connectdata *conn, + bool *done); +static CURLcode myssh_do_it(struct connectdata *conn, bool *done); + +static CURLcode scp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done); +static CURLcode scp_disconnect(struct connectdata *conn, + bool dead_connection); + +static CURLcode sftp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done); + +static void sftp_quote(struct connectdata *conn); +static void sftp_quote_stat(struct connectdata *conn); +static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock); +static int myssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock); + +static CURLcode myssh_setup_connection(struct connectdata *conn); + +/* + * SCP protocol handler. + */ + +const struct Curl_handler Curl_handler_scp = { + "SCP", /* scheme */ + myssh_setup_connection, /* setup_connection */ + myssh_do_it, /* do_it */ + scp_done, /* done */ + ZERO_NULL, /* do_more */ + myssh_connect, /* connect_it */ + myssh_multi_statemach, /* connecting */ + scp_doing, /* doing */ + myssh_getsock, /* proto_getsock */ + myssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + myssh_perform_getsock, /* perform_getsock */ + scp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SCP, /* protocol */ CURLPROTO_SCP, /* family */ - PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ -}; - -/* - * SFTP protocol handler. - */ - -const struct Curl_handler Curl_handler_sftp = { - "SFTP", /* scheme */ - myssh_setup_connection, /* setup_connection */ - myssh_do_it, /* do_it */ - sftp_done, /* done */ - ZERO_NULL, /* do_more */ - myssh_connect, /* connect_it */ - myssh_multi_statemach, /* connecting */ - sftp_doing, /* doing */ - myssh_getsock, /* proto_getsock */ - myssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - myssh_perform_getsock, /* perform_getsock */ - sftp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - ZERO_NULL, /* connection_check */ - PORT_SSH, /* defport */ - CURLPROTO_SFTP, /* protocol */ + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ +}; + +/* + * SFTP protocol handler. + */ + +const struct Curl_handler Curl_handler_sftp = { + "SFTP", /* scheme */ + myssh_setup_connection, /* setup_connection */ + myssh_do_it, /* do_it */ + sftp_done, /* done */ + ZERO_NULL, /* do_more */ + myssh_connect, /* connect_it */ + myssh_multi_statemach, /* connecting */ + sftp_doing, /* doing */ + myssh_getsock, /* proto_getsock */ + myssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + myssh_perform_getsock, /* perform_getsock */ + sftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SFTP, /* protocol */ CURLPROTO_SFTP, /* family */ - PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION - | PROTOPT_NOURLQUERY /* flags */ -}; - -static CURLcode sftp_error_to_CURLE(int err) -{ - switch(err) { - case SSH_FX_OK: - return CURLE_OK; - - case SSH_FX_NO_SUCH_FILE: - case SSH_FX_NO_SUCH_PATH: - return CURLE_REMOTE_FILE_NOT_FOUND; - - case SSH_FX_PERMISSION_DENIED: - case SSH_FX_WRITE_PROTECT: - return CURLE_REMOTE_ACCESS_DENIED; - - case SSH_FX_FILE_ALREADY_EXISTS: - return CURLE_REMOTE_FILE_EXISTS; - - default: - break; - } - - return CURLE_SSH; -} - -#ifndef DEBUGBUILD -#define state(x,y) mystate(x,y) -#else -#define state(x,y) mystate(x,y, __LINE__) -#endif - -/* - * SSH State machine related code - */ -/* This is the ONLY way to change SSH state! */ -static void mystate(struct connectdata *conn, sshstate nowstate -#ifdef DEBUGBUILD - , int lineno -#endif - ) -{ - struct ssh_conn *sshc = &conn->proto.sshc; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ - static const char *const names[] = { - "SSH_STOP", - "SSH_INIT", - "SSH_S_STARTUP", - "SSH_HOSTKEY", - "SSH_AUTHLIST", - "SSH_AUTH_PKEY_INIT", - "SSH_AUTH_PKEY", - "SSH_AUTH_PASS_INIT", - "SSH_AUTH_PASS", - "SSH_AUTH_AGENT_INIT", - "SSH_AUTH_AGENT_LIST", - "SSH_AUTH_AGENT", - "SSH_AUTH_HOST_INIT", - "SSH_AUTH_HOST", - "SSH_AUTH_KEY_INIT", - "SSH_AUTH_KEY", - "SSH_AUTH_GSSAPI", - "SSH_AUTH_DONE", - "SSH_SFTP_INIT", - "SSH_SFTP_REALPATH", - "SSH_SFTP_QUOTE_INIT", - "SSH_SFTP_POSTQUOTE_INIT", - "SSH_SFTP_QUOTE", - "SSH_SFTP_NEXT_QUOTE", - "SSH_SFTP_QUOTE_STAT", - "SSH_SFTP_QUOTE_SETSTAT", - "SSH_SFTP_QUOTE_SYMLINK", - "SSH_SFTP_QUOTE_MKDIR", - "SSH_SFTP_QUOTE_RENAME", - "SSH_SFTP_QUOTE_RMDIR", - "SSH_SFTP_QUOTE_UNLINK", - "SSH_SFTP_QUOTE_STATVFS", - "SSH_SFTP_GETINFO", - "SSH_SFTP_FILETIME", - "SSH_SFTP_TRANS_INIT", - "SSH_SFTP_UPLOAD_INIT", - "SSH_SFTP_CREATE_DIRS_INIT", - "SSH_SFTP_CREATE_DIRS", - "SSH_SFTP_CREATE_DIRS_MKDIR", - "SSH_SFTP_READDIR_INIT", - "SSH_SFTP_READDIR", - "SSH_SFTP_READDIR_LINK", - "SSH_SFTP_READDIR_BOTTOM", - "SSH_SFTP_READDIR_DONE", - "SSH_SFTP_DOWNLOAD_INIT", - "SSH_SFTP_DOWNLOAD_STAT", - "SSH_SFTP_CLOSE", - "SSH_SFTP_SHUTDOWN", - "SSH_SCP_TRANS_INIT", - "SSH_SCP_UPLOAD_INIT", - "SSH_SCP_DOWNLOAD_INIT", - "SSH_SCP_DOWNLOAD", - "SSH_SCP_DONE", - "SSH_SCP_SEND_EOF", - "SSH_SCP_WAIT_EOF", - "SSH_SCP_WAIT_CLOSE", - "SSH_SCP_CHANNEL_FREE", - "SSH_SESSION_DISCONNECT", - "SSH_SESSION_FREE", - "QUIT" - }; - - - if(sshc->state != nowstate) { - infof(conn->data, "SSH %p state change from %s to %s (line %d)\n", - (void *) sshc, names[sshc->state], names[nowstate], - lineno); - } -#endif - - sshc->state = nowstate; -} - -/* Multiple options: - * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5 - * hash (90s style auth, not sure we should have it here) - * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first - * use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE - * is returned by it. - * 3. none of the above. We only accept if it is present on known hosts. - * - * Returns SSH_OK or SSH_ERROR. - */ -static int myssh_is_known(struct connectdata *conn) -{ - int rc; - struct Curl_easy *data = conn->data; - struct ssh_conn *sshc = &conn->proto.sshc; - ssh_key pubkey; - size_t hlen; - unsigned char *hash = NULL; + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION + | PROTOPT_NOURLQUERY /* flags */ +}; + +static CURLcode sftp_error_to_CURLE(int err) +{ + switch(err) { + case SSH_FX_OK: + return CURLE_OK; + + case SSH_FX_NO_SUCH_FILE: + case SSH_FX_NO_SUCH_PATH: + return CURLE_REMOTE_FILE_NOT_FOUND; + + case SSH_FX_PERMISSION_DENIED: + case SSH_FX_WRITE_PROTECT: + return CURLE_REMOTE_ACCESS_DENIED; + + case SSH_FX_FILE_ALREADY_EXISTS: + return CURLE_REMOTE_FILE_EXISTS; + + default: + break; + } + + return CURLE_SSH; +} + +#ifndef DEBUGBUILD +#define state(x,y) mystate(x,y) +#else +#define state(x,y) mystate(x,y, __LINE__) +#endif + +/* + * SSH State machine related code + */ +/* This is the ONLY way to change SSH state! */ +static void mystate(struct connectdata *conn, sshstate nowstate +#ifdef DEBUGBUILD + , int lineno +#endif + ) +{ + struct ssh_conn *sshc = &conn->proto.sshc; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char *const names[] = { + "SSH_STOP", + "SSH_INIT", + "SSH_S_STARTUP", + "SSH_HOSTKEY", + "SSH_AUTHLIST", + "SSH_AUTH_PKEY_INIT", + "SSH_AUTH_PKEY", + "SSH_AUTH_PASS_INIT", + "SSH_AUTH_PASS", + "SSH_AUTH_AGENT_INIT", + "SSH_AUTH_AGENT_LIST", + "SSH_AUTH_AGENT", + "SSH_AUTH_HOST_INIT", + "SSH_AUTH_HOST", + "SSH_AUTH_KEY_INIT", + "SSH_AUTH_KEY", + "SSH_AUTH_GSSAPI", + "SSH_AUTH_DONE", + "SSH_SFTP_INIT", + "SSH_SFTP_REALPATH", + "SSH_SFTP_QUOTE_INIT", + "SSH_SFTP_POSTQUOTE_INIT", + "SSH_SFTP_QUOTE", + "SSH_SFTP_NEXT_QUOTE", + "SSH_SFTP_QUOTE_STAT", + "SSH_SFTP_QUOTE_SETSTAT", + "SSH_SFTP_QUOTE_SYMLINK", + "SSH_SFTP_QUOTE_MKDIR", + "SSH_SFTP_QUOTE_RENAME", + "SSH_SFTP_QUOTE_RMDIR", + "SSH_SFTP_QUOTE_UNLINK", + "SSH_SFTP_QUOTE_STATVFS", + "SSH_SFTP_GETINFO", + "SSH_SFTP_FILETIME", + "SSH_SFTP_TRANS_INIT", + "SSH_SFTP_UPLOAD_INIT", + "SSH_SFTP_CREATE_DIRS_INIT", + "SSH_SFTP_CREATE_DIRS", + "SSH_SFTP_CREATE_DIRS_MKDIR", + "SSH_SFTP_READDIR_INIT", + "SSH_SFTP_READDIR", + "SSH_SFTP_READDIR_LINK", + "SSH_SFTP_READDIR_BOTTOM", + "SSH_SFTP_READDIR_DONE", + "SSH_SFTP_DOWNLOAD_INIT", + "SSH_SFTP_DOWNLOAD_STAT", + "SSH_SFTP_CLOSE", + "SSH_SFTP_SHUTDOWN", + "SSH_SCP_TRANS_INIT", + "SSH_SCP_UPLOAD_INIT", + "SSH_SCP_DOWNLOAD_INIT", + "SSH_SCP_DOWNLOAD", + "SSH_SCP_DONE", + "SSH_SCP_SEND_EOF", + "SSH_SCP_WAIT_EOF", + "SSH_SCP_WAIT_CLOSE", + "SSH_SCP_CHANNEL_FREE", + "SSH_SESSION_DISCONNECT", + "SSH_SESSION_FREE", + "QUIT" + }; + + + if(sshc->state != nowstate) { + infof(conn->data, "SSH %p state change from %s to %s (line %d)\n", + (void *) sshc, names[sshc->state], names[nowstate], + lineno); + } +#endif + + sshc->state = nowstate; +} + +/* Multiple options: + * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5 + * hash (90s style auth, not sure we should have it here) + * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first + * use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE + * is returned by it. + * 3. none of the above. We only accept if it is present on known hosts. + * + * Returns SSH_OK or SSH_ERROR. + */ +static int myssh_is_known(struct connectdata *conn) +{ + int rc; + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + ssh_key pubkey; + size_t hlen; + unsigned char *hash = NULL; char *found_base64 = NULL; char *known_base64 = NULL; - int vstate; - enum curl_khmatch keymatch; - struct curl_khkey foundkey; + int vstate; + enum curl_khmatch keymatch; + struct curl_khkey foundkey; struct curl_khkey *knownkeyp = NULL; - curl_sshkeycallback func = - data->set.ssh_keyfunc; - + curl_sshkeycallback func = + data->set.ssh_keyfunc; + #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0) struct ssh_knownhosts_entry *knownhostsentry = NULL; struct curl_khkey knownkey; @@ -341,24 +341,24 @@ static int myssh_is_known(struct connectdata *conn) #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0) rc = ssh_get_server_publickey(sshc->ssh_session, &pubkey); #else - rc = ssh_get_publickey(sshc->ssh_session, &pubkey); + rc = ssh_get_publickey(sshc->ssh_session, &pubkey); #endif - if(rc != SSH_OK) - return rc; - - if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) { + if(rc != SSH_OK) + return rc; + + if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) { int i; char md5buffer[33]; const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; - rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, - &hash, &hlen); + rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, + &hash, &hlen); if(rc != SSH_OK || hlen != 16) { failf(data, "Denied establishing ssh session: md5 fingerprint not available"); - goto cleanup; + goto cleanup; } - + for(i = 0; i < 16; i++) msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char)hash[i]); @@ -368,19 +368,19 @@ static int myssh_is_known(struct connectdata *conn) failf(data, "Denied establishing ssh session: mismatch md5 fingerprint. " "Remote %s is not equal to %s", md5buffer, pubkey_md5); - rc = SSH_ERROR; - goto cleanup; - } - - rc = SSH_OK; - goto cleanup; - } - - if(data->set.ssl.primary.verifyhost != TRUE) { - rc = SSH_OK; - goto cleanup; - } - + rc = SSH_ERROR; + goto cleanup; + } + + rc = SSH_OK; + goto cleanup; + } + + if(data->set.ssl.primary.verifyhost != TRUE) { + rc = SSH_OK; + goto cleanup; + } + #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0) /* Get the known_key from the known hosts file */ vstate = ssh_session_get_known_hosts_entry(sshc->ssh_session, @@ -443,1741 +443,1741 @@ static int myssh_is_known(struct connectdata *conn) } #else - vstate = ssh_is_server_known(sshc->ssh_session); - switch(vstate) { - case SSH_SERVER_KNOWN_OK: - keymatch = CURLKHMATCH_OK; - break; - case SSH_SERVER_FILE_NOT_FOUND: - /* fallthrough */ - case SSH_SERVER_NOT_KNOWN: - keymatch = CURLKHMATCH_MISSING; - break; - default: - keymatch = CURLKHMATCH_MISMATCH; - break; - } + vstate = ssh_is_server_known(sshc->ssh_session); + switch(vstate) { + case SSH_SERVER_KNOWN_OK: + keymatch = CURLKHMATCH_OK; + break; + case SSH_SERVER_FILE_NOT_FOUND: + /* fallthrough */ + case SSH_SERVER_NOT_KNOWN: + keymatch = CURLKHMATCH_MISSING; + break; + default: + keymatch = CURLKHMATCH_MISMATCH; + break; + } #endif - - if(func) { /* use callback to determine action */ + + if(func) { /* use callback to determine action */ rc = ssh_pki_export_pubkey_base64(pubkey, &found_base64); - if(rc != SSH_OK) - goto cleanup; - + if(rc != SSH_OK) + goto cleanup; + foundkey.key = found_base64; foundkey.len = strlen(found_base64); - - switch(ssh_key_type(pubkey)) { - case SSH_KEYTYPE_RSA: - foundkey.keytype = CURLKHTYPE_RSA; - break; - case SSH_KEYTYPE_RSA1: - foundkey.keytype = CURLKHTYPE_RSA1; - break; - case SSH_KEYTYPE_ECDSA: + + switch(ssh_key_type(pubkey)) { + case SSH_KEYTYPE_RSA: + foundkey.keytype = CURLKHTYPE_RSA; + break; + case SSH_KEYTYPE_RSA1: + foundkey.keytype = CURLKHTYPE_RSA1; + break; + case SSH_KEYTYPE_ECDSA: #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0) case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P521: #endif - foundkey.keytype = CURLKHTYPE_ECDSA; - break; -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0) - case SSH_KEYTYPE_ED25519: - foundkey.keytype = CURLKHTYPE_ED25519; - break; -#endif - case SSH_KEYTYPE_DSS: - foundkey.keytype = CURLKHTYPE_DSS; - break; - default: - rc = SSH_ERROR; - goto cleanup; - } - - Curl_set_in_callback(data, true); + foundkey.keytype = CURLKHTYPE_ECDSA; + break; +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0) + case SSH_KEYTYPE_ED25519: + foundkey.keytype = CURLKHTYPE_ED25519; + break; +#endif + case SSH_KEYTYPE_DSS: + foundkey.keytype = CURLKHTYPE_DSS; + break; + default: + rc = SSH_ERROR; + goto cleanup; + } + + Curl_set_in_callback(data, true); rc = func(data, knownkeyp, /* from the knownhosts file */ &foundkey, /* from the remote host */ - keymatch, data->set.ssh_keyfunc_userp); - Curl_set_in_callback(data, false); - - switch(rc) { - case CURLKHSTAT_FINE_ADD_TO_FILE: + keymatch, data->set.ssh_keyfunc_userp); + Curl_set_in_callback(data, false); + + switch(rc) { + case CURLKHSTAT_FINE_ADD_TO_FILE: #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0) rc = ssh_session_update_known_hosts(sshc->ssh_session); #else - rc = ssh_write_knownhost(sshc->ssh_session); + rc = ssh_write_knownhost(sshc->ssh_session); #endif - if(rc != SSH_OK) { - goto cleanup; - } - break; - case CURLKHSTAT_FINE: - break; - default: /* REJECT/DEFER */ - rc = SSH_ERROR; - goto cleanup; - } - } - else { - if(keymatch != CURLKHMATCH_OK) { - rc = SSH_ERROR; - goto cleanup; - } - } - rc = SSH_OK; - -cleanup: + if(rc != SSH_OK) { + goto cleanup; + } + break; + case CURLKHSTAT_FINE: + break; + default: /* REJECT/DEFER */ + rc = SSH_ERROR; + goto cleanup; + } + } + else { + if(keymatch != CURLKHMATCH_OK) { + rc = SSH_ERROR; + goto cleanup; + } + } + rc = SSH_OK; + +cleanup: if(found_base64) { free(found_base64); } if(known_base64) { free(known_base64); } - if(hash) - ssh_clean_pubkey_hash(&hash); - ssh_key_free(pubkey); + if(hash) + ssh_clean_pubkey_hash(&hash); + ssh_key_free(pubkey); #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0) if(knownhostsentry) { ssh_knownhosts_entry_free(knownhostsentry); } #endif - return rc; -} - -#define MOVE_TO_ERROR_STATE(_r) { \ - state(conn, SSH_SESSION_DISCONNECT); \ - sshc->actualcode = _r; \ - rc = SSH_ERROR; \ - break; \ -} - -#define MOVE_TO_SFTP_CLOSE_STATE() { \ - state(conn, SSH_SFTP_CLOSE); \ - sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ - rc = SSH_ERROR; \ - break; \ -} - -#define MOVE_TO_LAST_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ - rc = SSH_OK; \ - state(conn, SSH_AUTH_PASS_INIT); \ - break; \ - } \ - else { \ - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ - } - -#define MOVE_TO_TERTIARY_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ - rc = SSH_OK; \ - state(conn, SSH_AUTH_KEY_INIT); \ - break; \ - } \ - else { \ - MOVE_TO_LAST_AUTH; \ - } - -#define MOVE_TO_SECONDARY_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ - rc = SSH_OK; \ - state(conn, SSH_AUTH_GSSAPI); \ - break; \ - } \ - else { \ - MOVE_TO_TERTIARY_AUTH; \ - } - -static -int myssh_auth_interactive(struct connectdata *conn) -{ - int rc; - struct ssh_conn *sshc = &conn->proto.sshc; - int nprompts; - -restart: - switch(sshc->kbd_state) { - case 0: - rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - - if(rc != SSH_AUTH_INFO) - return SSH_ERROR; - - nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); + return rc; +} + +#define MOVE_TO_ERROR_STATE(_r) { \ + state(conn, SSH_SESSION_DISCONNECT); \ + sshc->actualcode = _r; \ + rc = SSH_ERROR; \ + break; \ +} + +#define MOVE_TO_SFTP_CLOSE_STATE() { \ + state(conn, SSH_SFTP_CLOSE); \ + sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ + rc = SSH_ERROR; \ + break; \ +} + +#define MOVE_TO_LAST_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_PASS_INIT); \ + break; \ + } \ + else { \ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ + } + +#define MOVE_TO_TERTIARY_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_KEY_INIT); \ + break; \ + } \ + else { \ + MOVE_TO_LAST_AUTH; \ + } + +#define MOVE_TO_SECONDARY_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_GSSAPI); \ + break; \ + } \ + else { \ + MOVE_TO_TERTIARY_AUTH; \ + } + +static +int myssh_auth_interactive(struct connectdata *conn) +{ + int rc; + struct ssh_conn *sshc = &conn->proto.sshc; + int nprompts; + +restart: + switch(sshc->kbd_state) { + case 0: + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + + if(rc != SSH_AUTH_INFO) + return SSH_ERROR; + + nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); if(nprompts != 1) - return SSH_ERROR; - - rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd); - if(rc < 0) - return SSH_ERROR; - - /* FALLTHROUGH */ - case 1: - sshc->kbd_state = 1; - - rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - else if(rc == SSH_AUTH_SUCCESS) - rc = SSH_OK; - else if(rc == SSH_AUTH_INFO) { - nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); - if(nprompts != 0) - return SSH_ERROR; - - sshc->kbd_state = 2; - goto restart; - } - else - rc = SSH_ERROR; - break; - case 2: - sshc->kbd_state = 2; - - rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - else if(rc == SSH_AUTH_SUCCESS) - rc = SSH_OK; - else - rc = SSH_ERROR; - - break; - default: - return SSH_ERROR; - } - - sshc->kbd_state = 0; - return rc; -} - -/* - * ssh_statemach_act() runs the SSH state machine as far as it can without - * blocking and without reaching the end. The data the pointer 'block' points - * to will be set to TRUE if the libssh function returns SSH_AGAIN - * meaning it wants to be called again when the socket is ready - */ -static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) -{ - CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + return SSH_ERROR; + + rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd); + if(rc < 0) + return SSH_ERROR; + + /* FALLTHROUGH */ + case 1: + sshc->kbd_state = 1; + + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + else if(rc == SSH_AUTH_SUCCESS) + rc = SSH_OK; + else if(rc == SSH_AUTH_INFO) { + nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); + if(nprompts != 0) + return SSH_ERROR; + + sshc->kbd_state = 2; + goto restart; + } + else + rc = SSH_ERROR; + break; + case 2: + sshc->kbd_state = 2; + + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + else if(rc == SSH_AUTH_SUCCESS) + rc = SSH_OK; + else + rc = SSH_ERROR; + + break; + default: + return SSH_ERROR; + } + + sshc->kbd_state = 0; + return rc; +} + +/* + * ssh_statemach_act() runs the SSH state machine as far as it can without + * blocking and without reaching the end. The data the pointer 'block' points + * to will be set to TRUE if the libssh function returns SSH_AGAIN + * meaning it wants to be called again when the socket is ready + */ +static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; struct SSHPROTO *protop = data->req.p.ssh; - struct ssh_conn *sshc = &conn->proto.sshc; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int rc = SSH_NO_ERROR, err; - char *new_readdir_line; - int seekerr = CURL_SEEKFUNC_OK; - const char *err_msg; - *block = 0; /* we're not blocking by default */ - - do { - - switch(sshc->state) { - case SSH_INIT: - sshc->secondCreateDirs = 0; - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_OK; - -#if 0 - ssh_set_log_level(SSH_LOG_PROTOCOL); -#endif - - /* Set libssh to non-blocking, since everything internally is - non-blocking */ - ssh_set_blocking(sshc->ssh_session, 0); - - state(conn, SSH_S_STARTUP); - /* FALLTHROUGH */ - - case SSH_S_STARTUP: - rc = ssh_connect(sshc->ssh_session); - if(rc == SSH_AGAIN) - break; - - if(rc != SSH_OK) { - failf(data, "Failure establishing ssh session"); - MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT); - } - - state(conn, SSH_HOSTKEY); - - /* FALLTHROUGH */ - case SSH_HOSTKEY: - - rc = myssh_is_known(conn); - if(rc != SSH_OK) { - MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION); - } - - state(conn, SSH_AUTHLIST); - /* FALLTHROUGH */ - case SSH_AUTHLIST:{ - sshc->authed = FALSE; - - rc = ssh_userauth_none(sshc->ssh_session, NULL); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } - - if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Authenticated with none\n"); - state(conn, SSH_AUTH_DONE); - break; - } - else if(rc == SSH_AUTH_ERROR) { - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - } - - sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); - if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { - state(conn, SSH_AUTH_PKEY_INIT); - infof(data, "Authentication using SSH public key file\n"); - } - else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { - state(conn, SSH_AUTH_GSSAPI); - } - else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { - state(conn, SSH_AUTH_KEY_INIT); - } - else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { - state(conn, SSH_AUTH_PASS_INIT); - } - else { /* unsupported authentication method */ - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - } - - break; - } - case SSH_AUTH_PKEY_INIT: - if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { - MOVE_TO_SECONDARY_AUTH; - } - - /* Two choices, (1) private key was given on CMD, - * (2) use the "default" keys. */ - if(data->set.str[STRING_SSH_PRIVATE_KEY]) { - if(sshc->pubkey && !data->set.ssl.key_passwd) { - rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL, - sshc->pubkey); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } - - if(rc != SSH_OK) { - MOVE_TO_SECONDARY_AUTH; - } - } - - rc = ssh_pki_import_privkey_file(data-> - set.str[STRING_SSH_PRIVATE_KEY], - data->set.ssl.key_passwd, NULL, - NULL, &sshc->privkey); - if(rc != SSH_OK) { - failf(data, "Could not load private key file %s", - data->set.str[STRING_SSH_PRIVATE_KEY]); - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - break; - } - - state(conn, SSH_AUTH_PKEY); - break; - - } - else { - rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL, - data->set.ssl.key_passwd); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } - if(rc == SSH_AUTH_SUCCESS) { - rc = SSH_OK; - sshc->authed = TRUE; - infof(data, "Completed public key authentication\n"); - state(conn, SSH_AUTH_DONE); - break; - } - - MOVE_TO_SECONDARY_AUTH; - } - break; - case SSH_AUTH_PKEY: - rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } - - if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Completed public key authentication\n"); - state(conn, SSH_AUTH_DONE); - break; - } - else { - infof(data, "Failed public key authentication (rc: %d)\n", rc); - MOVE_TO_SECONDARY_AUTH; - } - break; - - case SSH_AUTH_GSSAPI: - if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { - MOVE_TO_TERTIARY_AUTH; - } - - rc = ssh_userauth_gssapi(sshc->ssh_session); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } - - if(rc == SSH_AUTH_SUCCESS) { - rc = SSH_OK; - sshc->authed = TRUE; - infof(data, "Completed gssapi authentication\n"); - state(conn, SSH_AUTH_DONE); - break; - } - - MOVE_TO_TERTIARY_AUTH; - break; - - case SSH_AUTH_KEY_INIT: - if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) { - state(conn, SSH_AUTH_KEY); - } - else { - MOVE_TO_LAST_AUTH; - } - break; - - case SSH_AUTH_KEY: - - /* Authentication failed. Continue with keyboard-interactive now. */ - rc = myssh_auth_interactive(conn); - if(rc == SSH_AGAIN) { - break; - } - if(rc == SSH_OK) { - sshc->authed = TRUE; - infof(data, "completed keyboard interactive authentication\n"); - } - state(conn, SSH_AUTH_DONE); - break; - - case SSH_AUTH_PASS_INIT: - if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { - /* Host key authentication is intentionally not implemented */ - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - } - state(conn, SSH_AUTH_PASS); - /* FALLTHROUGH */ - - case SSH_AUTH_PASS: - rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd); - if(rc == SSH_AUTH_AGAIN) { - rc = SSH_AGAIN; - break; - } - - if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Completed password authentication\n"); - state(conn, SSH_AUTH_DONE); - } - else { - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - } - break; - - case SSH_AUTH_DONE: - if(!sshc->authed) { - failf(data, "Authentication failure"); - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); - break; - } - - /* - * At this point we have an authenticated ssh session. - */ - infof(data, "Authentication complete\n"); - - Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ - - conn->sockfd = sock; - conn->writesockfd = CURL_SOCKET_BAD; - - if(conn->handler->protocol == CURLPROTO_SFTP) { - state(conn, SSH_SFTP_INIT); - break; - } - infof(data, "SSH CONNECT phase done\n"); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_INIT: - ssh_set_blocking(sshc->ssh_session, 1); - - sshc->sftp_session = sftp_new(sshc->ssh_session); - if(!sshc->sftp_session) { - failf(data, "Failure initializing sftp session: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); - break; - } - - rc = sftp_init(sshc->sftp_session); - if(rc != SSH_OK) { - rc = sftp_get_error(sshc->sftp_session); - failf(data, "Failure initializing sftp session: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc)); - break; - } - state(conn, SSH_SFTP_REALPATH); - /* FALLTHROUGH */ - case SSH_SFTP_REALPATH: - /* - * Get the "home" directory - */ - sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); - if(sshc->homedir == NULL) { - MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); - } - conn->data->state.most_recent_ftp_entrypath = sshc->homedir; - - /* This is the last step in the SFTP connect phase. Do note that while - we get the homedir here, we get the "workingpath" in the DO action - since the homedir will remain the same between request but the - working path will not. */ - DEBUGF(infof(data, "SSH CONNECT phase done\n")); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_QUOTE_INIT: - - result = Curl_getworkingpath(conn, sshc->homedir, &protop->path); - if(result) { - sshc->actualcode = result; - state(conn, SSH_STOP); - break; - } - - if(data->set.quote) { - infof(data, "Sending quote commands\n"); - sshc->quote_item = data->set.quote; - state(conn, SSH_SFTP_QUOTE); - } - else { - state(conn, SSH_SFTP_GETINFO); - } - break; - - case SSH_SFTP_POSTQUOTE_INIT: - if(data->set.postquote) { - infof(data, "Sending quote commands\n"); - sshc->quote_item = data->set.postquote; - state(conn, SSH_SFTP_QUOTE); - } - else { - state(conn, SSH_STOP); - } - break; - - case SSH_SFTP_QUOTE: - /* Send any quote commands */ - sftp_quote(conn); - break; - - case SSH_SFTP_NEXT_QUOTE: - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - - sshc->quote_item = sshc->quote_item->next; - - if(sshc->quote_item) { - state(conn, SSH_SFTP_QUOTE); - } - else { - if(sshc->nextstate != SSH_NO_STATE) { - state(conn, sshc->nextstate); - sshc->nextstate = SSH_NO_STATE; - } - else { - state(conn, SSH_SFTP_GETINFO); - } - } - break; - - case SSH_SFTP_QUOTE_STAT: - sftp_quote_stat(conn); - break; - - case SSH_SFTP_QUOTE_SETSTAT: - rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2, - sshc->quote_attrs); - if(rc != 0 && !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Attempt to set SFTP stats failed: %s", - ssh_get_error(sshc->ssh_session)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - /* sshc->actualcode = sftp_error_to_CURLE(err); - * we do not send the actual error; we return - * the error the libssh2 backend is returning */ - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_SYMLINK: - rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2, - sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "symlink command failed: %s", - ssh_get_error(sshc->ssh_session)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_MKDIR: - rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1, - (mode_t)data->set.new_directory_perms); - if(rc != 0 && !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - failf(data, "mkdir command failed: %s", - ssh_get_error(sshc->ssh_session)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_RENAME: - rc = sftp_rename(sshc->sftp_session, sshc->quote_path1, - sshc->quote_path2); - if(rc != 0 && !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "rename command failed: %s", - ssh_get_error(sshc->ssh_session)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_RMDIR: - rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - failf(data, "rmdir command failed: %s", - ssh_get_error(sshc->ssh_session)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_UNLINK: - rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - failf(data, "rm command failed: %s", - ssh_get_error(sshc->ssh_session)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_STATVFS: - { - sftp_statvfs_t statvfs; - - statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1); - if(!statvfs && !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - failf(data, "statvfs command failed: %s", - ssh_get_error(sshc->ssh_session)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - else if(statvfs) { - char *tmp = aprintf("statvfs:\n" - "f_bsize: %llu\n" "f_frsize: %llu\n" - "f_blocks: %llu\n" "f_bfree: %llu\n" - "f_bavail: %llu\n" "f_files: %llu\n" - "f_ffree: %llu\n" "f_favail: %llu\n" - "f_fsid: %llu\n" "f_flag: %llu\n" - "f_namemax: %llu\n", - statvfs->f_bsize, statvfs->f_frsize, - statvfs->f_blocks, statvfs->f_bfree, - statvfs->f_bavail, statvfs->f_files, - statvfs->f_ffree, statvfs->f_favail, - statvfs->f_fsid, statvfs->f_flag, - statvfs->f_namemax); - sftp_statvfs_free(statvfs); - - if(!tmp) { - result = CURLE_OUT_OF_MEMORY; - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - break; - } - - result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - free(tmp); - if(result) { - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - } - - case SSH_SFTP_GETINFO: - if(data->set.get_filetime) { - state(conn, SSH_SFTP_FILETIME); - } - else { - state(conn, SSH_SFTP_TRANS_INIT); - } - break; - - case SSH_SFTP_FILETIME: - { - sftp_attributes attrs; - - attrs = sftp_stat(sshc->sftp_session, protop->path); - if(attrs != 0) { - data->info.filetime = attrs->mtime; - sftp_attributes_free(attrs); - } - - state(conn, SSH_SFTP_TRANS_INIT); - break; - } - - case SSH_SFTP_TRANS_INIT: - if(data->set.upload) - state(conn, SSH_SFTP_UPLOAD_INIT); - else { - if(protop->path[strlen(protop->path)-1] == '/') - state(conn, SSH_SFTP_READDIR_INIT); - else - state(conn, SSH_SFTP_DOWNLOAD_INIT); - } - break; - - case SSH_SFTP_UPLOAD_INIT: - { - int flags; - - if(data->state.resume_from != 0) { - sftp_attributes attrs; - - if(data->state.resume_from < 0) { - attrs = sftp_stat(sshc->sftp_session, protop->path); - if(attrs != 0) { - curl_off_t size = attrs->size; - if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); - MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); - } - data->state.resume_from = attrs->size; - - sftp_attributes_free(attrs); - } - else { - data->state.resume_from = 0; - } - } - } - - if(data->set.ftp_append) - /* Try to open for append, but create if nonexisting */ - flags = O_WRONLY|O_CREAT|O_APPEND; - else if(data->state.resume_from > 0) - /* If we have restart position then open for append */ - flags = O_WRONLY|O_APPEND; - else - /* Clear file before writing (normal behaviour) */ - flags = O_WRONLY|O_CREAT|O_TRUNC; - - if(sshc->sftp_file) - sftp_close(sshc->sftp_file); - sshc->sftp_file = - sftp_open(sshc->sftp_session, protop->path, - flags, (mode_t)data->set.new_file_perms); - if(!sshc->sftp_file) { - err = sftp_get_error(sshc->sftp_session); - - if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE || - err == SSH_FX_NO_SUCH_PATH)) && - (data->set.ftp_create_missing_dirs && - (strlen(protop->path) > 1))) { - /* try to create the path remotely */ - rc = 0; - sshc->secondCreateDirs = 1; - state(conn, SSH_SFTP_CREATE_DIRS_INIT); - break; - } - else { - MOVE_TO_SFTP_CLOSE_STATE(); - } - } - - /* If we have a restart point then we need to seek to the correct - position. */ - if(data->state.resume_from > 0) { - /* Let's read off the proper amount of bytes from the input. */ - if(conn->seek_func) { - Curl_set_in_callback(data, true); - seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, - SEEK_SET); - Curl_set_in_callback(data, false); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - curl_off_t passed = 0; - - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - return CURLE_FTP_COULDNT_USE_REST; - } - /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ - do { - size_t readthisamountnow = - (data->state.resume_from - passed > data->set.buffer_size) ? - (size_t)data->set.buffer_size : - curlx_sotouz(data->state.resume_from - passed); - - size_t actuallyread = - data->state.fread_func(data->state.buffer, 1, - readthisamountnow, data->state.in); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Failed to read data"); - MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST); - } - } while(passed < data->state.resume_from); - } - - /* now, decrease the size of the read */ - if(data->state.infilesize > 0) { - data->state.infilesize -= data->state.resume_from; - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - - rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); - if(rc != 0) { - MOVE_TO_SFTP_CLOSE_STATE(); - } - } - if(data->state.infilesize > 0) { - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - /* upload data */ - Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->sockfd = conn->writesockfd; - - /* store this original bitmask setup to use later on if we can't - figure out a "real" bitmask */ - sshc->orig_waitfor = data->req.keepon; - - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh sftp send function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_OUT; - - /* since we don't really wait for anything at this point, we want the - state machine to move on as soon as possible so we set a very short - timeout here */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); - - state(conn, SSH_STOP); - break; - } - - case SSH_SFTP_CREATE_DIRS_INIT: - if(strlen(protop->path) > 1) { - sshc->slash_pos = protop->path + 1; /* ignore the leading '/' */ - state(conn, SSH_SFTP_CREATE_DIRS); - } - else { - state(conn, SSH_SFTP_UPLOAD_INIT); - } - break; - - case SSH_SFTP_CREATE_DIRS: - sshc->slash_pos = strchr(sshc->slash_pos, '/'); - if(sshc->slash_pos) { - *sshc->slash_pos = 0; - - infof(data, "Creating directory '%s'\n", protop->path); - state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); - break; - } - state(conn, SSH_SFTP_UPLOAD_INIT); - break; - - case SSH_SFTP_CREATE_DIRS_MKDIR: - /* 'mode' - parameter is preliminary - default to 0644 */ - rc = sftp_mkdir(sshc->sftp_session, protop->path, - (mode_t)data->set.new_directory_perms); - *sshc->slash_pos = '/'; - ++sshc->slash_pos; - if(rc < 0) { - /* - * Abort if failure wasn't that the dir already exists or the - * permission was denied (creation might succeed further down the - * path) - retry on unspecific FAILURE also - */ - err = sftp_get_error(sshc->sftp_session); - if((err != SSH_FX_FILE_ALREADY_EXISTS) && - (err != SSH_FX_FAILURE) && - (err != SSH_FX_PERMISSION_DENIED)) { - MOVE_TO_SFTP_CLOSE_STATE(); - } - rc = 0; /* clear rc and continue */ - } - state(conn, SSH_SFTP_CREATE_DIRS); - break; - - case SSH_SFTP_READDIR_INIT: - Curl_pgrsSetDownloadSize(data, -1); - if(data->set.opt_no_body) { - state(conn, SSH_STOP); - break; - } - - /* - * This is a directory that we are trying to get, so produce a directory - * listing - */ - sshc->sftp_dir = sftp_opendir(sshc->sftp_session, - protop->path); - if(!sshc->sftp_dir) { - failf(data, "Could not open directory for reading: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_SFTP_CLOSE_STATE(); - } - state(conn, SSH_SFTP_READDIR); - break; - - case SSH_SFTP_READDIR: - - if(sshc->readdir_attrs) - sftp_attributes_free(sshc->readdir_attrs); - - sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir); - if(sshc->readdir_attrs) { - sshc->readdir_filename = sshc->readdir_attrs->name; - sshc->readdir_longentry = sshc->readdir_attrs->longname; - sshc->readdir_len = strlen(sshc->readdir_filename); - - if(data->set.ftp_list_only) { - char *tmpLine; - - tmpLine = aprintf("%s\n", sshc->readdir_filename); - if(tmpLine == NULL) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - result = Curl_client_write(conn, CLIENTWRITE_BODY, - tmpLine, sshc->readdir_len + 1); - free(tmpLine); - - if(result) { - state(conn, SSH_STOP); - break; - } - /* since this counts what we send to the client, we include the - newline in this counter */ - data->req.bytecount += sshc->readdir_len + 1; - - /* output debug output if that is requested */ + struct ssh_conn *sshc = &conn->proto.sshc; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + int rc = SSH_NO_ERROR, err; + char *new_readdir_line; + int seekerr = CURL_SEEKFUNC_OK; + const char *err_msg; + *block = 0; /* we're not blocking by default */ + + do { + + switch(sshc->state) { + case SSH_INIT: + sshc->secondCreateDirs = 0; + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_OK; + +#if 0 + ssh_set_log_level(SSH_LOG_PROTOCOL); +#endif + + /* Set libssh to non-blocking, since everything internally is + non-blocking */ + ssh_set_blocking(sshc->ssh_session, 0); + + state(conn, SSH_S_STARTUP); + /* FALLTHROUGH */ + + case SSH_S_STARTUP: + rc = ssh_connect(sshc->ssh_session); + if(rc == SSH_AGAIN) + break; + + if(rc != SSH_OK) { + failf(data, "Failure establishing ssh session"); + MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT); + } + + state(conn, SSH_HOSTKEY); + + /* FALLTHROUGH */ + case SSH_HOSTKEY: + + rc = myssh_is_known(conn); + if(rc != SSH_OK) { + MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION); + } + + state(conn, SSH_AUTHLIST); + /* FALLTHROUGH */ + case SSH_AUTHLIST:{ + sshc->authed = FALSE; + + rc = ssh_userauth_none(sshc->ssh_session, NULL); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Authenticated with none\n"); + state(conn, SSH_AUTH_DONE); + break; + } + else if(rc == SSH_AUTH_ERROR) { + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + + sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); + if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { + state(conn, SSH_AUTH_PKEY_INIT); + infof(data, "Authentication using SSH public key file\n"); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { + state(conn, SSH_AUTH_GSSAPI); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { + state(conn, SSH_AUTH_KEY_INIT); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { + state(conn, SSH_AUTH_PASS_INIT); + } + else { /* unsupported authentication method */ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + + break; + } + case SSH_AUTH_PKEY_INIT: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { + MOVE_TO_SECONDARY_AUTH; + } + + /* Two choices, (1) private key was given on CMD, + * (2) use the "default" keys. */ + if(data->set.str[STRING_SSH_PRIVATE_KEY]) { + if(sshc->pubkey && !data->set.ssl.key_passwd) { + rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL, + sshc->pubkey); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc != SSH_OK) { + MOVE_TO_SECONDARY_AUTH; + } + } + + rc = ssh_pki_import_privkey_file(data-> + set.str[STRING_SSH_PRIVATE_KEY], + data->set.ssl.key_passwd, NULL, + NULL, &sshc->privkey); + if(rc != SSH_OK) { + failf(data, "Could not load private key file %s", + data->set.str[STRING_SSH_PRIVATE_KEY]); + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; + } + + state(conn, SSH_AUTH_PKEY); + break; + + } + else { + rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL, + data->set.ssl.key_passwd); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + if(rc == SSH_AUTH_SUCCESS) { + rc = SSH_OK; + sshc->authed = TRUE; + infof(data, "Completed public key authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + + MOVE_TO_SECONDARY_AUTH; + } + break; + case SSH_AUTH_PKEY: + rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed public key authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + else { + infof(data, "Failed public key authentication (rc: %d)\n", rc); + MOVE_TO_SECONDARY_AUTH; + } + break; + + case SSH_AUTH_GSSAPI: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { + MOVE_TO_TERTIARY_AUTH; + } + + rc = ssh_userauth_gssapi(sshc->ssh_session); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + rc = SSH_OK; + sshc->authed = TRUE; + infof(data, "Completed gssapi authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + + MOVE_TO_TERTIARY_AUTH; + break; + + case SSH_AUTH_KEY_INIT: + if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) { + state(conn, SSH_AUTH_KEY); + } + else { + MOVE_TO_LAST_AUTH; + } + break; + + case SSH_AUTH_KEY: + + /* Authentication failed. Continue with keyboard-interactive now. */ + rc = myssh_auth_interactive(conn); + if(rc == SSH_AGAIN) { + break; + } + if(rc == SSH_OK) { + sshc->authed = TRUE; + infof(data, "completed keyboard interactive authentication\n"); + } + state(conn, SSH_AUTH_DONE); + break; + + case SSH_AUTH_PASS_INIT: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { + /* Host key authentication is intentionally not implemented */ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + state(conn, SSH_AUTH_PASS); + /* FALLTHROUGH */ + + case SSH_AUTH_PASS: + rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed password authentication\n"); + state(conn, SSH_AUTH_DONE); + } + else { + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + break; + + case SSH_AUTH_DONE: + if(!sshc->authed) { + failf(data, "Authentication failure"); + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; + } + + /* + * At this point we have an authenticated ssh session. + */ + infof(data, "Authentication complete\n"); + + Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ + + conn->sockfd = sock; + conn->writesockfd = CURL_SOCKET_BAD; + + if(conn->handler->protocol == CURLPROTO_SFTP) { + state(conn, SSH_SFTP_INIT); + break; + } + infof(data, "SSH CONNECT phase done\n"); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_INIT: + ssh_set_blocking(sshc->ssh_session, 1); + + sshc->sftp_session = sftp_new(sshc->ssh_session); + if(!sshc->sftp_session) { + failf(data, "Failure initializing sftp session: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + break; + } + + rc = sftp_init(sshc->sftp_session); + if(rc != SSH_OK) { + rc = sftp_get_error(sshc->sftp_session); + failf(data, "Failure initializing sftp session: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc)); + break; + } + state(conn, SSH_SFTP_REALPATH); + /* FALLTHROUGH */ + case SSH_SFTP_REALPATH: + /* + * Get the "home" directory + */ + sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); + if(sshc->homedir == NULL) { + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + } + conn->data->state.most_recent_ftp_entrypath = sshc->homedir; + + /* This is the last step in the SFTP connect phase. Do note that while + we get the homedir here, we get the "workingpath" in the DO action + since the homedir will remain the same between request but the + working path will not. */ + DEBUGF(infof(data, "SSH CONNECT phase done\n")); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_QUOTE_INIT: + + result = Curl_getworkingpath(conn, sshc->homedir, &protop->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + if(data->set.quote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.quote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_SFTP_GETINFO); + } + break; + + case SSH_SFTP_POSTQUOTE_INIT: + if(data->set.postquote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.postquote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_QUOTE: + /* Send any quote commands */ + sftp_quote(conn); + break; + + case SSH_SFTP_NEXT_QUOTE: + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + sshc->quote_item = sshc->quote_item->next; + + if(sshc->quote_item) { + state(conn, SSH_SFTP_QUOTE); + } + else { + if(sshc->nextstate != SSH_NO_STATE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_NO_STATE; + } + else { + state(conn, SSH_SFTP_GETINFO); + } + } + break; + + case SSH_SFTP_QUOTE_STAT: + sftp_quote_stat(conn); + break; + + case SSH_SFTP_QUOTE_SETSTAT: + rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2, + sshc->quote_attrs); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to set SFTP stats failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + /* sshc->actualcode = sftp_error_to_CURLE(err); + * we do not send the actual error; we return + * the error the libssh2 backend is returning */ + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_SYMLINK: + rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2, + sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "symlink command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_MKDIR: + rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1, + (mode_t)data->set.new_directory_perms); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "mkdir command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RENAME: + rc = sftp_rename(sshc->sftp_session, sshc->quote_path1, + sshc->quote_path2); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "rename command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RMDIR: + rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "rmdir command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_UNLINK: + rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "rm command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_STATVFS: + { + sftp_statvfs_t statvfs; + + statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1); + if(!statvfs && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "statvfs command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + else if(statvfs) { + char *tmp = aprintf("statvfs:\n" + "f_bsize: %llu\n" "f_frsize: %llu\n" + "f_blocks: %llu\n" "f_bfree: %llu\n" + "f_bavail: %llu\n" "f_files: %llu\n" + "f_ffree: %llu\n" "f_favail: %llu\n" + "f_fsid: %llu\n" "f_flag: %llu\n" + "f_namemax: %llu\n", + statvfs->f_bsize, statvfs->f_frsize, + statvfs->f_blocks, statvfs->f_bfree, + statvfs->f_bavail, statvfs->f_files, + statvfs->f_ffree, statvfs->f_favail, + statvfs->f_fsid, statvfs->f_flag, + statvfs->f_namemax); + sftp_statvfs_free(statvfs); + + if(!tmp) { + result = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + break; + } + + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + } + + case SSH_SFTP_GETINFO: + if(data->set.get_filetime) { + state(conn, SSH_SFTP_FILETIME); + } + else { + state(conn, SSH_SFTP_TRANS_INIT); + } + break; + + case SSH_SFTP_FILETIME: + { + sftp_attributes attrs; + + attrs = sftp_stat(sshc->sftp_session, protop->path); + if(attrs != 0) { + data->info.filetime = attrs->mtime; + sftp_attributes_free(attrs); + } + + state(conn, SSH_SFTP_TRANS_INIT); + break; + } + + case SSH_SFTP_TRANS_INIT: + if(data->set.upload) + state(conn, SSH_SFTP_UPLOAD_INIT); + else { + if(protop->path[strlen(protop->path)-1] == '/') + state(conn, SSH_SFTP_READDIR_INIT); + else + state(conn, SSH_SFTP_DOWNLOAD_INIT); + } + break; + + case SSH_SFTP_UPLOAD_INIT: + { + int flags; + + if(data->state.resume_from != 0) { + sftp_attributes attrs; + + if(data->state.resume_from < 0) { + attrs = sftp_stat(sshc->sftp_session, protop->path); + if(attrs != 0) { + curl_off_t size = attrs->size; + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + } + data->state.resume_from = attrs->size; + + sftp_attributes_free(attrs); + } + else { + data->state.resume_from = 0; + } + } + } + + if(data->set.ftp_append) + /* Try to open for append, but create if nonexisting */ + flags = O_WRONLY|O_CREAT|O_APPEND; + else if(data->state.resume_from > 0) + /* If we have restart position then open for append */ + flags = O_WRONLY|O_APPEND; + else + /* Clear file before writing (normal behaviour) */ + flags = O_WRONLY|O_CREAT|O_TRUNC; + + if(sshc->sftp_file) + sftp_close(sshc->sftp_file); + sshc->sftp_file = + sftp_open(sshc->sftp_session, protop->path, + flags, (mode_t)data->set.new_file_perms); + if(!sshc->sftp_file) { + err = sftp_get_error(sshc->sftp_session); + + if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE || + err == SSH_FX_NO_SUCH_PATH)) && + (data->set.ftp_create_missing_dirs && + (strlen(protop->path) > 1))) { + /* try to create the path remotely */ + rc = 0; + sshc->secondCreateDirs = 1; + state(conn, SSH_SFTP_CREATE_DIRS_INIT); + break; + } + else { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + + /* If we have a restart point then we need to seek to the correct + position. */ + if(data->state.resume_from > 0) { + /* Let's read off the proper amount of bytes from the input. */ + if(conn->seek_func) { + Curl_set_in_callback(data, true); + seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, + SEEK_SET); + Curl_set_in_callback(data, false); + } + + if(seekerr != CURL_SEEKFUNC_OK) { + curl_off_t passed = 0; + + if(seekerr != CURL_SEEKFUNC_CANTSEEK) { + failf(data, "Could not seek stream"); + return CURLE_FTP_COULDNT_USE_REST; + } + /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? + (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + data->state.fread_func(data->state.buffer, 1, + readthisamountnow, data->state.in); + + passed += actuallyread; + if((actuallyread == 0) || (actuallyread > readthisamountnow)) { + /* this checks for greater-than only to make sure that the + CURL_READFUNC_ABORT return code still aborts */ + failf(data, "Failed to read data"); + MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST); + } + } while(passed < data->state.resume_from); + } + + /* now, decrease the size of the read */ + if(data->state.infilesize > 0) { + data->state.infilesize -= data->state.resume_from; + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + + rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + if(data->state.infilesize > 0) { + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + /* upload data */ + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh sftp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + /* since we don't really wait for anything at this point, we want the + state machine to move on as soon as possible so we set a very short + timeout here */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); + + state(conn, SSH_STOP); + break; + } + + case SSH_SFTP_CREATE_DIRS_INIT: + if(strlen(protop->path) > 1) { + sshc->slash_pos = protop->path + 1; /* ignore the leading '/' */ + state(conn, SSH_SFTP_CREATE_DIRS); + } + else { + state(conn, SSH_SFTP_UPLOAD_INIT); + } + break; + + case SSH_SFTP_CREATE_DIRS: + sshc->slash_pos = strchr(sshc->slash_pos, '/'); + if(sshc->slash_pos) { + *sshc->slash_pos = 0; + + infof(data, "Creating directory '%s'\n", protop->path); + state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); + break; + } + state(conn, SSH_SFTP_UPLOAD_INIT); + break; + + case SSH_SFTP_CREATE_DIRS_MKDIR: + /* 'mode' - parameter is preliminary - default to 0644 */ + rc = sftp_mkdir(sshc->sftp_session, protop->path, + (mode_t)data->set.new_directory_perms); + *sshc->slash_pos = '/'; + ++sshc->slash_pos; + if(rc < 0) { + /* + * Abort if failure wasn't that the dir already exists or the + * permission was denied (creation might succeed further down the + * path) - retry on unspecific FAILURE also + */ + err = sftp_get_error(sshc->sftp_session); + if((err != SSH_FX_FILE_ALREADY_EXISTS) && + (err != SSH_FX_FAILURE) && + (err != SSH_FX_PERMISSION_DENIED)) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + rc = 0; /* clear rc and continue */ + } + state(conn, SSH_SFTP_CREATE_DIRS); + break; + + case SSH_SFTP_READDIR_INIT: + Curl_pgrsSetDownloadSize(data, -1); + if(data->set.opt_no_body) { + state(conn, SSH_STOP); + break; + } + + /* + * This is a directory that we are trying to get, so produce a directory + * listing + */ + sshc->sftp_dir = sftp_opendir(sshc->sftp_session, + protop->path); + if(!sshc->sftp_dir) { + failf(data, "Could not open directory for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + } + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR: + + if(sshc->readdir_attrs) + sftp_attributes_free(sshc->readdir_attrs); + + sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir); + if(sshc->readdir_attrs) { + sshc->readdir_filename = sshc->readdir_attrs->name; + sshc->readdir_longentry = sshc->readdir_attrs->longname; + sshc->readdir_len = strlen(sshc->readdir_filename); + + if(data->set.ftp_list_only) { + char *tmpLine; + + tmpLine = aprintf("%s\n", sshc->readdir_filename); + if(tmpLine == NULL) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + result = Curl_client_write(conn, CLIENTWRITE_BODY, + tmpLine, sshc->readdir_len + 1); + free(tmpLine); + + if(result) { + state(conn, SSH_STOP); + break; + } + /* since this counts what we send to the client, we include the + newline in this counter */ + data->req.bytecount += sshc->readdir_len + 1; + + /* output debug output if that is requested */ Curl_debug(data, CURLINFO_DATA_OUT, (char *)sshc->readdir_filename, sshc->readdir_len); - } - else { - sshc->readdir_currLen = strlen(sshc->readdir_longentry); - sshc->readdir_totalLen = 80 + sshc->readdir_currLen; - sshc->readdir_line = calloc(sshc->readdir_totalLen, 1); - if(!sshc->readdir_line) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - - memcpy(sshc->readdir_line, sshc->readdir_longentry, - sshc->readdir_currLen); - if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && - ((sshc->readdir_attrs->permissions & S_IFMT) == - S_IFLNK)) { - sshc->readdir_linkPath = malloc(PATH_MAX + 1); - if(sshc->readdir_linkPath == NULL) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - - msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path, - sshc->readdir_filename); - - state(conn, SSH_SFTP_READDIR_LINK); - break; - } - state(conn, SSH_SFTP_READDIR_BOTTOM); - break; - } - } + } + else { + sshc->readdir_currLen = strlen(sshc->readdir_longentry); + sshc->readdir_totalLen = 80 + sshc->readdir_currLen; + sshc->readdir_line = calloc(sshc->readdir_totalLen, 1); + if(!sshc->readdir_line) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + memcpy(sshc->readdir_line, sshc->readdir_longentry, + sshc->readdir_currLen); + if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && + ((sshc->readdir_attrs->permissions & S_IFMT) == + S_IFLNK)) { + sshc->readdir_linkPath = malloc(PATH_MAX + 1); + if(sshc->readdir_linkPath == NULL) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path, + sshc->readdir_filename); + + state(conn, SSH_SFTP_READDIR_LINK); + break; + } + state(conn, SSH_SFTP_READDIR_BOTTOM); + break; + } + } else if(sftp_dir_eof(sshc->sftp_dir)) { - state(conn, SSH_SFTP_READDIR_DONE); - break; - } - else { - failf(data, "Could not open remote file for reading: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_SFTP_CLOSE_STATE(); - break; - } - break; - - case SSH_SFTP_READDIR_LINK: - if(sshc->readdir_link_attrs) - sftp_attributes_free(sshc->readdir_link_attrs); - - sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session, - sshc->readdir_linkPath); - if(sshc->readdir_link_attrs == 0) { - failf(data, "Could not read symlink for reading: %s", - ssh_get_error(sshc->ssh_session)); - MOVE_TO_SFTP_CLOSE_STATE(); - } - - if(sshc->readdir_link_attrs->name == NULL) { - sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, - sshc->readdir_linkPath); - if(sshc->readdir_filename == NULL) - sshc->readdir_len = 0; - else - sshc->readdir_len = strlen(sshc->readdir_tmp); - sshc->readdir_longentry = NULL; - sshc->readdir_filename = sshc->readdir_tmp; - } - else { - sshc->readdir_len = strlen(sshc->readdir_link_attrs->name); - sshc->readdir_filename = sshc->readdir_link_attrs->name; - sshc->readdir_longentry = sshc->readdir_link_attrs->longname; - } - - Curl_safefree(sshc->readdir_linkPath); - - /* get room for the filename and extra output */ - sshc->readdir_totalLen += 4 + sshc->readdir_len; - new_readdir_line = Curl_saferealloc(sshc->readdir_line, - sshc->readdir_totalLen); - if(!new_readdir_line) { - sshc->readdir_line = NULL; - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - sshc->readdir_line = new_readdir_line; - - sshc->readdir_currLen += msnprintf(sshc->readdir_line + - sshc->readdir_currLen, - sshc->readdir_totalLen - - sshc->readdir_currLen, - " -> %s", - sshc->readdir_filename); - - sftp_attributes_free(sshc->readdir_link_attrs); - sshc->readdir_link_attrs = NULL; - sshc->readdir_filename = NULL; - sshc->readdir_longentry = NULL; - - state(conn, SSH_SFTP_READDIR_BOTTOM); - /* FALLTHROUGH */ - case SSH_SFTP_READDIR_BOTTOM: - sshc->readdir_currLen += msnprintf(sshc->readdir_line + - sshc->readdir_currLen, - sshc->readdir_totalLen - - sshc->readdir_currLen, "\n"); - result = Curl_client_write(conn, CLIENTWRITE_BODY, - sshc->readdir_line, - sshc->readdir_currLen); - - if(!result) { - /* output debug output if that is requested */ + state(conn, SSH_SFTP_READDIR_DONE); + break; + } + else { + failf(data, "Could not open remote file for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + break; + } + break; + + case SSH_SFTP_READDIR_LINK: + if(sshc->readdir_link_attrs) + sftp_attributes_free(sshc->readdir_link_attrs); + + sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session, + sshc->readdir_linkPath); + if(sshc->readdir_link_attrs == 0) { + failf(data, "Could not read symlink for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + } + + if(sshc->readdir_link_attrs->name == NULL) { + sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, + sshc->readdir_linkPath); + if(sshc->readdir_filename == NULL) + sshc->readdir_len = 0; + else + sshc->readdir_len = strlen(sshc->readdir_tmp); + sshc->readdir_longentry = NULL; + sshc->readdir_filename = sshc->readdir_tmp; + } + else { + sshc->readdir_len = strlen(sshc->readdir_link_attrs->name); + sshc->readdir_filename = sshc->readdir_link_attrs->name; + sshc->readdir_longentry = sshc->readdir_link_attrs->longname; + } + + Curl_safefree(sshc->readdir_linkPath); + + /* get room for the filename and extra output */ + sshc->readdir_totalLen += 4 + sshc->readdir_len; + new_readdir_line = Curl_saferealloc(sshc->readdir_line, + sshc->readdir_totalLen); + if(!new_readdir_line) { + sshc->readdir_line = NULL; + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + sshc->readdir_line = new_readdir_line; + + sshc->readdir_currLen += msnprintf(sshc->readdir_line + + sshc->readdir_currLen, + sshc->readdir_totalLen - + sshc->readdir_currLen, + " -> %s", + sshc->readdir_filename); + + sftp_attributes_free(sshc->readdir_link_attrs); + sshc->readdir_link_attrs = NULL; + sshc->readdir_filename = NULL; + sshc->readdir_longentry = NULL; + + state(conn, SSH_SFTP_READDIR_BOTTOM); + /* FALLTHROUGH */ + case SSH_SFTP_READDIR_BOTTOM: + sshc->readdir_currLen += msnprintf(sshc->readdir_line + + sshc->readdir_currLen, + sshc->readdir_totalLen - + sshc->readdir_currLen, "\n"); + result = Curl_client_write(conn, CLIENTWRITE_BODY, + sshc->readdir_line, + sshc->readdir_currLen); + + if(!result) { + /* output debug output if that is requested */ Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line, sshc->readdir_currLen); - data->req.bytecount += sshc->readdir_currLen; - } - Curl_safefree(sshc->readdir_line); - ssh_string_free_char(sshc->readdir_tmp); - sshc->readdir_tmp = NULL; - - if(result) { - state(conn, SSH_STOP); - } - else - state(conn, SSH_SFTP_READDIR); - break; - - case SSH_SFTP_READDIR_DONE: - sftp_closedir(sshc->sftp_dir); - sshc->sftp_dir = NULL; - - /* no data to transfer */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_DOWNLOAD_INIT: - /* - * Work on getting the specified file - */ - if(sshc->sftp_file) - sftp_close(sshc->sftp_file); - - sshc->sftp_file = sftp_open(sshc->sftp_session, protop->path, - O_RDONLY, (mode_t)data->set.new_file_perms); - if(!sshc->sftp_file) { - failf(data, "Could not open remote file for reading: %s", - ssh_get_error(sshc->ssh_session)); - - MOVE_TO_SFTP_CLOSE_STATE(); - } - - state(conn, SSH_SFTP_DOWNLOAD_STAT); - break; - - case SSH_SFTP_DOWNLOAD_STAT: - { - sftp_attributes attrs; - curl_off_t size; - - attrs = sftp_fstat(sshc->sftp_file); - if(!attrs || - !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) || - (attrs->size == 0)) { - /* - * sftp_fstat didn't return an error, so maybe the server - * just doesn't support stat() - * OR the server doesn't return a file size with a stat() - * OR file size is 0 - */ - data->req.size = -1; - data->req.maxdownload = -1; - Curl_pgrsSetDownloadSize(data, -1); - size = 0; - } - else { - size = attrs->size; - - sftp_attributes_free(attrs); - - if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - if(conn->data->state.use_range) { - curl_off_t from, to; - char *ptr; - char *ptr2; - CURLofft to_t; - CURLofft from_t; - - from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from); - if(from_t == CURL_OFFT_FLOW) { - return CURLE_RANGE_ERROR; - } - while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) - ptr++; - to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); - if(to_t == CURL_OFFT_FLOW) { - return CURLE_RANGE_ERROR; - } - if((to_t == CURL_OFFT_INVAL) /* no "to" value given */ - || (to >= size)) { - to = size - 1; - } - if(from_t) { - /* from is relative to end of file */ - from = size - to; - to = size - 1; - } - if(from > size) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", from, size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - if(from > to) { - from = to; - size = 0; - } - else { - size = to - from + 1; - } - - rc = sftp_seek64(sshc->sftp_file, from); - if(rc != 0) { - MOVE_TO_SFTP_CLOSE_STATE(); - } - } - data->req.size = size; - data->req.maxdownload = size; - Curl_pgrsSetDownloadSize(data, size); - } - - /* We can resume if we can seek to the resume position */ - if(data->state.resume_from) { - if(data->state.resume_from < 0) { - /* We're supposed to download the last abs(from) bytes */ - if((curl_off_t)size < -data->state.resume_from) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - /* download from where? */ - data->state.resume_from += size; - } - else { - if((curl_off_t)size < data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - } - /* Now store the number of bytes we are expected to download */ - data->req.size = size - data->state.resume_from; - data->req.maxdownload = size - data->state.resume_from; - Curl_pgrsSetDownloadSize(data, - size - data->state.resume_from); - - rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); - if(rc != 0) { - MOVE_TO_SFTP_CLOSE_STATE(); - } - } - } - - /* Setup the actual download */ - if(data->req.size == 0) { - /* no data to transfer */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); - infof(data, "File already completely downloaded\n"); - state(conn, SSH_STOP); - break; - } - Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->writesockfd = conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh recv function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_IN; - - if(result) { - /* this should never occur; the close state should be entered - at the time the error occurs */ - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = result; - } - else { - sshc->sftp_recv_state = 0; - state(conn, SSH_STOP); - } - break; - - case SSH_SFTP_CLOSE: - if(sshc->sftp_file) { - sftp_close(sshc->sftp_file); - sshc->sftp_file = NULL; - } - Curl_safefree(protop->path); - - DEBUGF(infof(data, "SFTP DONE done\n")); - - /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT - After nextstate is executed, the control should come back to - SSH_SFTP_CLOSE to pass the correct result back */ - if(sshc->nextstate != SSH_NO_STATE && - sshc->nextstate != SSH_SFTP_CLOSE) { - state(conn, sshc->nextstate); - sshc->nextstate = SSH_SFTP_CLOSE; - } - else { - state(conn, SSH_STOP); - result = sshc->actualcode; - } - break; - - case SSH_SFTP_SHUTDOWN: - /* during times we get here due to a broken transfer and then the - sftp_handle might not have been taken down so make sure that is done - before we proceed */ - - if(sshc->sftp_file) { - sftp_close(sshc->sftp_file); - sshc->sftp_file = NULL; - } - - if(sshc->sftp_session) { - sftp_free(sshc->sftp_session); - sshc->sftp_session = NULL; - } - - SSH_STRING_FREE_CHAR(sshc->homedir); - conn->data->state.most_recent_ftp_entrypath = NULL; - - state(conn, SSH_SESSION_DISCONNECT); - break; - - - case SSH_SCP_TRANS_INIT: - result = Curl_getworkingpath(conn, sshc->homedir, &protop->path); - if(result) { - sshc->actualcode = result; - state(conn, SSH_STOP); - break; - } - - /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */ - ssh_set_blocking(sshc->ssh_session, 1); - - if(data->set.upload) { - if(data->state.infilesize < 0) { - failf(data, "SCP requires a known file size for upload"); - sshc->actualcode = CURLE_UPLOAD_FAILED; - MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); - } - - sshc->scp_session = - ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, protop->path); - state(conn, SSH_SCP_UPLOAD_INIT); - } - else { - sshc->scp_session = - ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, protop->path); - state(conn, SSH_SCP_DOWNLOAD_INIT); - } - - if(!sshc->scp_session) { - err_msg = ssh_get_error(sshc->ssh_session); - failf(conn->data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); - } - - break; - - case SSH_SCP_UPLOAD_INIT: - - rc = ssh_scp_init(sshc->scp_session); - if(rc != SSH_OK) { - err_msg = ssh_get_error(sshc->ssh_session); - failf(conn->data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); - } - - rc = ssh_scp_push_file(sshc->scp_session, protop->path, - data->state.infilesize, - (int)data->set.new_file_perms); - if(rc != SSH_OK) { - err_msg = ssh_get_error(sshc->ssh_session); - failf(conn->data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); - } - - /* upload data */ - Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->sockfd = conn->writesockfd; - - /* store this original bitmask setup to use later on if we can't - figure out a "real" bitmask */ - sshc->orig_waitfor = data->req.keepon; - - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh scp send function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_OUT; - - state(conn, SSH_STOP); - - break; - - case SSH_SCP_DOWNLOAD_INIT: - - rc = ssh_scp_init(sshc->scp_session); - if(rc != SSH_OK) { - err_msg = ssh_get_error(sshc->ssh_session); - failf(conn->data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); - } - state(conn, SSH_SCP_DOWNLOAD); - /* FALLTHROUGH */ - - case SSH_SCP_DOWNLOAD:{ - curl_off_t bytecount; - - rc = ssh_scp_pull_request(sshc->scp_session); - if(rc != SSH_SCP_REQUEST_NEWFILE) { - err_msg = ssh_get_error(sshc->ssh_session); - failf(conn->data, "%s", err_msg); - MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND); - break; - } - - /* download data */ - bytecount = ssh_scp_request_get_size(sshc->scp_session); - data->req.maxdownload = (curl_off_t) bytecount; - Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->writesockfd = conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh recv function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_IN; - - state(conn, SSH_STOP); - break; - } - case SSH_SCP_DONE: - if(data->set.upload) - state(conn, SSH_SCP_SEND_EOF); - else - state(conn, SSH_SCP_CHANNEL_FREE); - break; - - case SSH_SCP_SEND_EOF: - if(sshc->scp_session) { - rc = ssh_scp_close(sshc->scp_session); - if(rc == SSH_AGAIN) { - /* Currently the ssh_scp_close handles waiting for EOF in - * blocking way. - */ - break; - } - if(rc != SSH_OK) { - infof(data, "Failed to close libssh scp channel: %s\n", - ssh_get_error(sshc->ssh_session)); - } - } - - state(conn, SSH_SCP_CHANNEL_FREE); - break; - - case SSH_SCP_CHANNEL_FREE: - if(sshc->scp_session) { - ssh_scp_free(sshc->scp_session); - sshc->scp_session = NULL; - } - DEBUGF(infof(data, "SCP DONE phase complete\n")); - - ssh_set_blocking(sshc->ssh_session, 0); - - state(conn, SSH_SESSION_DISCONNECT); - /* FALLTHROUGH */ - - case SSH_SESSION_DISCONNECT: - /* during weird times when we've been prematurely aborted, the channel - is still alive when we reach this state and we MUST kill the channel - properly first */ - if(sshc->scp_session) { - ssh_scp_free(sshc->scp_session); - sshc->scp_session = NULL; - } - - ssh_disconnect(sshc->ssh_session); - - SSH_STRING_FREE_CHAR(sshc->homedir); - conn->data->state.most_recent_ftp_entrypath = NULL; - - state(conn, SSH_SESSION_FREE); - /* FALLTHROUGH */ - case SSH_SESSION_FREE: - if(sshc->ssh_session) { - ssh_free(sshc->ssh_session); - sshc->ssh_session = NULL; - } - - /* worst-case scenario cleanup */ - - DEBUGASSERT(sshc->ssh_session == NULL); - DEBUGASSERT(sshc->scp_session == NULL); - - if(sshc->readdir_tmp) { - ssh_string_free_char(sshc->readdir_tmp); - sshc->readdir_tmp = NULL; - } - - if(sshc->quote_attrs) - sftp_attributes_free(sshc->quote_attrs); - - if(sshc->readdir_attrs) - sftp_attributes_free(sshc->readdir_attrs); - - if(sshc->readdir_link_attrs) - sftp_attributes_free(sshc->readdir_link_attrs); - - if(sshc->privkey) - ssh_key_free(sshc->privkey); - if(sshc->pubkey) - ssh_key_free(sshc->pubkey); - - Curl_safefree(sshc->rsa_pub); - Curl_safefree(sshc->rsa); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - Curl_safefree(sshc->readdir_line); - Curl_safefree(sshc->readdir_linkPath); - SSH_STRING_FREE_CHAR(sshc->homedir); - - /* the code we are about to return */ - result = sshc->actualcode; - - memset(sshc, 0, sizeof(struct ssh_conn)); - - connclose(conn, "SSH session free"); - sshc->state = SSH_SESSION_FREE; /* current */ - sshc->nextstate = SSH_NO_STATE; - state(conn, SSH_STOP); - break; - - case SSH_QUIT: - /* fallthrough, just stop! */ - default: - /* internal error */ - sshc->nextstate = SSH_NO_STATE; - state(conn, SSH_STOP); - break; - - } - } while(!rc && (sshc->state != SSH_STOP)); - - - if(rc == SSH_AGAIN) { - /* we would block, we need to wait for the socket to be ready (in the - right direction too)! */ - *block = TRUE; - } - - return result; -} - - -/* called by the multi interface to figure out what socket(s) to wait for and - for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static int myssh_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock) -{ - int bitmap = GETSOCK_BLANK; - sock[0] = conn->sock[FIRSTSOCKET]; - - if(conn->waitfor & KEEP_RECV) - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - - if(conn->waitfor & KEEP_SEND) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - return bitmap; -} - -/* Generic function called by the multi interface to figure out what socket(s) - to wait for and for what actions during the DOING and PROTOCONNECT states*/ -static int myssh_getsock(struct connectdata *conn, - curl_socket_t *sock) -{ - /* if we know the direction we can use the generic *_getsock() function even - for the protocol_connect and doing states */ - return myssh_perform_getsock(conn, sock); -} - -static void myssh_block2waitfor(struct connectdata *conn, bool block) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - - /* If it didn't block, or nothing was returned by ssh_get_poll_flags - * have the original set */ - conn->waitfor = sshc->orig_waitfor; - - if(block) { - int dir = ssh_get_poll_flags(sshc->ssh_session); - if(dir & SSH_READ_PENDING) { - /* translate the libssh define bits into our own bit defines */ - conn->waitfor = KEEP_RECV; - } - else if(dir & SSH_WRITE_PENDING) { - conn->waitfor = KEEP_SEND; - } - } -} - -/* called repeatedly until done from multi.c */ -static CURLcode myssh_multi_statemach(struct connectdata *conn, - bool *done) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - bool block; /* we store the status and use that to provide a ssh_getsock() - implementation */ - CURLcode result = myssh_statemach_act(conn, &block); - - *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; - myssh_block2waitfor(conn, block); - - return result; -} - -static CURLcode myssh_block_statemach(struct connectdata *conn, - bool disconnect) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - - while((sshc->state != SSH_STOP) && !result) { - bool block; - timediff_t left = 1000; - struct curltime now = Curl_now(); - - result = myssh_statemach_act(conn, &block); - if(result) - break; - - if(!disconnect) { - if(Curl_pgrsUpdate(conn)) - return CURLE_ABORTED_BY_CALLBACK; - - result = Curl_speedcheck(data, now); - if(result) - break; - - left = Curl_timeleft(data, NULL, FALSE); - if(left < 0) { - failf(data, "Operation timed out"); - return CURLE_OPERATION_TIMEDOUT; - } - } - + data->req.bytecount += sshc->readdir_currLen; + } + Curl_safefree(sshc->readdir_line); + ssh_string_free_char(sshc->readdir_tmp); + sshc->readdir_tmp = NULL; + + if(result) { + state(conn, SSH_STOP); + } + else + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR_DONE: + sftp_closedir(sshc->sftp_dir); + sshc->sftp_dir = NULL; + + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_DOWNLOAD_INIT: + /* + * Work on getting the specified file + */ + if(sshc->sftp_file) + sftp_close(sshc->sftp_file); + + sshc->sftp_file = sftp_open(sshc->sftp_session, protop->path, + O_RDONLY, (mode_t)data->set.new_file_perms); + if(!sshc->sftp_file) { + failf(data, "Could not open remote file for reading: %s", + ssh_get_error(sshc->ssh_session)); + + MOVE_TO_SFTP_CLOSE_STATE(); + } + + state(conn, SSH_SFTP_DOWNLOAD_STAT); + break; + + case SSH_SFTP_DOWNLOAD_STAT: + { + sftp_attributes attrs; + curl_off_t size; + + attrs = sftp_fstat(sshc->sftp_file); + if(!attrs || + !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) || + (attrs->size == 0)) { + /* + * sftp_fstat didn't return an error, so maybe the server + * just doesn't support stat() + * OR the server doesn't return a file size with a stat() + * OR file size is 0 + */ + data->req.size = -1; + data->req.maxdownload = -1; + Curl_pgrsSetDownloadSize(data, -1); + size = 0; + } + else { + size = attrs->size; + + sftp_attributes_free(attrs); + + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(conn->data->state.use_range) { + curl_off_t from, to; + char *ptr; + char *ptr2; + CURLofft to_t; + CURLofft from_t; + + from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from); + if(from_t == CURL_OFFT_FLOW) { + return CURLE_RANGE_ERROR; + } + while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + ptr++; + to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); + if(to_t == CURL_OFFT_FLOW) { + return CURLE_RANGE_ERROR; + } + if((to_t == CURL_OFFT_INVAL) /* no "to" value given */ + || (to >= size)) { + to = size - 1; + } + if(from_t) { + /* from is relative to end of file */ + from = size - to; + to = size - 1; + } + if(from > size) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(from > to) { + from = to; + size = 0; + } + else { + size = to - from + 1; + } + + rc = sftp_seek64(sshc->sftp_file, from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + data->req.size = size; + data->req.maxdownload = size; + Curl_pgrsSetDownloadSize(data, size); + } + + /* We can resume if we can seek to the resume position */ + if(data->state.resume_from) { + if(data->state.resume_from < 0) { + /* We're supposed to download the last abs(from) bytes */ + if((curl_off_t)size < -data->state.resume_from) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* download from where? */ + data->state.resume_from += size; + } + else { + if((curl_off_t)size < data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + } + /* Now store the number of bytes we are expected to download */ + data->req.size = size - data->state.resume_from; + data->req.maxdownload = size - data->state.resume_from; + Curl_pgrsSetDownloadSize(data, + size - data->state.resume_from); + + rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + } + + /* Setup the actual download */ + if(data->req.size == 0) { + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + infof(data, "File already completely downloaded\n"); + state(conn, SSH_STOP); + break; + } + Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + if(result) { + /* this should never occur; the close state should be entered + at the time the error occurs */ + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result; + } + else { + sshc->sftp_recv_state = 0; + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_CLOSE: + if(sshc->sftp_file) { + sftp_close(sshc->sftp_file); + sshc->sftp_file = NULL; + } + Curl_safefree(protop->path); + + DEBUGF(infof(data, "SFTP DONE done\n")); + + /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT + After nextstate is executed, the control should come back to + SSH_SFTP_CLOSE to pass the correct result back */ + if(sshc->nextstate != SSH_NO_STATE && + sshc->nextstate != SSH_SFTP_CLOSE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_SFTP_CLOSE; + } + else { + state(conn, SSH_STOP); + result = sshc->actualcode; + } + break; + + case SSH_SFTP_SHUTDOWN: + /* during times we get here due to a broken transfer and then the + sftp_handle might not have been taken down so make sure that is done + before we proceed */ + + if(sshc->sftp_file) { + sftp_close(sshc->sftp_file); + sshc->sftp_file = NULL; + } + + if(sshc->sftp_session) { + sftp_free(sshc->sftp_session); + sshc->sftp_session = NULL; + } + + SSH_STRING_FREE_CHAR(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_DISCONNECT); + break; + + + case SSH_SCP_TRANS_INIT: + result = Curl_getworkingpath(conn, sshc->homedir, &protop->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */ + ssh_set_blocking(sshc->ssh_session, 1); + + if(data->set.upload) { + if(data->state.infilesize < 0) { + failf(data, "SCP requires a known file size for upload"); + sshc->actualcode = CURLE_UPLOAD_FAILED; + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + sshc->scp_session = + ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, protop->path); + state(conn, SSH_SCP_UPLOAD_INIT); + } + else { + sshc->scp_session = + ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, protop->path); + state(conn, SSH_SCP_DOWNLOAD_INIT); + } + + if(!sshc->scp_session) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + break; + + case SSH_SCP_UPLOAD_INIT: + + rc = ssh_scp_init(sshc->scp_session); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + rc = ssh_scp_push_file(sshc->scp_session, protop->path, + data->state.infilesize, + (int)data->set.new_file_perms); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + /* upload data */ + Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh scp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + state(conn, SSH_STOP); + + break; + + case SSH_SCP_DOWNLOAD_INIT: + + rc = ssh_scp_init(sshc->scp_session); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + } + state(conn, SSH_SCP_DOWNLOAD); + /* FALLTHROUGH */ + + case SSH_SCP_DOWNLOAD:{ + curl_off_t bytecount; + + rc = ssh_scp_pull_request(sshc->scp_session); + if(rc != SSH_SCP_REQUEST_NEWFILE) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND); + break; + } + + /* download data */ + bytecount = ssh_scp_request_get_size(sshc->scp_session); + data->req.maxdownload = (curl_off_t) bytecount; + Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + state(conn, SSH_STOP); + break; + } + case SSH_SCP_DONE: + if(data->set.upload) + state(conn, SSH_SCP_SEND_EOF); + else + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_SEND_EOF: + if(sshc->scp_session) { + rc = ssh_scp_close(sshc->scp_session); + if(rc == SSH_AGAIN) { + /* Currently the ssh_scp_close handles waiting for EOF in + * blocking way. + */ + break; + } + if(rc != SSH_OK) { + infof(data, "Failed to close libssh scp channel: %s\n", + ssh_get_error(sshc->ssh_session)); + } + } + + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_CHANNEL_FREE: + if(sshc->scp_session) { + ssh_scp_free(sshc->scp_session); + sshc->scp_session = NULL; + } + DEBUGF(infof(data, "SCP DONE phase complete\n")); + + ssh_set_blocking(sshc->ssh_session, 0); + + state(conn, SSH_SESSION_DISCONNECT); + /* FALLTHROUGH */ + + case SSH_SESSION_DISCONNECT: + /* during weird times when we've been prematurely aborted, the channel + is still alive when we reach this state and we MUST kill the channel + properly first */ + if(sshc->scp_session) { + ssh_scp_free(sshc->scp_session); + sshc->scp_session = NULL; + } + + ssh_disconnect(sshc->ssh_session); + + SSH_STRING_FREE_CHAR(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_FREE); + /* FALLTHROUGH */ + case SSH_SESSION_FREE: + if(sshc->ssh_session) { + ssh_free(sshc->ssh_session); + sshc->ssh_session = NULL; + } + + /* worst-case scenario cleanup */ + + DEBUGASSERT(sshc->ssh_session == NULL); + DEBUGASSERT(sshc->scp_session == NULL); + + if(sshc->readdir_tmp) { + ssh_string_free_char(sshc->readdir_tmp); + sshc->readdir_tmp = NULL; + } + + if(sshc->quote_attrs) + sftp_attributes_free(sshc->quote_attrs); + + if(sshc->readdir_attrs) + sftp_attributes_free(sshc->readdir_attrs); + + if(sshc->readdir_link_attrs) + sftp_attributes_free(sshc->readdir_link_attrs); + + if(sshc->privkey) + ssh_key_free(sshc->privkey); + if(sshc->pubkey) + ssh_key_free(sshc->pubkey); + + Curl_safefree(sshc->rsa_pub); + Curl_safefree(sshc->rsa); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + Curl_safefree(sshc->readdir_line); + Curl_safefree(sshc->readdir_linkPath); + SSH_STRING_FREE_CHAR(sshc->homedir); + + /* the code we are about to return */ + result = sshc->actualcode; + + memset(sshc, 0, sizeof(struct ssh_conn)); + + connclose(conn, "SSH session free"); + sshc->state = SSH_SESSION_FREE; /* current */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + + case SSH_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + + } + } while(!rc && (sshc->state != SSH_STOP)); + + + if(rc == SSH_AGAIN) { + /* we would block, we need to wait for the socket to be ready (in the + right direction too)! */ + *block = TRUE; + } + + return result; +} + + +/* called by the multi interface to figure out what socket(s) to wait for and + for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ +static int myssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock) +{ + int bitmap = GETSOCK_BLANK; + sock[0] = conn->sock[FIRSTSOCKET]; + + if(conn->waitfor & KEEP_RECV) + bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); + + if(conn->waitfor & KEEP_SEND) + bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); + + return bitmap; +} + +/* Generic function called by the multi interface to figure out what socket(s) + to wait for and for what actions during the DOING and PROTOCONNECT states*/ +static int myssh_getsock(struct connectdata *conn, + curl_socket_t *sock) +{ + /* if we know the direction we can use the generic *_getsock() function even + for the protocol_connect and doing states */ + return myssh_perform_getsock(conn, sock); +} + +static void myssh_block2waitfor(struct connectdata *conn, bool block) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + + /* If it didn't block, or nothing was returned by ssh_get_poll_flags + * have the original set */ + conn->waitfor = sshc->orig_waitfor; + + if(block) { + int dir = ssh_get_poll_flags(sshc->ssh_session); + if(dir & SSH_READ_PENDING) { + /* translate the libssh define bits into our own bit defines */ + conn->waitfor = KEEP_RECV; + } + else if(dir & SSH_WRITE_PENDING) { + conn->waitfor = KEEP_SEND; + } + } +} + +/* called repeatedly until done from multi.c */ +static CURLcode myssh_multi_statemach(struct connectdata *conn, + bool *done) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + bool block; /* we store the status and use that to provide a ssh_getsock() + implementation */ + CURLcode result = myssh_statemach_act(conn, &block); + + *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; + myssh_block2waitfor(conn, block); + + return result; +} + +static CURLcode myssh_block_statemach(struct connectdata *conn, + bool disconnect) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + while((sshc->state != SSH_STOP) && !result) { + bool block; + timediff_t left = 1000; + struct curltime now = Curl_now(); + + result = myssh_statemach_act(conn, &block); + if(result) + break; + + if(!disconnect) { + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + result = Curl_speedcheck(data, now); + if(result) + break; + + left = Curl_timeleft(data, NULL, FALSE); + if(left < 0) { + failf(data, "Operation timed out"); + return CURLE_OPERATION_TIMEDOUT; + } + } + if(block) { - curl_socket_t fd_read = conn->sock[FIRSTSOCKET]; - /* wait for the socket to become ready */ - (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD, - CURL_SOCKET_BAD, left > 1000 ? 1000 : left); - } - - } - - return result; -} - -/* - * SSH setup connection - */ -static CURLcode myssh_setup_connection(struct connectdata *conn) -{ - struct SSHPROTO *ssh; - + curl_socket_t fd_read = conn->sock[FIRSTSOCKET]; + /* wait for the socket to become ready */ + (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD, + CURL_SOCKET_BAD, left > 1000 ? 1000 : left); + } + + } + + return result; +} + +/* + * SSH setup connection + */ +static CURLcode myssh_setup_connection(struct connectdata *conn) +{ + struct SSHPROTO *ssh; + conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO)); - if(!ssh) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static Curl_recv scp_recv, sftp_recv; -static Curl_send scp_send, sftp_send; - -/* - * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to - * do protocol-specific actions at connect-time. - */ -static CURLcode myssh_connect(struct connectdata *conn, bool *done) -{ - struct ssh_conn *ssh; - CURLcode result; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - struct Curl_easy *data = conn->data; + if(!ssh) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +static Curl_recv scp_recv, sftp_recv; +static Curl_send scp_send, sftp_send; + +/* + * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to + * do protocol-specific actions at connect-time. + */ +static CURLcode myssh_connect(struct connectdata *conn, bool *done) +{ + struct ssh_conn *ssh; + CURLcode result; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + struct Curl_easy *data = conn->data; int rc; - - /* initialize per-handle data if not already */ + + /* initialize per-handle data if not already */ if(!data->req.p.ssh) - myssh_setup_connection(conn); - - /* We default to persistent connections. We set this already in this connect - function to make the re-use checks properly be able to check this bit. */ - connkeep(conn, "SSH default"); - - if(conn->handler->protocol & CURLPROTO_SCP) { - conn->recv[FIRSTSOCKET] = scp_recv; - conn->send[FIRSTSOCKET] = scp_send; - } - else { - conn->recv[FIRSTSOCKET] = sftp_recv; - conn->send[FIRSTSOCKET] = sftp_send; - } - - ssh = &conn->proto.sshc; - - ssh->ssh_session = ssh_new(); - if(ssh->ssh_session == NULL) { - failf(data, "Failure initialising ssh session"); - return CURLE_FAILED_INIT; - } - + myssh_setup_connection(conn); + + /* We default to persistent connections. We set this already in this connect + function to make the re-use checks properly be able to check this bit. */ + connkeep(conn, "SSH default"); + + if(conn->handler->protocol & CURLPROTO_SCP) { + conn->recv[FIRSTSOCKET] = scp_recv; + conn->send[FIRSTSOCKET] = scp_send; + } + else { + conn->recv[FIRSTSOCKET] = sftp_recv; + conn->send[FIRSTSOCKET] = sftp_send; + } + + ssh = &conn->proto.sshc; + + ssh->ssh_session = ssh_new(); + if(ssh->ssh_session == NULL) { + failf(data, "Failure initialising ssh session"); + return CURLE_FAILED_INIT; + } + rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name); if(rc != SSH_OK) { failf(data, "Could not set remote host"); return CURLE_FAILED_INIT; } - + rc = ssh_options_parse_config(ssh->ssh_session, NULL); if(rc != SSH_OK) { infof(data, "Could not parse SSH configuration files"); @@ -2191,24 +2191,24 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done) } if(conn->user && conn->user[0] != '\0') { - infof(data, "User: %s\n", conn->user); + infof(data, "User: %s\n", conn->user); rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user); if(rc != SSH_OK) { failf(data, "Could not set user"); return CURLE_FAILED_INIT; } - } - - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]); + } + + if(data->set.str[STRING_SSH_KNOWNHOSTS]) { + infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]); rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS, data->set.str[STRING_SSH_KNOWNHOSTS]); if(rc != SSH_OK) { failf(data, "Could not set known hosts file path"); return CURLE_FAILED_INIT; } - } - + } + if(conn->remote_port) { rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT, &conn->remote_port); @@ -2217,649 +2217,649 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done) return CURLE_FAILED_INIT; } } - - if(data->set.ssh_compression) { + + if(data->set.ssh_compression) { rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION, "zlib,zlib@openssh.com,none"); if(rc != SSH_OK) { failf(data, "Could not set compression"); return CURLE_FAILED_INIT; } - } - - ssh->privkey = NULL; - ssh->pubkey = NULL; - - if(data->set.str[STRING_SSH_PUBLIC_KEY]) { + } + + ssh->privkey = NULL; + ssh->pubkey = NULL; + + if(data->set.str[STRING_SSH_PUBLIC_KEY]) { rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY], &ssh->pubkey); - if(rc != SSH_OK) { - failf(data, "Could not load public key file"); + if(rc != SSH_OK) { + failf(data, "Could not load public key file"); return CURLE_FAILED_INIT; - } - } - - /* we do not verify here, we do it at the state machine, - * after connection */ - - state(conn, SSH_INIT); - - result = myssh_multi_statemach(conn, done); - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done) -{ - CURLcode result; - - result = myssh_multi_statemach(conn, dophase_done); - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - return result; -} - -/* - *********************************************************************** - * - * scp_perform() - * - * This is the actual DO function for SCP. Get a file according to - * the options previously setup. - */ - -static -CURLcode scp_perform(struct connectdata *conn, - bool *connected, bool *dophase_done) -{ - CURLcode result = CURLE_OK; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - *dophase_done = FALSE; /* not done yet */ - - /* start the first command in the DO phase */ - state(conn, SSH_SCP_TRANS_INIT); - - result = myssh_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -static CURLcode myssh_do_it(struct connectdata *conn, bool *done) -{ - CURLcode result; - bool connected = 0; - struct Curl_easy *data = conn->data; - struct ssh_conn *sshc = &conn->proto.sshc; - - *done = FALSE; /* default to false */ - - data->req.size = -1; /* make sure this is unknown at this point */ - - sshc->actualcode = CURLE_OK; /* reset error code */ - sshc->secondCreateDirs = 0; /* reset the create dir attempt state - variable */ - - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - Curl_pgrsSetUploadSize(data, -1); - Curl_pgrsSetDownloadSize(data, -1); - - if(conn->handler->protocol & CURLPROTO_SCP) - result = scp_perform(conn, &connected, done); - else - result = sftp_perform(conn, &connected, done); - - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode scp_disconnect(struct connectdata *conn, - bool dead_connection) -{ - CURLcode result = CURLE_OK; - struct ssh_conn *ssh = &conn->proto.sshc; - (void) dead_connection; - - if(ssh->ssh_session) { - /* only if there's a session still around to use! */ - - state(conn, SSH_SESSION_DISCONNECT); - - result = myssh_block_statemach(conn, TRUE); - } - - return result; -} - -/* generic done function for both SCP and SFTP called from their specific - done functions */ -static CURLcode myssh_done(struct connectdata *conn, CURLcode status) -{ - CURLcode result = CURLE_OK; + } + } + + /* we do not verify here, we do it at the state machine, + * after connection */ + + state(conn, SSH_INIT); + + result = myssh_multi_statemach(conn, done); + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done) +{ + CURLcode result; + + result = myssh_multi_statemach(conn, dophase_done); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* + *********************************************************************** + * + * scp_perform() + * + * This is the actual DO function for SCP. Get a file according to + * the options previously setup. + */ + +static +CURLcode scp_perform(struct connectdata *conn, + bool *connected, bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SCP_TRANS_INIT); + + result = myssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +static CURLcode myssh_do_it(struct connectdata *conn, bool *done) +{ + CURLcode result; + bool connected = 0; + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + + *done = FALSE; /* default to false */ + + data->req.size = -1; /* make sure this is unknown at this point */ + + sshc->actualcode = CURLE_OK; /* reset error code */ + sshc->secondCreateDirs = 0; /* reset the create dir attempt state + variable */ + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + if(conn->handler->protocol & CURLPROTO_SCP) + result = scp_perform(conn, &connected, done); + else + result = sftp_perform(conn, &connected, done); + + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode scp_disconnect(struct connectdata *conn, + bool dead_connection) +{ + CURLcode result = CURLE_OK; + struct ssh_conn *ssh = &conn->proto.sshc; + (void) dead_connection; + + if(ssh->ssh_session) { + /* only if there's a session still around to use! */ + + state(conn, SSH_SESSION_DISCONNECT); + + result = myssh_block_statemach(conn, TRUE); + } + + return result; +} + +/* generic done function for both SCP and SFTP called from their specific + done functions */ +static CURLcode myssh_done(struct connectdata *conn, CURLcode status) +{ + CURLcode result = CURLE_OK; struct SSHPROTO *protop = conn->data->req.p.ssh; - - if(!status) { - /* run the state-machine */ - result = myssh_block_statemach(conn, FALSE); - } - else - result = status; - - if(protop) - Curl_safefree(protop->path); - if(Curl_pgrsDone(conn)) - return CURLE_ABORTED_BY_CALLBACK; - - conn->data->req.keepon = 0; /* clear all bits */ - return result; -} - - -static CURLcode scp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - (void) premature; /* not used */ - - if(!status) - state(conn, SSH_SCP_DONE); - - return myssh_done(conn, status); - -} - -static ssize_t scp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, CURLcode *err) -{ - int rc; - (void) sockindex; /* we only support SCP on the fixed known primary socket */ - (void) err; - - rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len); - -#if 0 - /* The following code is misleading, mostly added as wishful thinking - * that libssh at some point will implement non-blocking ssh_scp_write/read. - * Currently rc can only be number of bytes read or SSH_ERROR. */ - myssh_block2waitfor(conn, (rc == SSH_AGAIN) ? TRUE : FALSE); - - if(rc == SSH_AGAIN) { - *err = CURLE_AGAIN; - return 0; - } - else -#endif - if(rc != SSH_OK) { - *err = CURLE_SSH; - return -1; - } - - return len; -} - -static ssize_t scp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len, CURLcode *err) -{ - ssize_t nread; - (void) err; - (void) sockindex; /* we only support SCP on the fixed known primary socket */ - - /* libssh returns int */ - nread = ssh_scp_read(conn->proto.sshc.scp_session, mem, len); - -#if 0 - /* The following code is misleading, mostly added as wishful thinking - * that libssh at some point will implement non-blocking ssh_scp_write/read. - * Currently rc can only be SSH_OK or SSH_ERROR. */ - - myssh_block2waitfor(conn, (nread == SSH_AGAIN) ? TRUE : FALSE); - if(nread == SSH_AGAIN) { - *err = CURLE_AGAIN; - nread = -1; - } -#endif - - return nread; -} - -/* - * =============== SFTP =============== - */ - -/* - *********************************************************************** - * - * sftp_perform() - * - * This is the actual DO function for SFTP. Get a file/directory according to - * the options previously setup. - */ - -static -CURLcode sftp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - *dophase_done = FALSE; /* not done yet */ - - /* start the first command in the DO phase */ - state(conn, SSH_SFTP_QUOTE_INIT); - - /* run the state-machine */ - result = myssh_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode sftp_doing(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result = myssh_multi_statemach(conn, dophase_done); - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) -{ - CURLcode result = CURLE_OK; - (void) dead_connection; - - DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); - - if(conn->proto.sshc.ssh_session) { - /* only if there's a session still around to use! */ - state(conn, SSH_SFTP_SHUTDOWN); - result = myssh_block_statemach(conn, TRUE); - } - - DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); - - return result; - -} - -static CURLcode sftp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - - if(!status) { - /* Post quote commands are executed after the SFTP_CLOSE state to avoid - errors that could happen due to open file handles during POSTQUOTE - operation */ - if(!premature && conn->data->set.postquote && !conn->bits.retry) - sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - state(conn, SSH_SFTP_CLOSE); - } - return myssh_done(conn, status); -} - -/* return number of sent bytes */ -static ssize_t sftp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, CURLcode *err) -{ - ssize_t nwrite; - (void)sockindex; - - nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len); - - myssh_block2waitfor(conn, FALSE); - -#if 0 /* not returned by libssh on write */ - if(nwrite == SSH_AGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else -#endif - if(nwrite < 0) { - *err = CURLE_SSH; - nwrite = -1; - } - - return nwrite; -} - -/* - * Return number of received (decrypted) bytes - * or <0 on error - */ -static ssize_t sftp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len, CURLcode *err) -{ - ssize_t nread; - (void)sockindex; - - DEBUGASSERT(len < CURL_MAX_READ_SIZE); - - switch(conn->proto.sshc.sftp_recv_state) { - case 0: - conn->proto.sshc.sftp_file_index = - sftp_async_read_begin(conn->proto.sshc.sftp_file, - (uint32_t)len); - if(conn->proto.sshc.sftp_file_index < 0) { - *err = CURLE_RECV_ERROR; - return -1; - } - - /* FALLTHROUGH */ - case 1: - conn->proto.sshc.sftp_recv_state = 1; - - nread = sftp_async_read(conn->proto.sshc.sftp_file, - mem, (uint32_t)len, - conn->proto.sshc.sftp_file_index); - - myssh_block2waitfor(conn, (nread == SSH_AGAIN)?TRUE:FALSE); - - if(nread == SSH_AGAIN) { - *err = CURLE_AGAIN; - return -1; - } - else if(nread < 0) { - *err = CURLE_RECV_ERROR; - return -1; - } - - conn->proto.sshc.sftp_recv_state = 0; - return nread; - - default: - /* we never reach here */ - return -1; - } -} - -static void sftp_quote(struct connectdata *conn) -{ - const char *cp; - struct Curl_easy *data = conn->data; + + if(!status) { + /* run the state-machine */ + result = myssh_block_statemach(conn, FALSE); + } + else + result = status; + + if(protop) + Curl_safefree(protop->path); + if(Curl_pgrsDone(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + conn->data->req.keepon = 0; /* clear all bits */ + return result; +} + + +static CURLcode scp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + (void) premature; /* not used */ + + if(!status) + state(conn, SSH_SCP_DONE); + + return myssh_done(conn, status); + +} + +static ssize_t scp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + int rc; + (void) sockindex; /* we only support SCP on the fixed known primary socket */ + (void) err; + + rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len); + +#if 0 + /* The following code is misleading, mostly added as wishful thinking + * that libssh at some point will implement non-blocking ssh_scp_write/read. + * Currently rc can only be number of bytes read or SSH_ERROR. */ + myssh_block2waitfor(conn, (rc == SSH_AGAIN) ? TRUE : FALSE); + + if(rc == SSH_AGAIN) { + *err = CURLE_AGAIN; + return 0; + } + else +#endif + if(rc != SSH_OK) { + *err = CURLE_SSH; + return -1; + } + + return len; +} + +static ssize_t scp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void) err; + (void) sockindex; /* we only support SCP on the fixed known primary socket */ + + /* libssh returns int */ + nread = ssh_scp_read(conn->proto.sshc.scp_session, mem, len); + +#if 0 + /* The following code is misleading, mostly added as wishful thinking + * that libssh at some point will implement non-blocking ssh_scp_write/read. + * Currently rc can only be SSH_OK or SSH_ERROR. */ + + myssh_block2waitfor(conn, (nread == SSH_AGAIN) ? TRUE : FALSE); + if(nread == SSH_AGAIN) { + *err = CURLE_AGAIN; + nread = -1; + } +#endif + + return nread; +} + +/* + * =============== SFTP =============== + */ + +/* + *********************************************************************** + * + * sftp_perform() + * + * This is the actual DO function for SFTP. Get a file/directory according to + * the options previously setup. + */ + +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SFTP_QUOTE_INIT); + + /* run the state-machine */ + result = myssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = myssh_multi_statemach(conn, dophase_done); + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) +{ + CURLcode result = CURLE_OK; + (void) dead_connection; + + DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); + + if(conn->proto.sshc.ssh_session) { + /* only if there's a session still around to use! */ + state(conn, SSH_SFTP_SHUTDOWN); + result = myssh_block_statemach(conn, TRUE); + } + + DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); + + return result; + +} + +static CURLcode sftp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + + if(!status) { + /* Post quote commands are executed after the SFTP_CLOSE state to avoid + errors that could happen due to open file handles during POSTQUOTE + operation */ + if(!premature && conn->data->set.postquote && !conn->bits.retry) + sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; + state(conn, SSH_SFTP_CLOSE); + } + return myssh_done(conn, status); +} + +/* return number of sent bytes */ +static ssize_t sftp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + ssize_t nwrite; + (void)sockindex; + + nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len); + + myssh_block2waitfor(conn, FALSE); + +#if 0 /* not returned by libssh on write */ + if(nwrite == SSH_AGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } + else +#endif + if(nwrite < 0) { + *err = CURLE_SSH; + nwrite = -1; + } + + return nwrite; +} + +/* + * Return number of received (decrypted) bytes + * or <0 on error + */ +static ssize_t sftp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void)sockindex; + + DEBUGASSERT(len < CURL_MAX_READ_SIZE); + + switch(conn->proto.sshc.sftp_recv_state) { + case 0: + conn->proto.sshc.sftp_file_index = + sftp_async_read_begin(conn->proto.sshc.sftp_file, + (uint32_t)len); + if(conn->proto.sshc.sftp_file_index < 0) { + *err = CURLE_RECV_ERROR; + return -1; + } + + /* FALLTHROUGH */ + case 1: + conn->proto.sshc.sftp_recv_state = 1; + + nread = sftp_async_read(conn->proto.sshc.sftp_file, + mem, (uint32_t)len, + conn->proto.sshc.sftp_file_index); + + myssh_block2waitfor(conn, (nread == SSH_AGAIN)?TRUE:FALSE); + + if(nread == SSH_AGAIN) { + *err = CURLE_AGAIN; + return -1; + } + else if(nread < 0) { + *err = CURLE_RECV_ERROR; + return -1; + } + + conn->proto.sshc.sftp_recv_state = 0; + return nread; + + default: + /* we never reach here */ + return -1; + } +} + +static void sftp_quote(struct connectdata *conn) +{ + const char *cp; + struct Curl_easy *data = conn->data; struct SSHPROTO *protop = data->req.p.ssh; - struct ssh_conn *sshc = &conn->proto.sshc; - CURLcode result; - - /* - * Support some of the "FTP" commands - */ - char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - if(strcasecompare("pwd", cmd)) { - /* output debug output if that is requested */ - char *tmp = aprintf("257 \"%s\" is current directory.\n", - protop->path); - if(!tmp) { - sshc->actualcode = CURLE_OUT_OF_MEMORY; - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return; - } + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result; + + /* + * Support some of the "FTP" commands + */ + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + if(strcasecompare("pwd", cmd)) { + /* output debug output if that is requested */ + char *tmp = aprintf("257 \"%s\" is current directory.\n", + protop->path); + if(!tmp) { + sshc->actualcode = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + return; + } Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4); Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp)); - /* this sends an FTP-like "header" to the header callback so that the - current directory can be read very similar to how it is read when - using ordinary FTP. */ - result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - free(tmp); - if(result) { - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - else - state(conn, SSH_SFTP_NEXT_QUOTE); - return; - } - - /* - * the arguments following the command must be separated from the - * command with a space so we can check for it unconditionally - */ - cp = strchr(cmd, ' '); - if(cp == NULL) { - failf(data, "Syntax error in SFTP command. Supply parameter(s)!"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - - /* - * also, every command takes at least one argument so we get that - * first argument right now - */ - result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error: Bad first parameter"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return; - } - - /* - * SFTP is a binary protocol, so we don't send text commands - * to the server. Instead, we scan for commands used by - * OpenSSH's sftp program and call the appropriate libssh - * functions. - */ - if(strncasecompare(cmd, "chgrp ", 6) || - strncasecompare(cmd, "chmod ", 6) || + /* this sends an FTP-like "header" to the header callback so that the + current directory can be read very similar to how it is read when + using ordinary FTP. */ + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + else + state(conn, SSH_SFTP_NEXT_QUOTE); + return; + } + + /* + * the arguments following the command must be separated from the + * command with a space so we can check for it unconditionally + */ + cp = strchr(cmd, ' '); + if(cp == NULL) { + failf(data, "Syntax error in SFTP command. Supply parameter(s)!"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + + /* + * also, every command takes at least one argument so we get that + * first argument right now + */ + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error: Bad first parameter"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + + /* + * SFTP is a binary protocol, so we don't send text commands + * to the server. Instead, we scan for commands used by + * OpenSSH's sftp program and call the appropriate libssh + * functions. + */ + if(strncasecompare(cmd, "chgrp ", 6) || + strncasecompare(cmd, "chmod ", 6) || strncasecompare(cmd, "chown ", 6) || strncasecompare(cmd, "atime ", 6) || strncasecompare(cmd, "mtime ", 6)) { - /* attribute change */ - - /* sshc->quote_path1 contains the mode to set */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else + /* attribute change */ + + /* sshc->quote_path1 contains the mode to set */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else failf(data, "Syntax error in chgrp/chmod/chown/atime/mtime: " - "Bad second parameter"); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return; - } - sshc->quote_attrs = NULL; - state(conn, SSH_SFTP_QUOTE_STAT); - return; - } - if(strncasecompare(cmd, "ln ", 3) || - strncasecompare(cmd, "symlink ", 8)) { - /* symbolic linking */ - /* sshc->quote_path1 is the source */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in ln/symlink: Bad second parameter"); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return; - } - state(conn, SSH_SFTP_QUOTE_SYMLINK); - return; - } - else if(strncasecompare(cmd, "mkdir ", 6)) { - /* create dir */ - state(conn, SSH_SFTP_QUOTE_MKDIR); - return; - } - else if(strncasecompare(cmd, "rename ", 7)) { - /* rename file */ - /* first param is the source path */ - /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in rename: Bad second parameter"); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return; - } - state(conn, SSH_SFTP_QUOTE_RENAME); - return; - } - else if(strncasecompare(cmd, "rmdir ", 6)) { - /* delete dir */ - state(conn, SSH_SFTP_QUOTE_RMDIR); - return; - } - else if(strncasecompare(cmd, "rm ", 3)) { - state(conn, SSH_SFTP_QUOTE_UNLINK); - return; - } -#ifdef HAS_STATVFS_SUPPORT - else if(strncasecompare(cmd, "statvfs ", 8)) { - state(conn, SSH_SFTP_QUOTE_STATVFS); - return; - } -#endif - - failf(data, "Unknown SFTP command"); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; -} - -static void sftp_quote_stat(struct connectdata *conn) -{ - struct Curl_easy *data = conn->data; - struct ssh_conn *sshc = &conn->proto.sshc; - char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - /* We read the file attributes, store them in sshc->quote_attrs - * and modify them accordingly to command. Then we switch to - * QUOTE_SETSTAT state to write new ones. - */ - - if(sshc->quote_attrs) - sftp_attributes_free(sshc->quote_attrs); - sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); - if(sshc->quote_attrs == NULL) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Attempt to get SFTP stats failed: %d", - sftp_get_error(sshc->sftp_session)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - - /* Now set the new attributes... */ - if(strncasecompare(cmd, "chgrp", 5)) { - sshc->quote_attrs->gid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10); - if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && - !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chgrp gid not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; - } - else if(strncasecompare(cmd, "chmod", 5)) { - mode_t perms; - perms = (mode_t)strtoul(sshc->quote_path1, NULL, 8); - /* permissions are octal */ - if(perms == 0 && !ISDIGIT(sshc->quote_path1[0])) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chmod permissions not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - sshc->quote_attrs->permissions = perms; - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS; - } - else if(strncasecompare(cmd, "chown", 5)) { - sshc->quote_attrs->uid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10); - if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && - !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chown uid not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; - } - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; - } + "Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + sshc->quote_attrs = NULL; + state(conn, SSH_SFTP_QUOTE_STAT); + return; + } + if(strncasecompare(cmd, "ln ", 3) || + strncasecompare(cmd, "symlink ", 8)) { + /* symbolic linking */ + /* sshc->quote_path1 is the source */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in ln/symlink: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + state(conn, SSH_SFTP_QUOTE_SYMLINK); + return; + } + else if(strncasecompare(cmd, "mkdir ", 6)) { + /* create dir */ + state(conn, SSH_SFTP_QUOTE_MKDIR); + return; + } + else if(strncasecompare(cmd, "rename ", 7)) { + /* rename file */ + /* first param is the source path */ + /* second param is the dest. path */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in rename: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + state(conn, SSH_SFTP_QUOTE_RENAME); + return; + } + else if(strncasecompare(cmd, "rmdir ", 6)) { + /* delete dir */ + state(conn, SSH_SFTP_QUOTE_RMDIR); + return; + } + else if(strncasecompare(cmd, "rm ", 3)) { + state(conn, SSH_SFTP_QUOTE_UNLINK); + return; + } +#ifdef HAS_STATVFS_SUPPORT + else if(strncasecompare(cmd, "statvfs ", 8)) { + state(conn, SSH_SFTP_QUOTE_STATVFS); + return; + } +#endif + + failf(data, "Unknown SFTP command"); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; +} + +static void sftp_quote_stat(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + /* We read the file attributes, store them in sshc->quote_attrs + * and modify them accordingly to command. Then we switch to + * QUOTE_SETSTAT state to write new ones. + */ + + if(sshc->quote_attrs) + sftp_attributes_free(sshc->quote_attrs); + sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); + if(sshc->quote_attrs == NULL) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to get SFTP stats failed: %d", + sftp_get_error(sshc->sftp_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + + /* Now set the new attributes... */ + if(strncasecompare(cmd, "chgrp", 5)) { + sshc->quote_attrs->gid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10); + if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chgrp gid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; + } + else if(strncasecompare(cmd, "chmod", 5)) { + mode_t perms; + perms = (mode_t)strtoul(sshc->quote_path1, NULL, 8); + /* permissions are octal */ + if(perms == 0 && !ISDIGIT(sshc->quote_path1[0])) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chmod permissions not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->permissions = perms; + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS; + } + else if(strncasecompare(cmd, "chown", 5)) { + sshc->quote_attrs->uid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10); + if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chown uid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; + } else if(strncasecompare(cmd, "atime", 5)) { time_t date = Curl_getdate_capped(sshc->quote_path1); if(date == -1) { @@ -2888,29 +2888,29 @@ static void sftp_quote_stat(struct connectdata *conn) sshc->quote_attrs->mtime = (uint32_t)date; sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME; } - - /* Now send the completed structure... */ - state(conn, SSH_SFTP_QUOTE_SETSTAT); - return; -} - -CURLcode Curl_ssh_init(void) -{ - if(ssh_init()) { - DEBUGF(fprintf(stderr, "Error: libssh_init failed\n")); - return CURLE_FAILED_INIT; - } - return CURLE_OK; -} - -void Curl_ssh_cleanup(void) -{ - (void)ssh_finalize(); -} - -size_t Curl_ssh_version(char *buffer, size_t buflen) -{ - return msnprintf(buffer, buflen, "libssh/%s", CURL_LIBSSH_VERSION); -} - -#endif /* USE_LIBSSH */ + + /* Now send the completed structure... */ + state(conn, SSH_SFTP_QUOTE_SETSTAT); + return; +} + +CURLcode Curl_ssh_init(void) +{ + if(ssh_init()) { + DEBUGF(fprintf(stderr, "Error: libssh_init failed\n")); + return CURLE_FAILED_INIT; + } + return CURLE_OK; +} + +void Curl_ssh_cleanup(void) +{ + (void)ssh_finalize(); +} + +size_t Curl_ssh_version(char *buffer, size_t buflen) +{ + return msnprintf(buffer, buflen, "libssh/%s", CURL_LIBSSH_VERSION); +} + +#endif /* USE_LIBSSH */ diff --git a/contrib/libs/curl/lib/vssh/libssh2.c b/contrib/libs/curl/lib/vssh/libssh2.c index 807c919641..b282bf23f4 100644 --- a/contrib/libs/curl/lib/vssh/libssh2.c +++ b/contrib/libs/curl/lib/vssh/libssh2.c @@ -1,471 +1,471 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* #define CURL_LIBSSH2_DEBUG */ - -#include "curl_setup.h" - -#ifdef USE_LIBSSH2 - -#include <limits.h> - -#error #include <libssh2.h> -#error #include <libssh2_sftp.h> - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_UTSNAME_H -#include <sys/utsname.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef __VMS -#include <in.h> -#include <inet.h> -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include <curl/curl.h> -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "http.h" /* for HTTP proxy tunnel stuff */ -#include "ssh.h" -#include "url.h" -#include "speedcheck.h" -#include "getinfo.h" -#include "strdup.h" -#include "strcase.h" -#include "vtls/vtls.h" -#include "connect.h" -#include "strerror.h" -#include "inet_ntop.h" -#include "parsedate.h" /* for the week day and month names */ -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "strtoofft.h" -#include "multiif.h" -#include "select.h" -#include "warnless.h" -#include "curl_path.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#if LIBSSH2_VERSION_NUM >= 0x010206 -/* libssh2_sftp_statvfs and friends were added in 1.2.6 */ -#define HAS_STATVFS_SUPPORT 1 -#endif - + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* #define CURL_LIBSSH2_DEBUG */ + +#include "curl_setup.h" + +#ifdef USE_LIBSSH2 + +#include <limits.h> + +#error #include <libssh2.h> +#error #include <libssh2_sftp.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_UTSNAME_H +#include <sys/utsname.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#ifdef __VMS +#include <in.h> +#include <inet.h> +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include <curl/curl.h> +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "ssh.h" +#include "url.h" +#include "speedcheck.h" +#include "getinfo.h" +#include "strdup.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "inet_ntop.h" +#include "parsedate.h" /* for the week day and month names */ +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "strtoofft.h" +#include "multiif.h" +#include "select.h" +#include "warnless.h" +#include "curl_path.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#if LIBSSH2_VERSION_NUM >= 0x010206 +/* libssh2_sftp_statvfs and friends were added in 1.2.6 */ +#define HAS_STATVFS_SUPPORT 1 +#endif + #define sftp_libssh2_realpath(s,p,t,m) \ libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \ (t), (m), LIBSSH2_SFTP_REALPATH) - -/* Local functions: */ + +/* Local functions: */ static const char *sftp_libssh2_strerror(unsigned long err); -static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc); -static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc); -static LIBSSH2_FREE_FUNC(my_libssh2_free); - +static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc); +static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc); +static LIBSSH2_FREE_FUNC(my_libssh2_free); + static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn); -static CURLcode ssh_connect(struct connectdata *conn, bool *done); -static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done); -static CURLcode ssh_do(struct connectdata *conn, bool *done); - -static CURLcode scp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode scp_doing(struct connectdata *conn, - bool *dophase_done); -static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection); - -static CURLcode sftp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode sftp_doing(struct connectdata *conn, - bool *dophase_done); -static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); -static -CURLcode sftp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done); -static int ssh_getsock(struct connectdata *conn, curl_socket_t *sock); -static int ssh_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock); -static CURLcode ssh_setup_connection(struct connectdata *conn); - -/* - * SCP protocol handler. - */ - -const struct Curl_handler Curl_handler_scp = { - "SCP", /* scheme */ - ssh_setup_connection, /* setup_connection */ - ssh_do, /* do_it */ - scp_done, /* done */ - ZERO_NULL, /* do_more */ - ssh_connect, /* connect_it */ - ssh_multi_statemach, /* connecting */ - scp_doing, /* doing */ - ssh_getsock, /* proto_getsock */ - ssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ssh_perform_getsock, /* perform_getsock */ - scp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - ZERO_NULL, /* connection_check */ - PORT_SSH, /* defport */ - CURLPROTO_SCP, /* protocol */ +static CURLcode ssh_connect(struct connectdata *conn, bool *done); +static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done); +static CURLcode ssh_do(struct connectdata *conn, bool *done); + +static CURLcode scp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode scp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection); + +static CURLcode sftp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done); +static int ssh_getsock(struct connectdata *conn, curl_socket_t *sock); +static int ssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock); +static CURLcode ssh_setup_connection(struct connectdata *conn); + +/* + * SCP protocol handler. + */ + +const struct Curl_handler Curl_handler_scp = { + "SCP", /* scheme */ + ssh_setup_connection, /* setup_connection */ + ssh_do, /* do_it */ + scp_done, /* done */ + ZERO_NULL, /* do_more */ + ssh_connect, /* connect_it */ + ssh_multi_statemach, /* connecting */ + scp_doing, /* doing */ + ssh_getsock, /* proto_getsock */ + ssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ssh_perform_getsock, /* perform_getsock */ + scp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SCP, /* protocol */ CURLPROTO_SCP, /* family */ - PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION - | PROTOPT_NOURLQUERY /* flags */ -}; - - -/* - * SFTP protocol handler. - */ - -const struct Curl_handler Curl_handler_sftp = { - "SFTP", /* scheme */ - ssh_setup_connection, /* setup_connection */ - ssh_do, /* do_it */ - sftp_done, /* done */ - ZERO_NULL, /* do_more */ - ssh_connect, /* connect_it */ - ssh_multi_statemach, /* connecting */ - sftp_doing, /* doing */ - ssh_getsock, /* proto_getsock */ - ssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ssh_perform_getsock, /* perform_getsock */ - sftp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - ZERO_NULL, /* connection_check */ - PORT_SSH, /* defport */ - CURLPROTO_SFTP, /* protocol */ + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION + | PROTOPT_NOURLQUERY /* flags */ +}; + + +/* + * SFTP protocol handler. + */ + +const struct Curl_handler Curl_handler_sftp = { + "SFTP", /* scheme */ + ssh_setup_connection, /* setup_connection */ + ssh_do, /* do_it */ + sftp_done, /* done */ + ZERO_NULL, /* do_more */ + ssh_connect, /* connect_it */ + ssh_multi_statemach, /* connecting */ + sftp_doing, /* doing */ + ssh_getsock, /* proto_getsock */ + ssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ssh_perform_getsock, /* perform_getsock */ + sftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SFTP, /* protocol */ CURLPROTO_SFTP, /* family */ - PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION - | PROTOPT_NOURLQUERY /* flags */ -}; - -static void -kbd_callback(const char *name, int name_len, const char *instruction, - int instruction_len, int num_prompts, - const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, - LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, - void **abstract) -{ - struct connectdata *conn = (struct connectdata *)*abstract; - -#ifdef CURL_LIBSSH2_DEBUG - fprintf(stderr, "name=%s\n", name); - fprintf(stderr, "name_len=%d\n", name_len); - fprintf(stderr, "instruction=%s\n", instruction); - fprintf(stderr, "instruction_len=%d\n", instruction_len); - fprintf(stderr, "num_prompts=%d\n", num_prompts); -#else - (void)name; - (void)name_len; - (void)instruction; - (void)instruction_len; -#endif /* CURL_LIBSSH2_DEBUG */ - if(num_prompts == 1) { - responses[0].text = strdup(conn->passwd); - responses[0].length = curlx_uztoui(strlen(conn->passwd)); - } - (void)prompts; - (void)abstract; -} /* kbd_callback */ - + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION + | PROTOPT_NOURLQUERY /* flags */ +}; + +static void +kbd_callback(const char *name, int name_len, const char *instruction, + int instruction_len, int num_prompts, + const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, + LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, + void **abstract) +{ + struct connectdata *conn = (struct connectdata *)*abstract; + +#ifdef CURL_LIBSSH2_DEBUG + fprintf(stderr, "name=%s\n", name); + fprintf(stderr, "name_len=%d\n", name_len); + fprintf(stderr, "instruction=%s\n", instruction); + fprintf(stderr, "instruction_len=%d\n", instruction_len); + fprintf(stderr, "num_prompts=%d\n", num_prompts); +#else + (void)name; + (void)name_len; + (void)instruction; + (void)instruction_len; +#endif /* CURL_LIBSSH2_DEBUG */ + if(num_prompts == 1) { + responses[0].text = strdup(conn->passwd); + responses[0].length = curlx_uztoui(strlen(conn->passwd)); + } + (void)prompts; + (void)abstract; +} /* kbd_callback */ + static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err) -{ - switch(err) { - case LIBSSH2_FX_OK: - return CURLE_OK; - - case LIBSSH2_FX_NO_SUCH_FILE: - case LIBSSH2_FX_NO_SUCH_PATH: - return CURLE_REMOTE_FILE_NOT_FOUND; - - case LIBSSH2_FX_PERMISSION_DENIED: - case LIBSSH2_FX_WRITE_PROTECT: - case LIBSSH2_FX_LOCK_CONFlICT: - return CURLE_REMOTE_ACCESS_DENIED; - - case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: - case LIBSSH2_FX_QUOTA_EXCEEDED: - return CURLE_REMOTE_DISK_FULL; - - case LIBSSH2_FX_FILE_ALREADY_EXISTS: - return CURLE_REMOTE_FILE_EXISTS; - - case LIBSSH2_FX_DIR_NOT_EMPTY: - return CURLE_QUOTE_ERROR; - - default: - break; - } - - return CURLE_SSH; -} - -static CURLcode libssh2_session_error_to_CURLE(int err) -{ - switch(err) { - /* Ordered by order of appearance in libssh2.h */ - case LIBSSH2_ERROR_NONE: - return CURLE_OK; - - /* This is the error returned by libssh2_scp_recv2 - * on unknown file */ - case LIBSSH2_ERROR_SCP_PROTOCOL: - return CURLE_REMOTE_FILE_NOT_FOUND; - - case LIBSSH2_ERROR_SOCKET_NONE: - return CURLE_COULDNT_CONNECT; - - case LIBSSH2_ERROR_ALLOC: - return CURLE_OUT_OF_MEMORY; - - case LIBSSH2_ERROR_SOCKET_SEND: - return CURLE_SEND_ERROR; - - case LIBSSH2_ERROR_HOSTKEY_INIT: - case LIBSSH2_ERROR_HOSTKEY_SIGN: - case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED: - case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED: - return CURLE_PEER_FAILED_VERIFICATION; - - case LIBSSH2_ERROR_PASSWORD_EXPIRED: - return CURLE_LOGIN_DENIED; - - case LIBSSH2_ERROR_SOCKET_TIMEOUT: - case LIBSSH2_ERROR_TIMEOUT: - return CURLE_OPERATION_TIMEDOUT; - - case LIBSSH2_ERROR_EAGAIN: - return CURLE_AGAIN; - } - - return CURLE_SSH; -} - -static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc) -{ - (void)abstract; /* arg not used */ - return malloc(count); -} - -static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc) -{ - (void)abstract; /* arg not used */ - return realloc(ptr, count); -} - -static LIBSSH2_FREE_FUNC(my_libssh2_free) -{ - (void)abstract; /* arg not used */ - if(ptr) /* ssh2 agent sometimes call free with null ptr */ - free(ptr); -} - -/* - * SSH State machine related code - */ -/* This is the ONLY way to change SSH state! */ -static void state(struct connectdata *conn, sshstate nowstate) -{ - struct ssh_conn *sshc = &conn->proto.sshc; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ - static const char * const names[] = { - "SSH_STOP", - "SSH_INIT", - "SSH_S_STARTUP", - "SSH_HOSTKEY", - "SSH_AUTHLIST", - "SSH_AUTH_PKEY_INIT", - "SSH_AUTH_PKEY", - "SSH_AUTH_PASS_INIT", - "SSH_AUTH_PASS", - "SSH_AUTH_AGENT_INIT", - "SSH_AUTH_AGENT_LIST", - "SSH_AUTH_AGENT", - "SSH_AUTH_HOST_INIT", - "SSH_AUTH_HOST", - "SSH_AUTH_KEY_INIT", - "SSH_AUTH_KEY", - "SSH_AUTH_GSSAPI", - "SSH_AUTH_DONE", - "SSH_SFTP_INIT", - "SSH_SFTP_REALPATH", - "SSH_SFTP_QUOTE_INIT", - "SSH_SFTP_POSTQUOTE_INIT", - "SSH_SFTP_QUOTE", - "SSH_SFTP_NEXT_QUOTE", - "SSH_SFTP_QUOTE_STAT", - "SSH_SFTP_QUOTE_SETSTAT", - "SSH_SFTP_QUOTE_SYMLINK", - "SSH_SFTP_QUOTE_MKDIR", - "SSH_SFTP_QUOTE_RENAME", - "SSH_SFTP_QUOTE_RMDIR", - "SSH_SFTP_QUOTE_UNLINK", - "SSH_SFTP_QUOTE_STATVFS", - "SSH_SFTP_GETINFO", - "SSH_SFTP_FILETIME", - "SSH_SFTP_TRANS_INIT", - "SSH_SFTP_UPLOAD_INIT", - "SSH_SFTP_CREATE_DIRS_INIT", - "SSH_SFTP_CREATE_DIRS", - "SSH_SFTP_CREATE_DIRS_MKDIR", - "SSH_SFTP_READDIR_INIT", - "SSH_SFTP_READDIR", - "SSH_SFTP_READDIR_LINK", - "SSH_SFTP_READDIR_BOTTOM", - "SSH_SFTP_READDIR_DONE", - "SSH_SFTP_DOWNLOAD_INIT", - "SSH_SFTP_DOWNLOAD_STAT", - "SSH_SFTP_CLOSE", - "SSH_SFTP_SHUTDOWN", - "SSH_SCP_TRANS_INIT", - "SSH_SCP_UPLOAD_INIT", - "SSH_SCP_DOWNLOAD_INIT", - "SSH_SCP_DOWNLOAD", - "SSH_SCP_DONE", - "SSH_SCP_SEND_EOF", - "SSH_SCP_WAIT_EOF", - "SSH_SCP_WAIT_CLOSE", - "SSH_SCP_CHANNEL_FREE", - "SSH_SESSION_DISCONNECT", - "SSH_SESSION_FREE", - "QUIT" - }; - - /* a precaution to make sure the lists are in sync */ - DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST); - - if(sshc->state != nowstate) { - infof(conn->data, "SFTP %p state change from %s to %s\n", - (void *)sshc, names[sshc->state], names[nowstate]); - } -#endif - - sshc->state = nowstate; -} - - -#ifdef HAVE_LIBSSH2_KNOWNHOST_API -static int sshkeycallback(struct Curl_easy *easy, - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch match, - void *clientp) -{ - (void)easy; - (void)knownkey; - (void)foundkey; - (void)clientp; - - /* we only allow perfect matches, and we reject everything else */ - return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE; -} -#endif - -/* - * Earlier libssh2 versions didn't have the ability to seek to 64bit positions - * with 32bit size_t. - */ -#ifdef HAVE_LIBSSH2_SFTP_SEEK64 -#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y) -#else -#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y) -#endif - -/* - * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit - * architectures so we check of the necessary function is present. - */ -#ifndef HAVE_LIBSSH2_SCP_SEND64 -#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0) -#else -#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \ - (libssh2_uint64_t)d, 0, 0) -#endif - -/* - * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64. - */ -#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE -#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y) -#endif - -static CURLcode ssh_knownhost(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - struct Curl_easy *data = conn->data; - - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - /* we're asked to verify the host against a file */ - struct ssh_conn *sshc = &conn->proto.sshc; +{ + switch(err) { + case LIBSSH2_FX_OK: + return CURLE_OK; + + case LIBSSH2_FX_NO_SUCH_FILE: + case LIBSSH2_FX_NO_SUCH_PATH: + return CURLE_REMOTE_FILE_NOT_FOUND; + + case LIBSSH2_FX_PERMISSION_DENIED: + case LIBSSH2_FX_WRITE_PROTECT: + case LIBSSH2_FX_LOCK_CONFlICT: + return CURLE_REMOTE_ACCESS_DENIED; + + case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: + case LIBSSH2_FX_QUOTA_EXCEEDED: + return CURLE_REMOTE_DISK_FULL; + + case LIBSSH2_FX_FILE_ALREADY_EXISTS: + return CURLE_REMOTE_FILE_EXISTS; + + case LIBSSH2_FX_DIR_NOT_EMPTY: + return CURLE_QUOTE_ERROR; + + default: + break; + } + + return CURLE_SSH; +} + +static CURLcode libssh2_session_error_to_CURLE(int err) +{ + switch(err) { + /* Ordered by order of appearance in libssh2.h */ + case LIBSSH2_ERROR_NONE: + return CURLE_OK; + + /* This is the error returned by libssh2_scp_recv2 + * on unknown file */ + case LIBSSH2_ERROR_SCP_PROTOCOL: + return CURLE_REMOTE_FILE_NOT_FOUND; + + case LIBSSH2_ERROR_SOCKET_NONE: + return CURLE_COULDNT_CONNECT; + + case LIBSSH2_ERROR_ALLOC: + return CURLE_OUT_OF_MEMORY; + + case LIBSSH2_ERROR_SOCKET_SEND: + return CURLE_SEND_ERROR; + + case LIBSSH2_ERROR_HOSTKEY_INIT: + case LIBSSH2_ERROR_HOSTKEY_SIGN: + case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED: + case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED: + return CURLE_PEER_FAILED_VERIFICATION; + + case LIBSSH2_ERROR_PASSWORD_EXPIRED: + return CURLE_LOGIN_DENIED; + + case LIBSSH2_ERROR_SOCKET_TIMEOUT: + case LIBSSH2_ERROR_TIMEOUT: + return CURLE_OPERATION_TIMEDOUT; + + case LIBSSH2_ERROR_EAGAIN: + return CURLE_AGAIN; + } + + return CURLE_SSH; +} + +static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc) +{ + (void)abstract; /* arg not used */ + return malloc(count); +} + +static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc) +{ + (void)abstract; /* arg not used */ + return realloc(ptr, count); +} + +static LIBSSH2_FREE_FUNC(my_libssh2_free) +{ + (void)abstract; /* arg not used */ + if(ptr) /* ssh2 agent sometimes call free with null ptr */ + free(ptr); +} + +/* + * SSH State machine related code + */ +/* This is the ONLY way to change SSH state! */ +static void state(struct connectdata *conn, sshstate nowstate) +{ + struct ssh_conn *sshc = &conn->proto.sshc; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char * const names[] = { + "SSH_STOP", + "SSH_INIT", + "SSH_S_STARTUP", + "SSH_HOSTKEY", + "SSH_AUTHLIST", + "SSH_AUTH_PKEY_INIT", + "SSH_AUTH_PKEY", + "SSH_AUTH_PASS_INIT", + "SSH_AUTH_PASS", + "SSH_AUTH_AGENT_INIT", + "SSH_AUTH_AGENT_LIST", + "SSH_AUTH_AGENT", + "SSH_AUTH_HOST_INIT", + "SSH_AUTH_HOST", + "SSH_AUTH_KEY_INIT", + "SSH_AUTH_KEY", + "SSH_AUTH_GSSAPI", + "SSH_AUTH_DONE", + "SSH_SFTP_INIT", + "SSH_SFTP_REALPATH", + "SSH_SFTP_QUOTE_INIT", + "SSH_SFTP_POSTQUOTE_INIT", + "SSH_SFTP_QUOTE", + "SSH_SFTP_NEXT_QUOTE", + "SSH_SFTP_QUOTE_STAT", + "SSH_SFTP_QUOTE_SETSTAT", + "SSH_SFTP_QUOTE_SYMLINK", + "SSH_SFTP_QUOTE_MKDIR", + "SSH_SFTP_QUOTE_RENAME", + "SSH_SFTP_QUOTE_RMDIR", + "SSH_SFTP_QUOTE_UNLINK", + "SSH_SFTP_QUOTE_STATVFS", + "SSH_SFTP_GETINFO", + "SSH_SFTP_FILETIME", + "SSH_SFTP_TRANS_INIT", + "SSH_SFTP_UPLOAD_INIT", + "SSH_SFTP_CREATE_DIRS_INIT", + "SSH_SFTP_CREATE_DIRS", + "SSH_SFTP_CREATE_DIRS_MKDIR", + "SSH_SFTP_READDIR_INIT", + "SSH_SFTP_READDIR", + "SSH_SFTP_READDIR_LINK", + "SSH_SFTP_READDIR_BOTTOM", + "SSH_SFTP_READDIR_DONE", + "SSH_SFTP_DOWNLOAD_INIT", + "SSH_SFTP_DOWNLOAD_STAT", + "SSH_SFTP_CLOSE", + "SSH_SFTP_SHUTDOWN", + "SSH_SCP_TRANS_INIT", + "SSH_SCP_UPLOAD_INIT", + "SSH_SCP_DOWNLOAD_INIT", + "SSH_SCP_DOWNLOAD", + "SSH_SCP_DONE", + "SSH_SCP_SEND_EOF", + "SSH_SCP_WAIT_EOF", + "SSH_SCP_WAIT_CLOSE", + "SSH_SCP_CHANNEL_FREE", + "SSH_SESSION_DISCONNECT", + "SSH_SESSION_FREE", + "QUIT" + }; + + /* a precaution to make sure the lists are in sync */ + DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST); + + if(sshc->state != nowstate) { + infof(conn->data, "SFTP %p state change from %s to %s\n", + (void *)sshc, names[sshc->state], names[nowstate]); + } +#endif + + sshc->state = nowstate; +} + + +#ifdef HAVE_LIBSSH2_KNOWNHOST_API +static int sshkeycallback(struct Curl_easy *easy, + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch match, + void *clientp) +{ + (void)easy; + (void)knownkey; + (void)foundkey; + (void)clientp; + + /* we only allow perfect matches, and we reject everything else */ + return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE; +} +#endif + +/* + * Earlier libssh2 versions didn't have the ability to seek to 64bit positions + * with 32bit size_t. + */ +#ifdef HAVE_LIBSSH2_SFTP_SEEK64 +#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y) +#else +#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y) +#endif + +/* + * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit + * architectures so we check of the necessary function is present. + */ +#ifndef HAVE_LIBSSH2_SCP_SEND64 +#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0) +#else +#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \ + (libssh2_uint64_t)d, 0, 0) +#endif + +/* + * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64. + */ +#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE +#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y) +#endif + +static CURLcode ssh_knownhost(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + struct Curl_easy *data = conn->data; + + if(data->set.str[STRING_SSH_KNOWNHOSTS]) { + /* we're asked to verify the host against a file */ + struct ssh_conn *sshc = &conn->proto.sshc; struct libssh2_knownhost *host = NULL; - int rc; - int keytype; - size_t keylen; - const char *remotekey = libssh2_session_hostkey(sshc->ssh_session, - &keylen, &keytype); - int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE; - int keybit = 0; - - if(remotekey) { - /* - * A subject to figure out is what host name we need to pass in here. - * What host name does OpenSSH store in its file if an IDN name is - * used? - */ - enum curl_khmatch keymatch; - curl_sshkeycallback func = - data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback; - struct curl_khkey knownkey; - struct curl_khkey *knownkeyp = NULL; - struct curl_khkey foundkey; - + int rc; + int keytype; + size_t keylen; + const char *remotekey = libssh2_session_hostkey(sshc->ssh_session, + &keylen, &keytype); + int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE; + int keybit = 0; + + if(remotekey) { + /* + * A subject to figure out is what host name we need to pass in here. + * What host name does OpenSSH store in its file if an IDN name is + * used? + */ + enum curl_khmatch keymatch; + curl_sshkeycallback func = + data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback; + struct curl_khkey knownkey; + struct curl_khkey *knownkeyp = NULL; + struct curl_khkey foundkey; + switch(keytype) { case LIBSSH2_HOSTKEY_TYPE_RSA: keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA; @@ -502,7 +502,7 @@ static CURLcode ssh_knownhost(struct connectdata *conn) /* no check means failure! */ rc = CURLKHSTAT_REJECT; else { -#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP +#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP keycheck = libssh2_knownhost_checkp(sshc->kh, conn->host.name, (conn->remote_port != PORT_SSH)? @@ -512,7 +512,7 @@ static CURLcode ssh_knownhost(struct connectdata *conn) LIBSSH2_KNOWNHOST_KEYENC_RAW| keybit, &host); -#else +#else keycheck = libssh2_knownhost_check(sshc->kh, conn->host.name, remotekey, keylen, @@ -520,12 +520,12 @@ static CURLcode ssh_knownhost(struct connectdata *conn) LIBSSH2_KNOWNHOST_KEYENC_RAW| keybit, &host); -#endif - +#endif + infof(data, "SSH host check: %d, key: %s\n", keycheck, (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? host->key:"<none>"); - + /* setup 'knownkey' */ if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { knownkey.key = host->key; @@ -539,15 +539,15 @@ static CURLcode ssh_knownhost(struct connectdata *conn) foundkey.key = remotekey; foundkey.len = keylen; foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? - CURLKHTYPE_RSA : CURLKHTYPE_DSS; - + CURLKHTYPE_RSA : CURLKHTYPE_DSS; + /* * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the * curl_khmatch enum are ever modified, we need to introduce a * translation table here! */ keymatch = (enum curl_khmatch)keycheck; - + /* Ask the callback how to behave */ Curl_set_in_callback(data, true); rc = func(data, knownkeyp, /* from the knownhosts file */ @@ -555,107 +555,107 @@ static CURLcode ssh_knownhost(struct connectdata *conn) keymatch, data->set.ssh_keyfunc_userp); Curl_set_in_callback(data, false); } - } - else - /* no remotekey means failure! */ - rc = CURLKHSTAT_REJECT; - - switch(rc) { - default: /* unknown return codes will equal reject */ - /* FALLTHROUGH */ - case CURLKHSTAT_REJECT: - state(conn, SSH_SESSION_FREE); - /* FALLTHROUGH */ - case CURLKHSTAT_DEFER: - /* DEFER means bail out but keep the SSH_HOSTKEY state */ - result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; - break; + } + else + /* no remotekey means failure! */ + rc = CURLKHSTAT_REJECT; + + switch(rc) { + default: /* unknown return codes will equal reject */ + /* FALLTHROUGH */ + case CURLKHSTAT_REJECT: + state(conn, SSH_SESSION_FREE); + /* FALLTHROUGH */ + case CURLKHSTAT_DEFER: + /* DEFER means bail out but keep the SSH_HOSTKEY state */ + result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; + break; case CURLKHSTAT_FINE_REPLACE: /* remove old host+key that doesn't match */ if(host) libssh2_knownhost_del(sshc->kh, host); /*FALLTHROUGH*/ - case CURLKHSTAT_FINE: + case CURLKHSTAT_FINE: /*FALLTHROUGH*/ - case CURLKHSTAT_FINE_ADD_TO_FILE: - /* proceed */ - if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) { - /* the found host+key didn't match but has been told to be fine - anyway so we add it in memory */ - int addrc = libssh2_knownhost_add(sshc->kh, - conn->host.name, NULL, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, NULL); - if(addrc) - infof(data, "Warning adding the known host %s failed!\n", - conn->host.name); + case CURLKHSTAT_FINE_ADD_TO_FILE: + /* proceed */ + if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) { + /* the found host+key didn't match but has been told to be fine + anyway so we add it in memory */ + int addrc = libssh2_knownhost_add(sshc->kh, + conn->host.name, NULL, + remotekey, keylen, + LIBSSH2_KNOWNHOST_TYPE_PLAIN| + LIBSSH2_KNOWNHOST_KEYENC_RAW| + keybit, NULL); + if(addrc) + infof(data, "Warning adding the known host %s failed!\n", + conn->host.name); else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE || rc == CURLKHSTAT_FINE_REPLACE) { - /* now we write the entire in-memory list of known hosts to the - known_hosts file */ - int wrc = - libssh2_knownhost_writefile(sshc->kh, - data->set.str[STRING_SSH_KNOWNHOSTS], - LIBSSH2_KNOWNHOST_FILE_OPENSSH); - if(wrc) { - infof(data, "Warning, writing %s failed!\n", - data->set.str[STRING_SSH_KNOWNHOSTS]); - } - } - } - break; - } - } -#else /* HAVE_LIBSSH2_KNOWNHOST_API */ - (void)conn; -#endif - return result; -} - -static CURLcode ssh_check_fingerprint(struct connectdata *conn) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - struct Curl_easy *data = conn->data; - const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; - char md5buffer[33]; - - const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session, - LIBSSH2_HOSTKEY_HASH_MD5); - - if(fingerprint) { - /* The fingerprint points to static storage (!), don't free() it. */ - int i; - for(i = 0; i < 16; i++) - msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]); - infof(data, "SSH MD5 fingerprint: %s\n", md5buffer); - } - - /* Before we authenticate we check the hostkey's MD5 fingerprint - * against a known fingerprint, if available. - */ - if(pubkey_md5 && strlen(pubkey_md5) == 32) { - if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) { - if(fingerprint) - failf(data, - "Denied establishing ssh session: mismatch md5 fingerprint. " - "Remote %s is not equal to %s", md5buffer, pubkey_md5); - else - failf(data, - "Denied establishing ssh session: md5 fingerprint not available"); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; - return sshc->actualcode; - } - infof(data, "MD5 checksum match!\n"); - /* as we already matched, we skip the check for known hosts */ - return CURLE_OK; - } - return ssh_knownhost(conn); -} - -/* + /* now we write the entire in-memory list of known hosts to the + known_hosts file */ + int wrc = + libssh2_knownhost_writefile(sshc->kh, + data->set.str[STRING_SSH_KNOWNHOSTS], + LIBSSH2_KNOWNHOST_FILE_OPENSSH); + if(wrc) { + infof(data, "Warning, writing %s failed!\n", + data->set.str[STRING_SSH_KNOWNHOSTS]); + } + } + } + break; + } + } +#else /* HAVE_LIBSSH2_KNOWNHOST_API */ + (void)conn; +#endif + return result; +} + +static CURLcode ssh_check_fingerprint(struct connectdata *conn) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + struct Curl_easy *data = conn->data; + const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; + char md5buffer[33]; + + const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session, + LIBSSH2_HOSTKEY_HASH_MD5); + + if(fingerprint) { + /* The fingerprint points to static storage (!), don't free() it. */ + int i; + for(i = 0; i < 16; i++) + msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]); + infof(data, "SSH MD5 fingerprint: %s\n", md5buffer); + } + + /* Before we authenticate we check the hostkey's MD5 fingerprint + * against a known fingerprint, if available. + */ + if(pubkey_md5 && strlen(pubkey_md5) == 32) { + if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) { + if(fingerprint) + failf(data, + "Denied establishing ssh session: mismatch md5 fingerprint. " + "Remote %s is not equal to %s", md5buffer, pubkey_md5); + else + failf(data, + "Denied establishing ssh session: md5 fingerprint not available"); + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; + return sshc->actualcode; + } + infof(data, "MD5 checksum match!\n"); + /* as we already matched, we skip the check for known hosts */ + return CURLE_OK; + } + return ssh_knownhost(conn); +} + +/* * ssh_force_knownhost_key_type() will check the known hosts file and try to * force a specific public key type from the server if an entry is found. */ @@ -788,38 +788,38 @@ static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn) } /* - * ssh_statemach_act() runs the SSH state machine as far as it can without - * blocking and without reaching the end. The data the pointer 'block' points - * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN - * meaning it wants to be called again when the socket is ready - */ - -static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) -{ - CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; + * ssh_statemach_act() runs the SSH state machine as far as it can without + * blocking and without reaching the end. The data the pointer 'block' points + * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN + * meaning it wants to be called again when the socket is ready + */ + +static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; struct SSHPROTO *sftp_scp = data->req.p.ssh; - struct ssh_conn *sshc = &conn->proto.sshc; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int rc = LIBSSH2_ERROR_NONE; + struct ssh_conn *sshc = &conn->proto.sshc; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + int rc = LIBSSH2_ERROR_NONE; int ssherr; unsigned long sftperr; - int seekerr = CURL_SEEKFUNC_OK; + int seekerr = CURL_SEEKFUNC_OK; size_t readdir_len; - *block = 0; /* we're not blocking by default */ - - do { - - switch(sshc->state) { - case SSH_INIT: - sshc->secondCreateDirs = 0; - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_OK; - - /* Set libssh2 to non-blocking, since everything internally is - non-blocking */ - libssh2_session_set_blocking(sshc->ssh_session, 0); - + *block = 0; /* we're not blocking by default */ + + do { + + switch(sshc->state) { + case SSH_INIT: + sshc->secondCreateDirs = 0; + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_OK; + + /* Set libssh2 to non-blocking, since everything internally is + non-blocking */ + libssh2_session_set_blocking(sshc->ssh_session, 0); + result = ssh_force_knownhost_key_type(conn); if(result) { state(conn, SSH_SESSION_FREE); @@ -827,777 +827,777 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } - state(conn, SSH_S_STARTUP); - /* FALLTHROUGH */ - - case SSH_S_STARTUP: - rc = libssh2_session_startup(sshc->ssh_session, (int)sock); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg); - - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_FAILED_INIT; - break; - } - - state(conn, SSH_HOSTKEY); - - /* FALLTHROUGH */ - case SSH_HOSTKEY: - /* - * Before we authenticate we should check the hostkey's fingerprint - * against our known hosts. How that is handled (reading from file, - * whatever) is up to us. - */ - result = ssh_check_fingerprint(conn); - if(!result) - state(conn, SSH_AUTHLIST); - /* ssh_check_fingerprint sets state appropriately on error */ - break; - - case SSH_AUTHLIST: - /* - * Figure out authentication methods - * NB: As soon as we have provided a username to an openssh server we - * must never change it later. Thus, always specify the correct username - * here, even though the libssh2 docs kind of indicate that it should be - * possible to get a 'generic' list (not user-specific) of authentication - * methods, presumably with a blank username. That won't work in my - * experience. - * So always specify it here. - */ - sshc->authlist = libssh2_userauth_list(sshc->ssh_session, - conn->user, - curlx_uztoui(strlen(conn->user))); - - if(!sshc->authlist) { - if(libssh2_userauth_authenticated(sshc->ssh_session)) { - sshc->authed = TRUE; - infof(data, "SSH user accepted with no authentication\n"); - state(conn, SSH_AUTH_DONE); - break; - } + state(conn, SSH_S_STARTUP); + /* FALLTHROUGH */ + + case SSH_S_STARTUP: + rc = libssh2_session_startup(sshc->ssh_session, (int)sock); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); + failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg); + + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_FAILED_INIT; + break; + } + + state(conn, SSH_HOSTKEY); + + /* FALLTHROUGH */ + case SSH_HOSTKEY: + /* + * Before we authenticate we should check the hostkey's fingerprint + * against our known hosts. How that is handled (reading from file, + * whatever) is up to us. + */ + result = ssh_check_fingerprint(conn); + if(!result) + state(conn, SSH_AUTHLIST); + /* ssh_check_fingerprint sets state appropriately on error */ + break; + + case SSH_AUTHLIST: + /* + * Figure out authentication methods + * NB: As soon as we have provided a username to an openssh server we + * must never change it later. Thus, always specify the correct username + * here, even though the libssh2 docs kind of indicate that it should be + * possible to get a 'generic' list (not user-specific) of authentication + * methods, presumably with a blank username. That won't work in my + * experience. + * So always specify it here. + */ + sshc->authlist = libssh2_userauth_list(sshc->ssh_session, + conn->user, + curlx_uztoui(strlen(conn->user))); + + if(!sshc->authlist) { + if(libssh2_userauth_authenticated(sshc->ssh_session)) { + sshc->authed = TRUE; + infof(data, "SSH user accepted with no authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } ssherr = libssh2_session_last_errno(sshc->ssh_session); if(ssherr == LIBSSH2_ERROR_EAGAIN) - rc = LIBSSH2_ERROR_EAGAIN; - else { - state(conn, SSH_SESSION_FREE); + rc = LIBSSH2_ERROR_EAGAIN; + else { + state(conn, SSH_SESSION_FREE); sshc->actualcode = libssh2_session_error_to_CURLE(ssherr); - } - break; - } - infof(data, "SSH authentication methods available: %s\n", - sshc->authlist); - - state(conn, SSH_AUTH_PKEY_INIT); - break; - - case SSH_AUTH_PKEY_INIT: - /* - * Check the supported auth types in the order I feel is most secure - * with the requested type of authentication - */ - sshc->authed = FALSE; - - if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) && - (strstr(sshc->authlist, "publickey") != NULL)) { - bool out_of_memory = FALSE; - - sshc->rsa_pub = sshc->rsa = NULL; - - if(data->set.str[STRING_SSH_PRIVATE_KEY]) - sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]); - else { - /* To ponder about: should really the lib be messing about with the - HOME environment variable etc? */ - char *home = curl_getenv("HOME"); - - /* If no private key file is specified, try some common paths. */ - if(home) { - /* Try ~/.ssh first. */ - sshc->rsa = aprintf("%s/.ssh/id_rsa", home); - if(!sshc->rsa) - out_of_memory = TRUE; - else if(access(sshc->rsa, R_OK) != 0) { - Curl_safefree(sshc->rsa); - sshc->rsa = aprintf("%s/.ssh/id_dsa", home); - if(!sshc->rsa) - out_of_memory = TRUE; - else if(access(sshc->rsa, R_OK) != 0) { - Curl_safefree(sshc->rsa); - } - } - free(home); - } - if(!out_of_memory && !sshc->rsa) { - /* Nothing found; try the current dir. */ - sshc->rsa = strdup("id_rsa"); - if(sshc->rsa && access(sshc->rsa, R_OK) != 0) { - Curl_safefree(sshc->rsa); - sshc->rsa = strdup("id_dsa"); - if(sshc->rsa && access(sshc->rsa, R_OK) != 0) { - Curl_safefree(sshc->rsa); - /* Out of guesses. Set to the empty string to avoid - * surprising info messages. */ - sshc->rsa = strdup(""); - } - } - } - } - - /* - * Unless the user explicitly specifies a public key file, let - * libssh2 extract the public key from the private key file. - * This is done by simply passing sshc->rsa_pub = NULL. - */ - if(data->set.str[STRING_SSH_PUBLIC_KEY] - /* treat empty string the same way as NULL */ - && data->set.str[STRING_SSH_PUBLIC_KEY][0]) { - sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]); - if(!sshc->rsa_pub) - out_of_memory = TRUE; - } - - if(out_of_memory || sshc->rsa == NULL) { - Curl_safefree(sshc->rsa); - Curl_safefree(sshc->rsa_pub); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - - sshc->passphrase = data->set.ssl.key_passwd; - if(!sshc->passphrase) - sshc->passphrase = ""; - - if(sshc->rsa_pub) - infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub); - infof(data, "Using SSH private key file '%s'\n", sshc->rsa); - - state(conn, SSH_AUTH_PKEY); - } - else { - state(conn, SSH_AUTH_PASS_INIT); - } - break; - - case SSH_AUTH_PKEY: - /* The function below checks if the files exists, no need to stat() here. - */ - rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session, - conn->user, - curlx_uztoui( - strlen(conn->user)), - sshc->rsa_pub, - sshc->rsa, sshc->passphrase); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - - Curl_safefree(sshc->rsa_pub); - Curl_safefree(sshc->rsa); - - if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized SSH public key authentication\n"); - state(conn, SSH_AUTH_DONE); - } - else { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "SSH public key authentication failed: %s\n", err_msg); - state(conn, SSH_AUTH_PASS_INIT); - rc = 0; /* clear rc and continue */ - } - break; - - case SSH_AUTH_PASS_INIT: - if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) && - (strstr(sshc->authlist, "password") != NULL)) { - state(conn, SSH_AUTH_PASS); - } - else { - state(conn, SSH_AUTH_HOST_INIT); - rc = 0; /* clear rc and continue */ - } - break; - - case SSH_AUTH_PASS: - rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user, - curlx_uztoui(strlen(conn->user)), - conn->passwd, - curlx_uztoui(strlen(conn->passwd)), - NULL); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized password authentication\n"); - state(conn, SSH_AUTH_DONE); - } - else { - state(conn, SSH_AUTH_HOST_INIT); - rc = 0; /* clear rc and continue */ - } - break; - - case SSH_AUTH_HOST_INIT: - if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) && - (strstr(sshc->authlist, "hostbased") != NULL)) { - state(conn, SSH_AUTH_HOST); - } - else { - state(conn, SSH_AUTH_AGENT_INIT); - } - break; - - case SSH_AUTH_HOST: - state(conn, SSH_AUTH_AGENT_INIT); - break; - - case SSH_AUTH_AGENT_INIT: -#ifdef HAVE_LIBSSH2_AGENT_API - if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT) - && (strstr(sshc->authlist, "publickey") != NULL)) { - - /* Connect to the ssh-agent */ - /* The agent could be shared by a curl thread i believe - but nothing obvious as keys can be added/removed at any time */ - if(!sshc->ssh_agent) { - sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session); - if(!sshc->ssh_agent) { - infof(data, "Could not create agent object\n"); - - state(conn, SSH_AUTH_KEY_INIT); - break; - } - } - - rc = libssh2_agent_connect(sshc->ssh_agent); - if(rc == LIBSSH2_ERROR_EAGAIN) - break; - if(rc < 0) { - infof(data, "Failure connecting to agent\n"); - state(conn, SSH_AUTH_KEY_INIT); - rc = 0; /* clear rc and continue */ - } - else { - state(conn, SSH_AUTH_AGENT_LIST); - } - } - else -#endif /* HAVE_LIBSSH2_AGENT_API */ - state(conn, SSH_AUTH_KEY_INIT); - break; - - case SSH_AUTH_AGENT_LIST: -#ifdef HAVE_LIBSSH2_AGENT_API - rc = libssh2_agent_list_identities(sshc->ssh_agent); - - if(rc == LIBSSH2_ERROR_EAGAIN) - break; - if(rc < 0) { - infof(data, "Failure requesting identities to agent\n"); - state(conn, SSH_AUTH_KEY_INIT); - rc = 0; /* clear rc and continue */ - } - else { - state(conn, SSH_AUTH_AGENT); - sshc->sshagent_prev_identity = NULL; - } -#endif - break; - - case SSH_AUTH_AGENT: -#ifdef HAVE_LIBSSH2_AGENT_API - /* as prev_identity evolves only after an identity user auth finished we - can safely request it again as long as EAGAIN is returned here or by - libssh2_agent_userauth */ - rc = libssh2_agent_get_identity(sshc->ssh_agent, - &sshc->sshagent_identity, - sshc->sshagent_prev_identity); - if(rc == LIBSSH2_ERROR_EAGAIN) - break; - - if(rc == 0) { - rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user, - sshc->sshagent_identity); - - if(rc < 0) { - if(rc != LIBSSH2_ERROR_EAGAIN) { - /* tried and failed? go to next identity */ - sshc->sshagent_prev_identity = sshc->sshagent_identity; - } - break; - } - } - - if(rc < 0) - infof(data, "Failure requesting identities to agent\n"); - else if(rc == 1) - infof(data, "No identity would match\n"); - - if(rc == LIBSSH2_ERROR_NONE) { - sshc->authed = TRUE; - infof(data, "Agent based authentication successful\n"); - state(conn, SSH_AUTH_DONE); - } - else { - state(conn, SSH_AUTH_KEY_INIT); - rc = 0; /* clear rc and continue */ - } -#endif - break; - - case SSH_AUTH_KEY_INIT: - if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) - && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) { - state(conn, SSH_AUTH_KEY); - } - else { - state(conn, SSH_AUTH_DONE); - } - break; - - case SSH_AUTH_KEY: - /* Authentication failed. Continue with keyboard-interactive now. */ - rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session, - conn->user, - curlx_uztoui( - strlen(conn->user)), - &kbd_callback); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized keyboard interactive authentication\n"); - } - state(conn, SSH_AUTH_DONE); - break; - - case SSH_AUTH_DONE: - if(!sshc->authed) { - failf(data, "Authentication failure"); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_LOGIN_DENIED; - break; - } - - /* - * At this point we have an authenticated ssh session. - */ - infof(data, "Authentication complete\n"); - - Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ - - conn->sockfd = sock; - conn->writesockfd = CURL_SOCKET_BAD; - - if(conn->handler->protocol == CURLPROTO_SFTP) { - state(conn, SSH_SFTP_INIT); - break; - } - infof(data, "SSH CONNECT phase done\n"); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_INIT: - /* - * Start the libssh2 sftp session - */ - sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session); - if(!sshc->sftp_session) { - char *err_msg = NULL; - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - failf(data, "Failure initializing sftp session: %s", err_msg); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_FAILED_INIT; - break; - } - state(conn, SSH_SFTP_REALPATH); - break; - - case SSH_SFTP_REALPATH: - { - char tempHome[PATH_MAX]; - - /* - * Get the "home" directory - */ - rc = sftp_libssh2_realpath(sshc->sftp_session, ".", - tempHome, PATH_MAX-1); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc > 0) { - /* It seems that this string is not always NULL terminated */ - tempHome[rc] = '\0'; - sshc->homedir = strdup(tempHome); - if(!sshc->homedir) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - conn->data->state.most_recent_ftp_entrypath = sshc->homedir; - } - else { - /* Return the error type */ + } + break; + } + infof(data, "SSH authentication methods available: %s\n", + sshc->authlist); + + state(conn, SSH_AUTH_PKEY_INIT); + break; + + case SSH_AUTH_PKEY_INIT: + /* + * Check the supported auth types in the order I feel is most secure + * with the requested type of authentication + */ + sshc->authed = FALSE; + + if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) && + (strstr(sshc->authlist, "publickey") != NULL)) { + bool out_of_memory = FALSE; + + sshc->rsa_pub = sshc->rsa = NULL; + + if(data->set.str[STRING_SSH_PRIVATE_KEY]) + sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]); + else { + /* To ponder about: should really the lib be messing about with the + HOME environment variable etc? */ + char *home = curl_getenv("HOME"); + + /* If no private key file is specified, try some common paths. */ + if(home) { + /* Try ~/.ssh first. */ + sshc->rsa = aprintf("%s/.ssh/id_rsa", home); + if(!sshc->rsa) + out_of_memory = TRUE; + else if(access(sshc->rsa, R_OK) != 0) { + Curl_safefree(sshc->rsa); + sshc->rsa = aprintf("%s/.ssh/id_dsa", home); + if(!sshc->rsa) + out_of_memory = TRUE; + else if(access(sshc->rsa, R_OK) != 0) { + Curl_safefree(sshc->rsa); + } + } + free(home); + } + if(!out_of_memory && !sshc->rsa) { + /* Nothing found; try the current dir. */ + sshc->rsa = strdup("id_rsa"); + if(sshc->rsa && access(sshc->rsa, R_OK) != 0) { + Curl_safefree(sshc->rsa); + sshc->rsa = strdup("id_dsa"); + if(sshc->rsa && access(sshc->rsa, R_OK) != 0) { + Curl_safefree(sshc->rsa); + /* Out of guesses. Set to the empty string to avoid + * surprising info messages. */ + sshc->rsa = strdup(""); + } + } + } + } + + /* + * Unless the user explicitly specifies a public key file, let + * libssh2 extract the public key from the private key file. + * This is done by simply passing sshc->rsa_pub = NULL. + */ + if(data->set.str[STRING_SSH_PUBLIC_KEY] + /* treat empty string the same way as NULL */ + && data->set.str[STRING_SSH_PUBLIC_KEY][0]) { + sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]); + if(!sshc->rsa_pub) + out_of_memory = TRUE; + } + + if(out_of_memory || sshc->rsa == NULL) { + Curl_safefree(sshc->rsa); + Curl_safefree(sshc->rsa_pub); + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + sshc->passphrase = data->set.ssl.key_passwd; + if(!sshc->passphrase) + sshc->passphrase = ""; + + if(sshc->rsa_pub) + infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub); + infof(data, "Using SSH private key file '%s'\n", sshc->rsa); + + state(conn, SSH_AUTH_PKEY); + } + else { + state(conn, SSH_AUTH_PASS_INIT); + } + break; + + case SSH_AUTH_PKEY: + /* The function below checks if the files exists, no need to stat() here. + */ + rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session, + conn->user, + curlx_uztoui( + strlen(conn->user)), + sshc->rsa_pub, + sshc->rsa, sshc->passphrase); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + + Curl_safefree(sshc->rsa_pub); + Curl_safefree(sshc->rsa); + + if(rc == 0) { + sshc->authed = TRUE; + infof(data, "Initialized SSH public key authentication\n"); + state(conn, SSH_AUTH_DONE); + } + else { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "SSH public key authentication failed: %s\n", err_msg); + state(conn, SSH_AUTH_PASS_INIT); + rc = 0; /* clear rc and continue */ + } + break; + + case SSH_AUTH_PASS_INIT: + if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) && + (strstr(sshc->authlist, "password") != NULL)) { + state(conn, SSH_AUTH_PASS); + } + else { + state(conn, SSH_AUTH_HOST_INIT); + rc = 0; /* clear rc and continue */ + } + break; + + case SSH_AUTH_PASS: + rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user, + curlx_uztoui(strlen(conn->user)), + conn->passwd, + curlx_uztoui(strlen(conn->passwd)), + NULL); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc == 0) { + sshc->authed = TRUE; + infof(data, "Initialized password authentication\n"); + state(conn, SSH_AUTH_DONE); + } + else { + state(conn, SSH_AUTH_HOST_INIT); + rc = 0; /* clear rc and continue */ + } + break; + + case SSH_AUTH_HOST_INIT: + if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) && + (strstr(sshc->authlist, "hostbased") != NULL)) { + state(conn, SSH_AUTH_HOST); + } + else { + state(conn, SSH_AUTH_AGENT_INIT); + } + break; + + case SSH_AUTH_HOST: + state(conn, SSH_AUTH_AGENT_INIT); + break; + + case SSH_AUTH_AGENT_INIT: +#ifdef HAVE_LIBSSH2_AGENT_API + if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT) + && (strstr(sshc->authlist, "publickey") != NULL)) { + + /* Connect to the ssh-agent */ + /* The agent could be shared by a curl thread i believe + but nothing obvious as keys can be added/removed at any time */ + if(!sshc->ssh_agent) { + sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session); + if(!sshc->ssh_agent) { + infof(data, "Could not create agent object\n"); + + state(conn, SSH_AUTH_KEY_INIT); + break; + } + } + + rc = libssh2_agent_connect(sshc->ssh_agent); + if(rc == LIBSSH2_ERROR_EAGAIN) + break; + if(rc < 0) { + infof(data, "Failure connecting to agent\n"); + state(conn, SSH_AUTH_KEY_INIT); + rc = 0; /* clear rc and continue */ + } + else { + state(conn, SSH_AUTH_AGENT_LIST); + } + } + else +#endif /* HAVE_LIBSSH2_AGENT_API */ + state(conn, SSH_AUTH_KEY_INIT); + break; + + case SSH_AUTH_AGENT_LIST: +#ifdef HAVE_LIBSSH2_AGENT_API + rc = libssh2_agent_list_identities(sshc->ssh_agent); + + if(rc == LIBSSH2_ERROR_EAGAIN) + break; + if(rc < 0) { + infof(data, "Failure requesting identities to agent\n"); + state(conn, SSH_AUTH_KEY_INIT); + rc = 0; /* clear rc and continue */ + } + else { + state(conn, SSH_AUTH_AGENT); + sshc->sshagent_prev_identity = NULL; + } +#endif + break; + + case SSH_AUTH_AGENT: +#ifdef HAVE_LIBSSH2_AGENT_API + /* as prev_identity evolves only after an identity user auth finished we + can safely request it again as long as EAGAIN is returned here or by + libssh2_agent_userauth */ + rc = libssh2_agent_get_identity(sshc->ssh_agent, + &sshc->sshagent_identity, + sshc->sshagent_prev_identity); + if(rc == LIBSSH2_ERROR_EAGAIN) + break; + + if(rc == 0) { + rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user, + sshc->sshagent_identity); + + if(rc < 0) { + if(rc != LIBSSH2_ERROR_EAGAIN) { + /* tried and failed? go to next identity */ + sshc->sshagent_prev_identity = sshc->sshagent_identity; + } + break; + } + } + + if(rc < 0) + infof(data, "Failure requesting identities to agent\n"); + else if(rc == 1) + infof(data, "No identity would match\n"); + + if(rc == LIBSSH2_ERROR_NONE) { + sshc->authed = TRUE; + infof(data, "Agent based authentication successful\n"); + state(conn, SSH_AUTH_DONE); + } + else { + state(conn, SSH_AUTH_KEY_INIT); + rc = 0; /* clear rc and continue */ + } +#endif + break; + + case SSH_AUTH_KEY_INIT: + if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) + && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) { + state(conn, SSH_AUTH_KEY); + } + else { + state(conn, SSH_AUTH_DONE); + } + break; + + case SSH_AUTH_KEY: + /* Authentication failed. Continue with keyboard-interactive now. */ + rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session, + conn->user, + curlx_uztoui( + strlen(conn->user)), + &kbd_callback); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc == 0) { + sshc->authed = TRUE; + infof(data, "Initialized keyboard interactive authentication\n"); + } + state(conn, SSH_AUTH_DONE); + break; + + case SSH_AUTH_DONE: + if(!sshc->authed) { + failf(data, "Authentication failure"); + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_LOGIN_DENIED; + break; + } + + /* + * At this point we have an authenticated ssh session. + */ + infof(data, "Authentication complete\n"); + + Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ + + conn->sockfd = sock; + conn->writesockfd = CURL_SOCKET_BAD; + + if(conn->handler->protocol == CURLPROTO_SFTP) { + state(conn, SSH_SFTP_INIT); + break; + } + infof(data, "SSH CONNECT phase done\n"); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_INIT: + /* + * Start the libssh2 sftp session + */ + sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session); + if(!sshc->sftp_session) { + char *err_msg = NULL; + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + failf(data, "Failure initializing sftp session: %s", err_msg); + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_FAILED_INIT; + break; + } + state(conn, SSH_SFTP_REALPATH); + break; + + case SSH_SFTP_REALPATH: + { + char tempHome[PATH_MAX]; + + /* + * Get the "home" directory + */ + rc = sftp_libssh2_realpath(sshc->sftp_session, ".", + tempHome, PATH_MAX-1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc > 0) { + /* It seems that this string is not always NULL terminated */ + tempHome[rc] = '\0'; + sshc->homedir = strdup(tempHome); + if(!sshc->homedir) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + conn->data->state.most_recent_ftp_entrypath = sshc->homedir; + } + else { + /* Return the error type */ sftperr = libssh2_sftp_last_error(sshc->sftp_session); if(sftperr) result = sftp_libssh2_error_to_CURLE(sftperr); - else - /* in this case, the error wasn't in the SFTP level but for example - a time-out or similar */ - result = CURLE_SSH; - sshc->actualcode = result; + else + /* in this case, the error wasn't in the SFTP level but for example + a time-out or similar */ + result = CURLE_SSH; + sshc->actualcode = result; DEBUGF(infof(data, "error = %lu makes libcurl = %d\n", sftperr, (int)result)); - state(conn, SSH_STOP); - break; - } - } - /* This is the last step in the SFTP connect phase. Do note that while - we get the homedir here, we get the "workingpath" in the DO action - since the homedir will remain the same between request but the - working path will not. */ - DEBUGF(infof(data, "SSH CONNECT phase done\n")); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_QUOTE_INIT: - - result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); - if(result) { - sshc->actualcode = result; - state(conn, SSH_STOP); - break; - } - - if(data->set.quote) { - infof(data, "Sending quote commands\n"); - sshc->quote_item = data->set.quote; - state(conn, SSH_SFTP_QUOTE); - } - else { - state(conn, SSH_SFTP_GETINFO); - } - break; - - case SSH_SFTP_POSTQUOTE_INIT: - if(data->set.postquote) { - infof(data, "Sending quote commands\n"); - sshc->quote_item = data->set.postquote; - state(conn, SSH_SFTP_QUOTE); - } - else { - state(conn, SSH_STOP); - } - break; - - case SSH_SFTP_QUOTE: - /* Send any quote commands */ - { - const char *cp; - - /* - * Support some of the "FTP" commands - * - * 'sshc->quote_item' is already verified to be non-NULL before it - * switched to this state. - */ - char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - if(strcasecompare("pwd", cmd)) { - /* output debug output if that is requested */ - char *tmp = aprintf("257 \"%s\" is current directory.\n", - sftp_scp->path); - if(!tmp) { - result = CURLE_OUT_OF_MEMORY; - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - break; - } + state(conn, SSH_STOP); + break; + } + } + /* This is the last step in the SFTP connect phase. Do note that while + we get the homedir here, we get the "workingpath" in the DO action + since the homedir will remain the same between request but the + working path will not. */ + DEBUGF(infof(data, "SSH CONNECT phase done\n")); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_QUOTE_INIT: + + result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + if(data->set.quote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.quote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_SFTP_GETINFO); + } + break; + + case SSH_SFTP_POSTQUOTE_INIT: + if(data->set.postquote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.postquote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_QUOTE: + /* Send any quote commands */ + { + const char *cp; + + /* + * Support some of the "FTP" commands + * + * 'sshc->quote_item' is already verified to be non-NULL before it + * switched to this state. + */ + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + if(strcasecompare("pwd", cmd)) { + /* output debug output if that is requested */ + char *tmp = aprintf("257 \"%s\" is current directory.\n", + sftp_scp->path); + if(!tmp) { + result = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + break; + } Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4); Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp)); - /* this sends an FTP-like "header" to the header callback so that the - current directory can be read very similar to how it is read when - using ordinary FTP. */ - result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - free(tmp); - if(result) { - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - else - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - } - { - /* - * the arguments following the command must be separated from the - * command with a space so we can check for it unconditionally - */ - cp = strchr(cmd, ' '); - if(cp == NULL) { + /* this sends an FTP-like "header" to the header callback so that the + current directory can be read very similar to how it is read when + using ordinary FTP. */ + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + else + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + } + { + /* + * the arguments following the command must be separated from the + * command with a space so we can check for it unconditionally + */ + cp = strchr(cmd, ' '); + if(cp == NULL) { failf(data, "Syntax error command '%s'. Missing parameter!", cmd); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - - /* - * also, every command takes at least one argument so we get that - * first argument right now - */ - result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + + /* + * also, every command takes at least one argument so we get that + * first argument right now + */ + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else failf(data, "Syntax error: Bad first parameter to '%s'", cmd); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - - /* - * SFTP is a binary protocol, so we don't send text commands - * to the server. Instead, we scan for commands used by - * OpenSSH's sftp program and call the appropriate libssh2 - * functions. - */ - if(strncasecompare(cmd, "chgrp ", 6) || - strncasecompare(cmd, "chmod ", 6) || + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + + /* + * SFTP is a binary protocol, so we don't send text commands + * to the server. Instead, we scan for commands used by + * OpenSSH's sftp program and call the appropriate libssh2 + * functions. + */ + if(strncasecompare(cmd, "chgrp ", 6) || + strncasecompare(cmd, "chmod ", 6) || strncasecompare(cmd, "chown ", 6) || strncasecompare(cmd, "atime ", 6) || strncasecompare(cmd, "mtime ", 6)) { - /* attribute change */ - - /* sshc->quote_path1 contains the mode to set */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else + /* attribute change */ + + /* sshc->quote_path1 contains the mode to set */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else failf(data, "Syntax error in %s: Bad second parameter", cmd); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); - state(conn, SSH_SFTP_QUOTE_STAT); - break; - } - if(strncasecompare(cmd, "ln ", 3) || - strncasecompare(cmd, "symlink ", 8)) { - /* symbolic linking */ - /* sshc->quote_path1 is the source */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, - "Syntax error in ln/symlink: Bad second parameter"); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - state(conn, SSH_SFTP_QUOTE_SYMLINK); - break; - } - else if(strncasecompare(cmd, "mkdir ", 6)) { - /* create dir */ - state(conn, SSH_SFTP_QUOTE_MKDIR); - break; - } - else if(strncasecompare(cmd, "rename ", 7)) { - /* rename file */ - /* first param is the source path */ - /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in rename: Bad second parameter"); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - state(conn, SSH_SFTP_QUOTE_RENAME); - break; - } - else if(strncasecompare(cmd, "rmdir ", 6)) { - /* delete dir */ - state(conn, SSH_SFTP_QUOTE_RMDIR); - break; - } - else if(strncasecompare(cmd, "rm ", 3)) { - state(conn, SSH_SFTP_QUOTE_UNLINK); - break; - } -#ifdef HAS_STATVFS_SUPPORT - else if(strncasecompare(cmd, "statvfs ", 8)) { - state(conn, SSH_SFTP_QUOTE_STATVFS); - break; - } -#endif - - failf(data, "Unknown SFTP command"); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - break; - - case SSH_SFTP_NEXT_QUOTE: - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - - sshc->quote_item = sshc->quote_item->next; - - if(sshc->quote_item) { - state(conn, SSH_SFTP_QUOTE); - } - else { - if(sshc->nextstate != SSH_NO_STATE) { - state(conn, sshc->nextstate); - sshc->nextstate = SSH_NO_STATE; - } - else { - state(conn, SSH_SFTP_GETINFO); - } - } - break; - - case SSH_SFTP_QUOTE_STAT: - { - char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - if(!strncasecompare(cmd, "chmod", 5)) { - /* Since chown and chgrp only set owner OR group but libssh2 wants to - * set them both at once, we need to obtain the current ownership - * first. This takes an extra protocol round trip. - */ - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_STAT, - &sshc->quote_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc != 0 && !sshc->acceptfail) { /* get those attributes */ + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + state(conn, SSH_SFTP_QUOTE_STAT); + break; + } + if(strncasecompare(cmd, "ln ", 3) || + strncasecompare(cmd, "symlink ", 8)) { + /* symbolic linking */ + /* sshc->quote_path1 is the source */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, + "Syntax error in ln/symlink: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + state(conn, SSH_SFTP_QUOTE_SYMLINK); + break; + } + else if(strncasecompare(cmd, "mkdir ", 6)) { + /* create dir */ + state(conn, SSH_SFTP_QUOTE_MKDIR); + break; + } + else if(strncasecompare(cmd, "rename ", 7)) { + /* rename file */ + /* first param is the source path */ + /* second param is the dest. path */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in rename: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + state(conn, SSH_SFTP_QUOTE_RENAME); + break; + } + else if(strncasecompare(cmd, "rmdir ", 6)) { + /* delete dir */ + state(conn, SSH_SFTP_QUOTE_RMDIR); + break; + } + else if(strncasecompare(cmd, "rm ", 3)) { + state(conn, SSH_SFTP_QUOTE_UNLINK); + break; + } +#ifdef HAS_STATVFS_SUPPORT + else if(strncasecompare(cmd, "statvfs ", 8)) { + state(conn, SSH_SFTP_QUOTE_STATVFS); + break; + } +#endif + + failf(data, "Unknown SFTP command"); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + break; + + case SSH_SFTP_NEXT_QUOTE: + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + sshc->quote_item = sshc->quote_item->next; + + if(sshc->quote_item) { + state(conn, SSH_SFTP_QUOTE); + } + else { + if(sshc->nextstate != SSH_NO_STATE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_NO_STATE; + } + else { + state(conn, SSH_SFTP_GETINFO); + } + } + break; + + case SSH_SFTP_QUOTE_STAT: + { + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + if(!strncasecompare(cmd, "chmod", 5)) { + /* Since chown and chgrp only set owner OR group but libssh2 wants to + * set them both at once, we need to obtain the current ownership + * first. This takes an extra protocol round trip. + */ + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, + curlx_uztoui(strlen(sshc->quote_path2)), + LIBSSH2_SFTP_STAT, + &sshc->quote_attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { /* get those attributes */ sftperr = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Attempt to get SFTP stats failed: %s", + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to get SFTP stats failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - - /* Now set the new attributes... */ - if(strncasecompare(cmd, "chgrp", 5)) { - sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; - if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && - !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chgrp gid not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - else if(strncasecompare(cmd, "chmod", 5)) { - sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; - /* permissions are octal */ - if(sshc->quote_attrs.permissions == 0 && - !ISDIGIT(sshc->quote_path1[0])) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chmod permissions not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - else if(strncasecompare(cmd, "chown", 5)) { - sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; - if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && - !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chown uid not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + + /* Now set the new attributes... */ + if(strncasecompare(cmd, "chgrp", 5)) { + sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; + if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chgrp gid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + else if(strncasecompare(cmd, "chmod", 5)) { + sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; + /* permissions are octal */ + if(sshc->quote_attrs.permissions == 0 && + !ISDIGIT(sshc->quote_path1[0])) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chmod permissions not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + else if(strncasecompare(cmd, "chown", 5)) { + sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; + if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chown uid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } else if(strncasecompare(cmd, "atime", 5)) { time_t date = Curl_getdate_capped(sshc->quote_path1); if(date == -1) { @@ -1626,553 +1626,553 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->quote_attrs.mtime = (unsigned long)date; sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; } - - /* Now send the completed structure... */ - state(conn, SSH_SFTP_QUOTE_SETSTAT); - break; - } - - case SSH_SFTP_QUOTE_SETSTAT: - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_SETSTAT, - &sshc->quote_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc != 0 && !sshc->acceptfail) { + + /* Now send the completed structure... */ + state(conn, SSH_SFTP_QUOTE_SETSTAT); + break; + } + + case SSH_SFTP_QUOTE_SETSTAT: + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, + curlx_uztoui(strlen(sshc->quote_path2)), + LIBSSH2_SFTP_SETSTAT, + &sshc->quote_attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Attempt to set SFTP stats failed: %s", + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to set SFTP stats failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_SYMLINK: - rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_SYMLINK); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc != 0 && !sshc->acceptfail) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_SYMLINK: + rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1)), + sshc->quote_path2, + curlx_uztoui(strlen(sshc->quote_path2)), + LIBSSH2_SFTP_SYMLINK); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "symlink command failed: %s", + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "symlink command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_MKDIR: - rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - data->set.new_directory_perms); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc != 0 && !sshc->acceptfail) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_MKDIR: + rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1)), + data->set.new_directory_perms); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path1); failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_RENAME: - rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_RENAME_OVERWRITE | - LIBSSH2_SFTP_RENAME_ATOMIC | - LIBSSH2_SFTP_RENAME_NATIVE); - - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc != 0 && !sshc->acceptfail) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RENAME: + rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1)), + sshc->quote_path2, + curlx_uztoui(strlen(sshc->quote_path2)), + LIBSSH2_SFTP_RENAME_OVERWRITE | + LIBSSH2_SFTP_RENAME_ATOMIC | + LIBSSH2_SFTP_RENAME_NATIVE); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); failf(data, "rename command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_RMDIR: - rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1))); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc != 0 && !sshc->acceptfail) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RMDIR: + rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1))); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path1); failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_UNLINK: - rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1))); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc != 0 && !sshc->acceptfail) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_UNLINK: + rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1))); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path1); failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - -#ifdef HAS_STATVFS_SUPPORT - case SSH_SFTP_QUOTE_STATVFS: - { - LIBSSH2_SFTP_STATVFS statvfs; - rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - &statvfs); - - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc != 0 && !sshc->acceptfail) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + +#ifdef HAS_STATVFS_SUPPORT + case SSH_SFTP_QUOTE_STATVFS: + { + LIBSSH2_SFTP_STATVFS statvfs; + rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1)), + &statvfs); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path1); failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - else if(rc == 0) { - char *tmp = aprintf("statvfs:\n" - "f_bsize: %llu\n" "f_frsize: %llu\n" - "f_blocks: %llu\n" "f_bfree: %llu\n" - "f_bavail: %llu\n" "f_files: %llu\n" - "f_ffree: %llu\n" "f_favail: %llu\n" - "f_fsid: %llu\n" "f_flag: %llu\n" - "f_namemax: %llu\n", - statvfs.f_bsize, statvfs.f_frsize, - statvfs.f_blocks, statvfs.f_bfree, - statvfs.f_bavail, statvfs.f_files, - statvfs.f_ffree, statvfs.f_favail, - statvfs.f_fsid, statvfs.f_flag, - statvfs.f_namemax); - if(!tmp) { - result = CURLE_OUT_OF_MEMORY; - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - break; - } - - result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - free(tmp); - if(result) { - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - } -#endif - case SSH_SFTP_GETINFO: - { - if(data->set.get_filetime) { - state(conn, SSH_SFTP_FILETIME); - } - else { - state(conn, SSH_SFTP_TRANS_INIT); - } - break; - } - - case SSH_SFTP_FILETIME: - { - LIBSSH2_SFTP_ATTRIBUTES attrs; - - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc == 0) { - data->info.filetime = attrs.mtime; - } - - state(conn, SSH_SFTP_TRANS_INIT); - break; - } - - case SSH_SFTP_TRANS_INIT: - if(data->set.upload) - state(conn, SSH_SFTP_UPLOAD_INIT); - else { - if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/') - state(conn, SSH_SFTP_READDIR_INIT); - else - state(conn, SSH_SFTP_DOWNLOAD_INIT); - } - break; - - case SSH_SFTP_UPLOAD_INIT: - { - unsigned long flags; - /* - * NOTE!!! libssh2 requires that the destination path is a full path - * that includes the destination file and name OR ends in a "/" - * If this is not done the destination file will be named the - * same name as the last directory in the path. - */ - - if(data->state.resume_from != 0) { - LIBSSH2_SFTP_ATTRIBUTES attrs; - if(data->state.resume_from < 0) { - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc) { - data->state.resume_from = 0; - } - else { - curl_off_t size = attrs.filesize; - if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - data->state.resume_from = attrs.filesize; - } - } - } - - if(data->set.ftp_append) - /* Try to open for append, but create if nonexisting */ - flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND; - else if(data->state.resume_from > 0) - /* If we have restart position then open for append */ - flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND; - else - /* Clear file before writing (normal behaviour) */ - flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC; - - sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - flags, data->set.new_file_perms, - LIBSSH2_SFTP_OPENFILE); - - if(!sshc->sftp_handle) { - rc = libssh2_session_last_errno(sshc->ssh_session); - - if(LIBSSH2_ERROR_EAGAIN == rc) - break; - - if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc) - /* only when there was an SFTP protocol error can we extract - the sftp error! */ + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + else if(rc == 0) { + char *tmp = aprintf("statvfs:\n" + "f_bsize: %llu\n" "f_frsize: %llu\n" + "f_blocks: %llu\n" "f_bfree: %llu\n" + "f_bavail: %llu\n" "f_files: %llu\n" + "f_ffree: %llu\n" "f_favail: %llu\n" + "f_fsid: %llu\n" "f_flag: %llu\n" + "f_namemax: %llu\n", + statvfs.f_bsize, statvfs.f_frsize, + statvfs.f_blocks, statvfs.f_bfree, + statvfs.f_bavail, statvfs.f_files, + statvfs.f_ffree, statvfs.f_favail, + statvfs.f_fsid, statvfs.f_flag, + statvfs.f_namemax); + if(!tmp) { + result = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + break; + } + + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + } +#endif + case SSH_SFTP_GETINFO: + { + if(data->set.get_filetime) { + state(conn, SSH_SFTP_FILETIME); + } + else { + state(conn, SSH_SFTP_TRANS_INIT); + } + break; + } + + case SSH_SFTP_FILETIME: + { + LIBSSH2_SFTP_ATTRIBUTES attrs; + + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + LIBSSH2_SFTP_STAT, &attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc == 0) { + data->info.filetime = attrs.mtime; + } + + state(conn, SSH_SFTP_TRANS_INIT); + break; + } + + case SSH_SFTP_TRANS_INIT: + if(data->set.upload) + state(conn, SSH_SFTP_UPLOAD_INIT); + else { + if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/') + state(conn, SSH_SFTP_READDIR_INIT); + else + state(conn, SSH_SFTP_DOWNLOAD_INIT); + } + break; + + case SSH_SFTP_UPLOAD_INIT: + { + unsigned long flags; + /* + * NOTE!!! libssh2 requires that the destination path is a full path + * that includes the destination file and name OR ends in a "/" + * If this is not done the destination file will be named the + * same name as the last directory in the path. + */ + + if(data->state.resume_from != 0) { + LIBSSH2_SFTP_ATTRIBUTES attrs; + if(data->state.resume_from < 0) { + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + LIBSSH2_SFTP_STAT, &attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + data->state.resume_from = 0; + } + else { + curl_off_t size = attrs.filesize; + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + data->state.resume_from = attrs.filesize; + } + } + } + + if(data->set.ftp_append) + /* Try to open for append, but create if nonexisting */ + flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND; + else if(data->state.resume_from > 0) + /* If we have restart position then open for append */ + flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND; + else + /* Clear file before writing (normal behaviour) */ + flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC; + + sshc->sftp_handle = + libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + flags, data->set.new_file_perms, + LIBSSH2_SFTP_OPENFILE); + + if(!sshc->sftp_handle) { + rc = libssh2_session_last_errno(sshc->ssh_session); + + if(LIBSSH2_ERROR_EAGAIN == rc) + break; + + if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc) + /* only when there was an SFTP protocol error can we extract + the sftp error! */ sftperr = libssh2_sftp_last_error(sshc->sftp_session); - else + else sftperr = LIBSSH2_FX_OK; /* not an sftp error at all */ - - if(sshc->secondCreateDirs) { - state(conn, SSH_SFTP_CLOSE); + + if(sshc->secondCreateDirs) { + state(conn, SSH_SFTP_CLOSE); sshc->actualcode = sftperr != LIBSSH2_FX_OK ? sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH; - failf(data, "Creating the dir/file failed: %s", + failf(data, "Creating the dir/file failed: %s", sftp_libssh2_strerror(sftperr)); - break; - } + break; + } if(((sftperr == LIBSSH2_FX_NO_SUCH_FILE) || (sftperr == LIBSSH2_FX_FAILURE) || (sftperr == LIBSSH2_FX_NO_SUCH_PATH)) && - (data->set.ftp_create_missing_dirs && - (strlen(sftp_scp->path) > 1))) { - /* try to create the path remotely */ - rc = 0; /* clear rc and continue */ - sshc->secondCreateDirs = 1; - state(conn, SSH_SFTP_CREATE_DIRS_INIT); - break; - } - state(conn, SSH_SFTP_CLOSE); + (data->set.ftp_create_missing_dirs && + (strlen(sftp_scp->path) > 1))) { + /* try to create the path remotely */ + rc = 0; /* clear rc and continue */ + sshc->secondCreateDirs = 1; + state(conn, SSH_SFTP_CREATE_DIRS_INIT); + break; + } + state(conn, SSH_SFTP_CLOSE); sshc->actualcode = sftperr != LIBSSH2_FX_OK ? sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH; - if(!sshc->actualcode) { + if(!sshc->actualcode) { /* Sometimes, for some reason libssh2_sftp_last_error() returns zero even though libssh2_sftp_open() failed previously! We need to work around that! */ - sshc->actualcode = CURLE_SSH; + sshc->actualcode = CURLE_SSH; sftperr = LIBSSH2_FX_OK; - } + } failf(data, "Upload failed: %s (%lu/%d)", sftperr != LIBSSH2_FX_OK ? sftp_libssh2_strerror(sftperr):"ssh error", sftperr, rc); - break; - } - - /* If we have a restart point then we need to seek to the correct - position. */ - if(data->state.resume_from > 0) { - /* Let's read off the proper amount of bytes from the input. */ - if(conn->seek_func) { - Curl_set_in_callback(data, true); - seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, - SEEK_SET); - Curl_set_in_callback(data, false); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - curl_off_t passed = 0; - - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - return CURLE_FTP_COULDNT_USE_REST; - } - /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ - do { - size_t readthisamountnow = - (data->state.resume_from - passed > data->set.buffer_size) ? - (size_t)data->set.buffer_size : - curlx_sotouz(data->state.resume_from - passed); - - size_t actuallyread; - Curl_set_in_callback(data, true); - actuallyread = data->state.fread_func(data->state.buffer, 1, - readthisamountnow, - data->state.in); - Curl_set_in_callback(data, false); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Failed to read data"); - return CURLE_FTP_COULDNT_USE_REST; - } - } while(passed < data->state.resume_from); - } - - /* now, decrease the size of the read */ - if(data->state.infilesize > 0) { - data->state.infilesize -= data->state.resume_from; - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - - SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); - } - if(data->state.infilesize > 0) { - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - /* upload data */ - Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->sockfd = conn->writesockfd; - - if(result) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = result; - } - else { - /* store this original bitmask setup to use later on if we can't - figure out a "real" bitmask */ - sshc->orig_waitfor = data->req.keepon; - - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh2 sftp send function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_OUT; - - /* since we don't really wait for anything at this point, we want the - state machine to move on as soon as possible so we set a very short - timeout here */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); - - state(conn, SSH_STOP); - } - break; - } - - case SSH_SFTP_CREATE_DIRS_INIT: - if(strlen(sftp_scp->path) > 1) { - sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */ - state(conn, SSH_SFTP_CREATE_DIRS); - } - else { - state(conn, SSH_SFTP_UPLOAD_INIT); - } - break; - - case SSH_SFTP_CREATE_DIRS: - sshc->slash_pos = strchr(sshc->slash_pos, '/'); - if(sshc->slash_pos) { - *sshc->slash_pos = 0; - - infof(data, "Creating directory '%s'\n", sftp_scp->path); - state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); - break; - } - state(conn, SSH_SFTP_UPLOAD_INIT); - break; - - case SSH_SFTP_CREATE_DIRS_MKDIR: - /* 'mode' - parameter is preliminary - default to 0644 */ - rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - data->set.new_directory_perms); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - *sshc->slash_pos = '/'; - ++sshc->slash_pos; - if(rc < 0) { - /* - * Abort if failure wasn't that the dir already exists or the - * permission was denied (creation might succeed further down the - * path) - retry on unspecific FAILURE also - */ + break; + } + + /* If we have a restart point then we need to seek to the correct + position. */ + if(data->state.resume_from > 0) { + /* Let's read off the proper amount of bytes from the input. */ + if(conn->seek_func) { + Curl_set_in_callback(data, true); + seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, + SEEK_SET); + Curl_set_in_callback(data, false); + } + + if(seekerr != CURL_SEEKFUNC_OK) { + curl_off_t passed = 0; + + if(seekerr != CURL_SEEKFUNC_CANTSEEK) { + failf(data, "Could not seek stream"); + return CURLE_FTP_COULDNT_USE_REST; + } + /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? + (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread; + Curl_set_in_callback(data, true); + actuallyread = data->state.fread_func(data->state.buffer, 1, + readthisamountnow, + data->state.in); + Curl_set_in_callback(data, false); + + passed += actuallyread; + if((actuallyread == 0) || (actuallyread > readthisamountnow)) { + /* this checks for greater-than only to make sure that the + CURL_READFUNC_ABORT return code still aborts */ + failf(data, "Failed to read data"); + return CURLE_FTP_COULDNT_USE_REST; + } + } while(passed < data->state.resume_from); + } + + /* now, decrease the size of the read */ + if(data->state.infilesize > 0) { + data->state.infilesize -= data->state.resume_from; + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + + SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); + } + if(data->state.infilesize > 0) { + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + /* upload data */ + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result; + } + else { + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh2 sftp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + /* since we don't really wait for anything at this point, we want the + state machine to move on as soon as possible so we set a very short + timeout here */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); + + state(conn, SSH_STOP); + } + break; + } + + case SSH_SFTP_CREATE_DIRS_INIT: + if(strlen(sftp_scp->path) > 1) { + sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */ + state(conn, SSH_SFTP_CREATE_DIRS); + } + else { + state(conn, SSH_SFTP_UPLOAD_INIT); + } + break; + + case SSH_SFTP_CREATE_DIRS: + sshc->slash_pos = strchr(sshc->slash_pos, '/'); + if(sshc->slash_pos) { + *sshc->slash_pos = 0; + + infof(data, "Creating directory '%s'\n", sftp_scp->path); + state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); + break; + } + state(conn, SSH_SFTP_UPLOAD_INIT); + break; + + case SSH_SFTP_CREATE_DIRS_MKDIR: + /* 'mode' - parameter is preliminary - default to 0644 */ + rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + data->set.new_directory_perms); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + *sshc->slash_pos = '/'; + ++sshc->slash_pos; + if(rc < 0) { + /* + * Abort if failure wasn't that the dir already exists or the + * permission was denied (creation might succeed further down the + * path) - retry on unspecific FAILURE also + */ sftperr = libssh2_sftp_last_error(sshc->sftp_session); if((sftperr != LIBSSH2_FX_FILE_ALREADY_EXISTS) && (sftperr != LIBSSH2_FX_FAILURE) && (sftperr != LIBSSH2_FX_PERMISSION_DENIED)) { result = sftp_libssh2_error_to_CURLE(sftperr); - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = result?result:CURLE_SSH; - break; - } - rc = 0; /* clear rc and continue */ - } - state(conn, SSH_SFTP_CREATE_DIRS); - break; - - case SSH_SFTP_READDIR_INIT: - Curl_pgrsSetDownloadSize(data, -1); - if(data->set.opt_no_body) { - state(conn, SSH_STOP); - break; - } - - /* - * This is a directory that we are trying to get, so produce a directory - * listing - */ - sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session, - sftp_scp->path, - curlx_uztoui( - strlen(sftp_scp->path)), - 0, 0, LIBSSH2_SFTP_OPENDIR); - if(!sshc->sftp_handle) { - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result?result:CURLE_SSH; + break; + } + rc = 0; /* clear rc and continue */ + } + state(conn, SSH_SFTP_CREATE_DIRS); + break; + + case SSH_SFTP_READDIR_INIT: + Curl_pgrsSetDownloadSize(data, -1); + if(data->set.opt_no_body) { + state(conn, SSH_STOP); + break; + } + + /* + * This is a directory that we are trying to get, so produce a directory + * listing + */ + sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session, + sftp_scp->path, + curlx_uztoui( + strlen(sftp_scp->path)), + 0, 0, LIBSSH2_SFTP_OPENDIR); + if(!sshc->sftp_handle) { + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "Could not open directory for reading: %s", + failf(data, "Could not open directory for reading: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(conn, SSH_SFTP_CLOSE); result = sftp_libssh2_error_to_CURLE(sftperr); - sshc->actualcode = result?result:CURLE_SSH; - break; - } - sshc->readdir_filename = malloc(PATH_MAX + 1); - if(!sshc->readdir_filename) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - sshc->readdir_longentry = malloc(PATH_MAX + 1); - if(!sshc->readdir_longentry) { - Curl_safefree(sshc->readdir_filename); - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } + sshc->actualcode = result?result:CURLE_SSH; + break; + } + sshc->readdir_filename = malloc(PATH_MAX + 1); + if(!sshc->readdir_filename) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + sshc->readdir_longentry = malloc(PATH_MAX + 1); + if(!sshc->readdir_longentry) { + Curl_safefree(sshc->readdir_filename); + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } Curl_dyn_init(&sshc->readdir, PATH_MAX * 2); - state(conn, SSH_SFTP_READDIR); - break; - - case SSH_SFTP_READDIR: - rc = libssh2_sftp_readdir_ex(sshc->sftp_handle, - sshc->readdir_filename, - PATH_MAX, - sshc->readdir_longentry, - PATH_MAX, - &sshc->readdir_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc > 0) { + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR: + rc = libssh2_sftp_readdir_ex(sshc->sftp_handle, + sshc->readdir_filename, + PATH_MAX, + sshc->readdir_longentry, + PATH_MAX, + &sshc->readdir_attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc > 0) { readdir_len = (size_t) rc; sshc->readdir_filename[readdir_len] = '\0'; - - if(data->set.ftp_list_only) { - result = Curl_client_write(conn, CLIENTWRITE_BODY, + + if(data->set.ftp_list_only) { + result = Curl_client_write(conn, CLIENTWRITE_BODY, sshc->readdir_filename, readdir_len); if(!result) result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); - if(result) { - state(conn, SSH_STOP); - break; - } - /* since this counts what we send to the client, we include the - newline in this counter */ + if(result) { + state(conn, SSH_STOP); + break; + } + /* since this counts what we send to the client, we include the + newline in this counter */ data->req.bytecount += readdir_len + 1; - - /* output debug output if that is requested */ + + /* output debug output if that is requested */ Curl_debug(data, CURLINFO_DATA_IN, sshc->readdir_filename, readdir_len); Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1); - } - else { + } + else { result = Curl_dyn_add(&sshc->readdir, sshc->readdir_longentry); - + if(!result) { if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) && ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) == @@ -2185,832 +2185,832 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } else { state(conn, SSH_SFTP_READDIR_BOTTOM); - break; - } - } + break; + } + } sshc->actualcode = result; state(conn, SSH_SFTP_CLOSE); - break; - } - } - else if(rc == 0) { - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_READDIR_DONE); - break; - } - else if(rc < 0) { + break; + } + } + else if(rc == 0) { + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + state(conn, SSH_SFTP_READDIR_DONE); + break; + } + else if(rc < 0) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); result = sftp_libssh2_error_to_CURLE(sftperr); - sshc->actualcode = result?result:CURLE_SSH; - failf(data, "Could not open remote file for reading: %s :: %d", + sshc->actualcode = result?result:CURLE_SSH; + failf(data, "Could not open remote file for reading: %s :: %d", sftp_libssh2_strerror(sftperr), - libssh2_session_last_errno(sshc->ssh_session)); - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_CLOSE); - break; - } - break; - - case SSH_SFTP_READDIR_LINK: - rc = - libssh2_sftp_symlink_ex(sshc->sftp_session, + libssh2_session_last_errno(sshc->ssh_session)); + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + state(conn, SSH_SFTP_CLOSE); + break; + } + break; + + case SSH_SFTP_READDIR_LINK: + rc = + libssh2_sftp_symlink_ex(sshc->sftp_session, Curl_dyn_ptr(&sshc->readdir_link), (int)Curl_dyn_len(&sshc->readdir_link), - sshc->readdir_filename, - PATH_MAX, LIBSSH2_SFTP_READLINK); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } + sshc->readdir_filename, + PATH_MAX, LIBSSH2_SFTP_READLINK); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } readdir_len = (size_t) rc; Curl_dyn_free(&sshc->readdir_link); - + /* append filename and extra output */ result = Curl_dyn_addf(&sshc->readdir, " -> %s", sshc->readdir_filename); if(result) { - sshc->readdir_line = NULL; - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_CLOSE); + sshc->readdir_line = NULL; + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + state(conn, SSH_SFTP_CLOSE); sshc->actualcode = result; - break; - } - - state(conn, SSH_SFTP_READDIR_BOTTOM); - break; - - case SSH_SFTP_READDIR_BOTTOM: + break; + } + + state(conn, SSH_SFTP_READDIR_BOTTOM); + break; + + case SSH_SFTP_READDIR_BOTTOM: result = Curl_dyn_addn(&sshc->readdir, "\n", 1); if(!result) result = Curl_client_write(conn, CLIENTWRITE_BODY, Curl_dyn_ptr(&sshc->readdir), Curl_dyn_len(&sshc->readdir)); - - if(!result) { - /* output debug output if that is requested */ + + if(!result) { + /* output debug output if that is requested */ Curl_debug(data, CURLINFO_DATA_IN, Curl_dyn_ptr(&sshc->readdir), Curl_dyn_len(&sshc->readdir)); data->req.bytecount += Curl_dyn_len(&sshc->readdir); - } - if(result) { + } + if(result) { Curl_dyn_free(&sshc->readdir); - state(conn, SSH_STOP); - } + state(conn, SSH_STOP); + } else { Curl_dyn_reset(&sshc->readdir); - state(conn, SSH_SFTP_READDIR); - } - break; - - case SSH_SFTP_READDIR_DONE: - if(libssh2_sftp_closedir(sshc->sftp_handle) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - sshc->sftp_handle = NULL; - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - - /* no data to transfer */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_DOWNLOAD_INIT: - /* - * Work on getting the specified file - */ - sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - LIBSSH2_FXF_READ, data->set.new_file_perms, - LIBSSH2_SFTP_OPENFILE); - if(!sshc->sftp_handle) { - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } + state(conn, SSH_SFTP_READDIR); + } + break; + + case SSH_SFTP_READDIR_DONE: + if(libssh2_sftp_closedir(sshc->sftp_handle) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + sshc->sftp_handle = NULL; + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_DOWNLOAD_INIT: + /* + * Work on getting the specified file + */ + sshc->sftp_handle = + libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + LIBSSH2_FXF_READ, data->set.new_file_perms, + LIBSSH2_SFTP_OPENFILE); + if(!sshc->sftp_handle) { + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "Could not open remote file for reading: %s", + failf(data, "Could not open remote file for reading: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(conn, SSH_SFTP_CLOSE); result = sftp_libssh2_error_to_CURLE(sftperr); - sshc->actualcode = result?result:CURLE_SSH; - break; - } - state(conn, SSH_SFTP_DOWNLOAD_STAT); - break; - - case SSH_SFTP_DOWNLOAD_STAT: - { - LIBSSH2_SFTP_ATTRIBUTES attrs; - - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc || - !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) || - (attrs.filesize == 0)) { - /* - * libssh2_sftp_open() didn't return an error, so maybe the server - * just doesn't support stat() - * OR the server doesn't return a file size with a stat() - * OR file size is 0 - */ - data->req.size = -1; - data->req.maxdownload = -1; - Curl_pgrsSetDownloadSize(data, -1); - } - else { - curl_off_t size = attrs.filesize; - - if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - if(conn->data->state.use_range) { - curl_off_t from, to; - char *ptr; - char *ptr2; - CURLofft to_t; - CURLofft from_t; - - from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from); - if(from_t == CURL_OFFT_FLOW) - return CURLE_RANGE_ERROR; - while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) - ptr++; - to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); - if(to_t == CURL_OFFT_FLOW) - return CURLE_RANGE_ERROR; - if((to_t == CURL_OFFT_INVAL) /* no "to" value given */ - || (to >= size)) { - to = size - 1; - } - if(from_t) { - /* from is relative to end of file */ - from = size - to; - to = size - 1; - } - if(from > size) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - if(from > to) { - from = to; - size = 0; - } - else { - size = to - from + 1; - } - - SFTP_SEEK(conn->proto.sshc.sftp_handle, from); - } - data->req.size = size; - data->req.maxdownload = size; - Curl_pgrsSetDownloadSize(data, size); - } - - /* We can resume if we can seek to the resume position */ - if(data->state.resume_from) { - if(data->state.resume_from < 0) { - /* We're supposed to download the last abs(from) bytes */ - if((curl_off_t)attrs.filesize < -data->state.resume_from) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, attrs.filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - /* download from where? */ - data->state.resume_from += attrs.filesize; - } - else { - if((curl_off_t)attrs.filesize < data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, attrs.filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - } - /* Now store the number of bytes we are expected to download */ - data->req.size = attrs.filesize - data->state.resume_from; - data->req.maxdownload = attrs.filesize - data->state.resume_from; - Curl_pgrsSetDownloadSize(data, - attrs.filesize - data->state.resume_from); - SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); - } - } - - /* Setup the actual download */ - if(data->req.size == 0) { - /* no data to transfer */ - Curl_setup_transfer(data, -1, -1, FALSE, -1); - infof(data, "File already completely downloaded\n"); - state(conn, SSH_STOP); - break; - } - Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->writesockfd = conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh2 recv function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_IN; - - if(result) { - /* this should never occur; the close state should be entered - at the time the error occurs */ - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = result; - } - else { - state(conn, SSH_STOP); - } - break; - - case SSH_SFTP_CLOSE: - if(sshc->sftp_handle) { - rc = libssh2_sftp_close(sshc->sftp_handle); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); - } - sshc->sftp_handle = NULL; - } - - Curl_safefree(sftp_scp->path); - - DEBUGF(infof(data, "SFTP DONE done\n")); - - /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT - After nextstate is executed, the control should come back to - SSH_SFTP_CLOSE to pass the correct result back */ - if(sshc->nextstate != SSH_NO_STATE && - sshc->nextstate != SSH_SFTP_CLOSE) { - state(conn, sshc->nextstate); - sshc->nextstate = SSH_SFTP_CLOSE; - } - else { - state(conn, SSH_STOP); - result = sshc->actualcode; - } - break; - - case SSH_SFTP_SHUTDOWN: - /* during times we get here due to a broken transfer and then the - sftp_handle might not have been taken down so make sure that is done - before we proceed */ - - if(sshc->sftp_handle) { - rc = libssh2_sftp_close(sshc->sftp_handle); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, - NULL, 0); - infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); - } - sshc->sftp_handle = NULL; - } - if(sshc->sftp_session) { - rc = libssh2_sftp_shutdown(sshc->sftp_session); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc < 0) { - infof(data, "Failed to stop libssh2 sftp subsystem\n"); - } - sshc->sftp_session = NULL; - } - - Curl_safefree(sshc->homedir); - conn->data->state.most_recent_ftp_entrypath = NULL; - - state(conn, SSH_SESSION_DISCONNECT); - break; - - case SSH_SCP_TRANS_INIT: - result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); - if(result) { - sshc->actualcode = result; - state(conn, SSH_STOP); - break; - } - - if(data->set.upload) { - if(data->state.infilesize < 0) { - failf(data, "SCP requires a known file size for upload"); - sshc->actualcode = CURLE_UPLOAD_FAILED; - state(conn, SSH_SCP_CHANNEL_FREE); - break; - } - state(conn, SSH_SCP_UPLOAD_INIT); - } - else { - state(conn, SSH_SCP_DOWNLOAD_INIT); - } - break; - - case SSH_SCP_UPLOAD_INIT: - /* - * libssh2 requires that the destination path is a full path that - * includes the destination file and name OR ends in a "/" . If this is - * not done the destination file will be named the same name as the last - * directory in the path. - */ - sshc->ssh_channel = - SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms, - data->state.infilesize); - if(!sshc->ssh_channel) { - int ssh_err; - char *err_msg = NULL; - - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - - ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0)); - failf(conn->data, "%s", err_msg); - state(conn, SSH_SCP_CHANNEL_FREE); - sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); - /* Map generic errors to upload failed */ - if(sshc->actualcode == CURLE_SSH || - sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND) - sshc->actualcode = CURLE_UPLOAD_FAILED; - break; - } - - /* upload data */ + sshc->actualcode = result?result:CURLE_SSH; + break; + } + state(conn, SSH_SFTP_DOWNLOAD_STAT); + break; + + case SSH_SFTP_DOWNLOAD_STAT: + { + LIBSSH2_SFTP_ATTRIBUTES attrs; + + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + LIBSSH2_SFTP_STAT, &attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc || + !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) || + (attrs.filesize == 0)) { + /* + * libssh2_sftp_open() didn't return an error, so maybe the server + * just doesn't support stat() + * OR the server doesn't return a file size with a stat() + * OR file size is 0 + */ + data->req.size = -1; + data->req.maxdownload = -1; + Curl_pgrsSetDownloadSize(data, -1); + } + else { + curl_off_t size = attrs.filesize; + + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(conn->data->state.use_range) { + curl_off_t from, to; + char *ptr; + char *ptr2; + CURLofft to_t; + CURLofft from_t; + + from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from); + if(from_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + ptr++; + to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); + if(to_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + if((to_t == CURL_OFFT_INVAL) /* no "to" value given */ + || (to >= size)) { + to = size - 1; + } + if(from_t) { + /* from is relative to end of file */ + from = size - to; + to = size - 1; + } + if(from > size) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(from > to) { + from = to; + size = 0; + } + else { + size = to - from + 1; + } + + SFTP_SEEK(conn->proto.sshc.sftp_handle, from); + } + data->req.size = size; + data->req.maxdownload = size; + Curl_pgrsSetDownloadSize(data, size); + } + + /* We can resume if we can seek to the resume position */ + if(data->state.resume_from) { + if(data->state.resume_from < 0) { + /* We're supposed to download the last abs(from) bytes */ + if((curl_off_t)attrs.filesize < -data->state.resume_from) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, attrs.filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* download from where? */ + data->state.resume_from += attrs.filesize; + } + else { + if((curl_off_t)attrs.filesize < data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, attrs.filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + } + /* Now store the number of bytes we are expected to download */ + data->req.size = attrs.filesize - data->state.resume_from; + data->req.maxdownload = attrs.filesize - data->state.resume_from; + Curl_pgrsSetDownloadSize(data, + attrs.filesize - data->state.resume_from); + SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); + } + } + + /* Setup the actual download */ + if(data->req.size == 0) { + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + infof(data, "File already completely downloaded\n"); + state(conn, SSH_STOP); + break; + } + Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh2 recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + if(result) { + /* this should never occur; the close state should be entered + at the time the error occurs */ + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result; + } + else { + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_CLOSE: + if(sshc->sftp_handle) { + rc = libssh2_sftp_close(sshc->sftp_handle); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); + } + sshc->sftp_handle = NULL; + } + + Curl_safefree(sftp_scp->path); + + DEBUGF(infof(data, "SFTP DONE done\n")); + + /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT + After nextstate is executed, the control should come back to + SSH_SFTP_CLOSE to pass the correct result back */ + if(sshc->nextstate != SSH_NO_STATE && + sshc->nextstate != SSH_SFTP_CLOSE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_SFTP_CLOSE; + } + else { + state(conn, SSH_STOP); + result = sshc->actualcode; + } + break; + + case SSH_SFTP_SHUTDOWN: + /* during times we get here due to a broken transfer and then the + sftp_handle might not have been taken down so make sure that is done + before we proceed */ + + if(sshc->sftp_handle) { + rc = libssh2_sftp_close(sshc->sftp_handle); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, + NULL, 0); + infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); + } + sshc->sftp_handle = NULL; + } + if(sshc->sftp_session) { + rc = libssh2_sftp_shutdown(sshc->sftp_session); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + infof(data, "Failed to stop libssh2 sftp subsystem\n"); + } + sshc->sftp_session = NULL; + } + + Curl_safefree(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_DISCONNECT); + break; + + case SSH_SCP_TRANS_INIT: + result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + if(data->set.upload) { + if(data->state.infilesize < 0) { + failf(data, "SCP requires a known file size for upload"); + sshc->actualcode = CURLE_UPLOAD_FAILED; + state(conn, SSH_SCP_CHANNEL_FREE); + break; + } + state(conn, SSH_SCP_UPLOAD_INIT); + } + else { + state(conn, SSH_SCP_DOWNLOAD_INIT); + } + break; + + case SSH_SCP_UPLOAD_INIT: + /* + * libssh2 requires that the destination path is a full path that + * includes the destination file and name OR ends in a "/" . If this is + * not done the destination file will be named the same name as the last + * directory in the path. + */ + sshc->ssh_channel = + SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms, + data->state.infilesize); + if(!sshc->ssh_channel) { + int ssh_err; + char *err_msg = NULL; + + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + + ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0)); + failf(conn->data, "%s", err_msg); + state(conn, SSH_SCP_CHANNEL_FREE); + sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); + /* Map generic errors to upload failed */ + if(sshc->actualcode == CURLE_SSH || + sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND) + sshc->actualcode = CURLE_UPLOAD_FAILED; + break; + } + + /* upload data */ data->req.size = data->state.infilesize; Curl_pgrsSetUploadSize(data, data->state.infilesize); Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->sockfd = conn->writesockfd; - - if(result) { - state(conn, SSH_SCP_CHANNEL_FREE); - sshc->actualcode = result; - } - else { - /* store this original bitmask setup to use later on if we can't - figure out a "real" bitmask */ - sshc->orig_waitfor = data->req.keepon; - - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh2 scp send function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_OUT; - - state(conn, SSH_STOP); - } - break; - - case SSH_SCP_DOWNLOAD_INIT: - { - curl_off_t bytecount; - - /* - * We must check the remote file; if it is a directory no values will - * be set in sb - */ - - /* - * If support for >2GB files exists, use it. - */ - - /* get a fresh new channel from the ssh layer */ -#if LIBSSH2_VERSION_NUM < 0x010700 - struct stat sb; - memset(&sb, 0, sizeof(struct stat)); - sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session, - sftp_scp->path, &sb); -#else - libssh2_struct_stat sb; - memset(&sb, 0, sizeof(libssh2_struct_stat)); - sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session, - sftp_scp->path, &sb); -#endif - - if(!sshc->ssh_channel) { - int ssh_err; - char *err_msg = NULL; - - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - - - ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0)); - failf(conn->data, "%s", err_msg); - state(conn, SSH_SCP_CHANNEL_FREE); - sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); - break; - } - - /* download data */ - bytecount = (curl_off_t)sb.st_size; + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + if(result) { + state(conn, SSH_SCP_CHANNEL_FREE); + sshc->actualcode = result; + } + else { + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh2 scp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + state(conn, SSH_STOP); + } + break; + + case SSH_SCP_DOWNLOAD_INIT: + { + curl_off_t bytecount; + + /* + * We must check the remote file; if it is a directory no values will + * be set in sb + */ + + /* + * If support for >2GB files exists, use it. + */ + + /* get a fresh new channel from the ssh layer */ +#if LIBSSH2_VERSION_NUM < 0x010700 + struct stat sb; + memset(&sb, 0, sizeof(struct stat)); + sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session, + sftp_scp->path, &sb); +#else + libssh2_struct_stat sb; + memset(&sb, 0, sizeof(libssh2_struct_stat)); + sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session, + sftp_scp->path, &sb); +#endif + + if(!sshc->ssh_channel) { + int ssh_err; + char *err_msg = NULL; + + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + + + ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0)); + failf(conn->data, "%s", err_msg); + state(conn, SSH_SCP_CHANNEL_FREE); + sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); + break; + } + + /* download data */ + bytecount = (curl_off_t)sb.st_size; data->req.maxdownload = (curl_off_t)sb.st_size; - Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->writesockfd = conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh2 recv function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_IN; - - if(result) { - state(conn, SSH_SCP_CHANNEL_FREE); - sshc->actualcode = result; - } - else - state(conn, SSH_STOP); - } - break; - - case SSH_SCP_DONE: - if(data->set.upload) - state(conn, SSH_SCP_SEND_EOF); - else - state(conn, SSH_SCP_CHANNEL_FREE); - break; - - case SSH_SCP_SEND_EOF: - if(sshc->ssh_channel) { - rc = libssh2_channel_send_eof(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to send libssh2 channel EOF: %d %s\n", - rc, err_msg); - } - } - state(conn, SSH_SCP_WAIT_EOF); - break; - - case SSH_SCP_WAIT_EOF: - if(sshc->ssh_channel) { - rc = libssh2_channel_wait_eof(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg); - } - } - state(conn, SSH_SCP_WAIT_CLOSE); - break; - - case SSH_SCP_WAIT_CLOSE: - if(sshc->ssh_channel) { - rc = libssh2_channel_wait_closed(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Channel failed to close: %d %s\n", rc, err_msg); - } - } - state(conn, SSH_SCP_CHANNEL_FREE); - break; - - case SSH_SCP_CHANNEL_FREE: - if(sshc->ssh_channel) { - rc = libssh2_channel_free(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", - rc, err_msg); - } - sshc->ssh_channel = NULL; - } - DEBUGF(infof(data, "SCP DONE phase complete\n")); -#if 0 /* PREV */ - state(conn, SSH_SESSION_DISCONNECT); -#endif - state(conn, SSH_STOP); - result = sshc->actualcode; - break; - - case SSH_SESSION_DISCONNECT: - /* during weird times when we've been prematurely aborted, the channel - is still alive when we reach this state and we MUST kill the channel - properly first */ - if(sshc->ssh_channel) { - rc = libssh2_channel_free(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", - rc, err_msg); - } - sshc->ssh_channel = NULL; - } - - if(sshc->ssh_session) { - rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown"); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to disconnect libssh2 session: %d %s\n", - rc, err_msg); - } - } - - Curl_safefree(sshc->homedir); - conn->data->state.most_recent_ftp_entrypath = NULL; - - state(conn, SSH_SESSION_FREE); - break; - - case SSH_SESSION_FREE: -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - if(sshc->kh) { - libssh2_knownhost_free(sshc->kh); - sshc->kh = NULL; - } -#endif - -#ifdef HAVE_LIBSSH2_AGENT_API - if(sshc->ssh_agent) { - rc = libssh2_agent_disconnect(sshc->ssh_agent); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to disconnect from libssh2 agent: %d %s\n", - rc, err_msg); - } - libssh2_agent_free(sshc->ssh_agent); - sshc->ssh_agent = NULL; - - /* NB: there is no need to free identities, they are part of internal - agent stuff */ - sshc->sshagent_identity = NULL; - sshc->sshagent_prev_identity = NULL; - } -#endif - - if(sshc->ssh_session) { - rc = libssh2_session_free(sshc->ssh_session); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg); - } - sshc->ssh_session = NULL; - } - - /* worst-case scenario cleanup */ - - DEBUGASSERT(sshc->ssh_session == NULL); - DEBUGASSERT(sshc->ssh_channel == NULL); - DEBUGASSERT(sshc->sftp_session == NULL); - DEBUGASSERT(sshc->sftp_handle == NULL); -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - DEBUGASSERT(sshc->kh == NULL); -#endif -#ifdef HAVE_LIBSSH2_AGENT_API - DEBUGASSERT(sshc->ssh_agent == NULL); -#endif - - Curl_safefree(sshc->rsa_pub); - Curl_safefree(sshc->rsa); - - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - - Curl_safefree(sshc->homedir); - - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - Curl_safefree(sshc->readdir_line); + Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh2 recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + if(result) { + state(conn, SSH_SCP_CHANNEL_FREE); + sshc->actualcode = result; + } + else + state(conn, SSH_STOP); + } + break; + + case SSH_SCP_DONE: + if(data->set.upload) + state(conn, SSH_SCP_SEND_EOF); + else + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_SEND_EOF: + if(sshc->ssh_channel) { + rc = libssh2_channel_send_eof(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to send libssh2 channel EOF: %d %s\n", + rc, err_msg); + } + } + state(conn, SSH_SCP_WAIT_EOF); + break; + + case SSH_SCP_WAIT_EOF: + if(sshc->ssh_channel) { + rc = libssh2_channel_wait_eof(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg); + } + } + state(conn, SSH_SCP_WAIT_CLOSE); + break; + + case SSH_SCP_WAIT_CLOSE: + if(sshc->ssh_channel) { + rc = libssh2_channel_wait_closed(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Channel failed to close: %d %s\n", rc, err_msg); + } + } + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_CHANNEL_FREE: + if(sshc->ssh_channel) { + rc = libssh2_channel_free(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", + rc, err_msg); + } + sshc->ssh_channel = NULL; + } + DEBUGF(infof(data, "SCP DONE phase complete\n")); +#if 0 /* PREV */ + state(conn, SSH_SESSION_DISCONNECT); +#endif + state(conn, SSH_STOP); + result = sshc->actualcode; + break; + + case SSH_SESSION_DISCONNECT: + /* during weird times when we've been prematurely aborted, the channel + is still alive when we reach this state and we MUST kill the channel + properly first */ + if(sshc->ssh_channel) { + rc = libssh2_channel_free(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", + rc, err_msg); + } + sshc->ssh_channel = NULL; + } + + if(sshc->ssh_session) { + rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown"); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to disconnect libssh2 session: %d %s\n", + rc, err_msg); + } + } + + Curl_safefree(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_FREE); + break; + + case SSH_SESSION_FREE: +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + if(sshc->kh) { + libssh2_knownhost_free(sshc->kh); + sshc->kh = NULL; + } +#endif + +#ifdef HAVE_LIBSSH2_AGENT_API + if(sshc->ssh_agent) { + rc = libssh2_agent_disconnect(sshc->ssh_agent); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to disconnect from libssh2 agent: %d %s\n", + rc, err_msg); + } + libssh2_agent_free(sshc->ssh_agent); + sshc->ssh_agent = NULL; + + /* NB: there is no need to free identities, they are part of internal + agent stuff */ + sshc->sshagent_identity = NULL; + sshc->sshagent_prev_identity = NULL; + } +#endif + + if(sshc->ssh_session) { + rc = libssh2_session_free(sshc->ssh_session); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg); + } + sshc->ssh_session = NULL; + } + + /* worst-case scenario cleanup */ + + DEBUGASSERT(sshc->ssh_session == NULL); + DEBUGASSERT(sshc->ssh_channel == NULL); + DEBUGASSERT(sshc->sftp_session == NULL); + DEBUGASSERT(sshc->sftp_handle == NULL); +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + DEBUGASSERT(sshc->kh == NULL); +#endif +#ifdef HAVE_LIBSSH2_AGENT_API + DEBUGASSERT(sshc->ssh_agent == NULL); +#endif + + Curl_safefree(sshc->rsa_pub); + Curl_safefree(sshc->rsa); + + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + Curl_safefree(sshc->homedir); + + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + Curl_safefree(sshc->readdir_line); Curl_dyn_free(&sshc->readdir); - - /* the code we are about to return */ - result = sshc->actualcode; - - memset(sshc, 0, sizeof(struct ssh_conn)); - - connclose(conn, "SSH session free"); - sshc->state = SSH_SESSION_FREE; /* current */ - sshc->nextstate = SSH_NO_STATE; - state(conn, SSH_STOP); - break; - - case SSH_QUIT: - /* fallthrough, just stop! */ - default: - /* internal error */ - sshc->nextstate = SSH_NO_STATE; - state(conn, SSH_STOP); - break; - } - - } while(!rc && (sshc->state != SSH_STOP)); - - if(rc == LIBSSH2_ERROR_EAGAIN) { - /* we would block, we need to wait for the socket to be ready (in the - right direction too)! */ - *block = TRUE; - } - - return result; -} - -/* called by the multi interface to figure out what socket(s) to wait for and - for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static int ssh_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock) -{ - int bitmap = GETSOCK_BLANK; - - sock[0] = conn->sock[FIRSTSOCKET]; - - if(conn->waitfor & KEEP_RECV) - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - - if(conn->waitfor & KEEP_SEND) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - return bitmap; -} - -/* Generic function called by the multi interface to figure out what socket(s) - to wait for and for what actions during the DOING and PROTOCONNECT states*/ -static int ssh_getsock(struct connectdata *conn, - curl_socket_t *sock) -{ - /* if we know the direction we can use the generic *_getsock() function even - for the protocol_connect and doing states */ - return ssh_perform_getsock(conn, sock); -} - -/* - * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this - * function is used to figure out in what direction and stores this info so - * that the multi interface can take advantage of it. Make sure to call this - * function in all cases so that when it _doesn't_ return EAGAIN we can - * restore the default wait bits. - */ -static void ssh_block2waitfor(struct connectdata *conn, bool block) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - int dir = 0; - if(block) { - dir = libssh2_session_block_directions(sshc->ssh_session); - if(dir) { - /* translate the libssh2 define bits into our own bit defines */ - conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) | - ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0); - } - } - if(!dir) - /* It didn't block or libssh2 didn't reveal in which direction, put back - the original set */ - conn->waitfor = sshc->orig_waitfor; -} - -/* called repeatedly until done from multi.c */ -static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - CURLcode result = CURLE_OK; - bool block; /* we store the status and use that to provide a ssh_getsock() - implementation */ - do { - result = ssh_statemach_act(conn, &block); - *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; - /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then - try again */ - } while(!result && !*done && !block); - ssh_block2waitfor(conn, block); - - return result; -} - -static CURLcode ssh_block_statemach(struct connectdata *conn, + + /* the code we are about to return */ + result = sshc->actualcode; + + memset(sshc, 0, sizeof(struct ssh_conn)); + + connclose(conn, "SSH session free"); + sshc->state = SSH_SESSION_FREE; /* current */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + + case SSH_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + } + + } while(!rc && (sshc->state != SSH_STOP)); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + /* we would block, we need to wait for the socket to be ready (in the + right direction too)! */ + *block = TRUE; + } + + return result; +} + +/* called by the multi interface to figure out what socket(s) to wait for and + for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ +static int ssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock) +{ + int bitmap = GETSOCK_BLANK; + + sock[0] = conn->sock[FIRSTSOCKET]; + + if(conn->waitfor & KEEP_RECV) + bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); + + if(conn->waitfor & KEEP_SEND) + bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); + + return bitmap; +} + +/* Generic function called by the multi interface to figure out what socket(s) + to wait for and for what actions during the DOING and PROTOCONNECT states*/ +static int ssh_getsock(struct connectdata *conn, + curl_socket_t *sock) +{ + /* if we know the direction we can use the generic *_getsock() function even + for the protocol_connect and doing states */ + return ssh_perform_getsock(conn, sock); +} + +/* + * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this + * function is used to figure out in what direction and stores this info so + * that the multi interface can take advantage of it. Make sure to call this + * function in all cases so that when it _doesn't_ return EAGAIN we can + * restore the default wait bits. + */ +static void ssh_block2waitfor(struct connectdata *conn, bool block) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + int dir = 0; + if(block) { + dir = libssh2_session_block_directions(sshc->ssh_session); + if(dir) { + /* translate the libssh2 define bits into our own bit defines */ + conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) | + ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0); + } + } + if(!dir) + /* It didn't block or libssh2 didn't reveal in which direction, put back + the original set */ + conn->waitfor = sshc->orig_waitfor; +} + +/* called repeatedly until done from multi.c */ +static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result = CURLE_OK; + bool block; /* we store the status and use that to provide a ssh_getsock() + implementation */ + do { + result = ssh_statemach_act(conn, &block); + *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; + /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then + try again */ + } while(!result && !*done && !block); + ssh_block2waitfor(conn, block); + + return result; +} + +static CURLcode ssh_block_statemach(struct connectdata *conn, bool duringconnect) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - - while((sshc->state != SSH_STOP) && !result) { - bool block; - timediff_t left = 1000; - struct curltime now = Curl_now(); - - result = ssh_statemach_act(conn, &block); - if(result) - break; - +{ + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + while((sshc->state != SSH_STOP) && !result) { + bool block; + timediff_t left = 1000; + struct curltime now = Curl_now(); + + result = ssh_statemach_act(conn, &block); + if(result) + break; + if(Curl_pgrsUpdate(conn)) return CURLE_ABORTED_BY_CALLBACK; - + result = Curl_speedcheck(data, now); if(result) break; - + left = Curl_timeleft(data, NULL, duringconnect); if(left < 0) { failf(data, "Operation timed out"); return CURLE_OPERATION_TIMEDOUT; - } - + } + if(block) { - int dir = libssh2_session_block_directions(sshc->ssh_session); - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - curl_socket_t fd_read = CURL_SOCKET_BAD; - curl_socket_t fd_write = CURL_SOCKET_BAD; - if(LIBSSH2_SESSION_BLOCK_INBOUND & dir) - fd_read = sock; - if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) - fd_write = sock; - /* wait for the socket to become ready */ - (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, + int dir = libssh2_session_block_directions(sshc->ssh_session); + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + curl_socket_t fd_read = CURL_SOCKET_BAD; + curl_socket_t fd_write = CURL_SOCKET_BAD; + if(LIBSSH2_SESSION_BLOCK_INBOUND & dir) + fd_read = sock; + if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) + fd_write = sock; + /* wait for the socket to become ready */ + (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, left>1000?1000:left); - } - } - - return result; -} - -/* - * SSH setup and connection - */ -static CURLcode ssh_setup_connection(struct connectdata *conn) -{ - struct SSHPROTO *ssh; - + } + } + + return result; +} + +/* + * SSH setup and connection + */ +static CURLcode ssh_setup_connection(struct connectdata *conn) +{ + struct SSHPROTO *ssh; + conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO)); - if(!ssh) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static Curl_recv scp_recv, sftp_recv; -static Curl_send scp_send, sftp_send; - + if(!ssh) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +static Curl_recv scp_recv, sftp_recv; +static Curl_send scp_send, sftp_send; + #ifndef CURL_DISABLE_PROXY static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags, void **abstract) @@ -3059,47 +3059,47 @@ static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer, } #endif -/* - * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to - * do protocol-specific actions at connect-time. - */ -static CURLcode ssh_connect(struct connectdata *conn, bool *done) -{ -#ifdef CURL_LIBSSH2_DEBUG - curl_socket_t sock; -#endif - struct ssh_conn *ssh; - CURLcode result; - struct Curl_easy *data = conn->data; - - /* initialize per-handle data if not already */ +/* + * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to + * do protocol-specific actions at connect-time. + */ +static CURLcode ssh_connect(struct connectdata *conn, bool *done) +{ +#ifdef CURL_LIBSSH2_DEBUG + curl_socket_t sock; +#endif + struct ssh_conn *ssh; + CURLcode result; + struct Curl_easy *data = conn->data; + + /* initialize per-handle data if not already */ if(!data->req.p.ssh) - ssh_setup_connection(conn); - - /* We default to persistent connections. We set this already in this connect - function to make the re-use checks properly be able to check this bit. */ - connkeep(conn, "SSH default"); - - ssh = &conn->proto.sshc; - -#ifdef CURL_LIBSSH2_DEBUG - if(conn->user) { - infof(data, "User: %s\n", conn->user); - } - if(conn->passwd) { - infof(data, "Password: %s\n", conn->passwd); - } - sock = conn->sock[FIRSTSOCKET]; -#endif /* CURL_LIBSSH2_DEBUG */ - - ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, - my_libssh2_free, - my_libssh2_realloc, conn); - if(ssh->ssh_session == NULL) { - failf(data, "Failure initialising ssh session"); - return CURLE_FAILED_INIT; - } - + ssh_setup_connection(conn); + + /* We default to persistent connections. We set this already in this connect + function to make the re-use checks properly be able to check this bit. */ + connkeep(conn, "SSH default"); + + ssh = &conn->proto.sshc; + +#ifdef CURL_LIBSSH2_DEBUG + if(conn->user) { + infof(data, "User: %s\n", conn->user); + } + if(conn->passwd) { + infof(data, "Password: %s\n", conn->passwd); + } + sock = conn->sock[FIRSTSOCKET]; +#endif /* CURL_LIBSSH2_DEBUG */ + + ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, + my_libssh2_free, + my_libssh2_realloc, conn); + if(ssh->ssh_session == NULL) { + failf(data, "Failure initialising ssh session"); + return CURLE_FAILED_INIT; + } + #ifndef CURL_DISABLE_PROXY if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) { /* @@ -3155,450 +3155,450 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) conn->send[FIRSTSOCKET] = sftp_send; } - if(data->set.ssh_compression) { -#if LIBSSH2_VERSION_NUM >= 0x010208 - if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) -#endif - infof(data, "Failed to enable compression for ssh session\n"); - } - -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - int rc; - ssh->kh = libssh2_knownhost_init(ssh->ssh_session); - if(!ssh->kh) { - libssh2_session_free(ssh->ssh_session); - return CURLE_FAILED_INIT; - } - - /* read all known hosts from there */ - rc = libssh2_knownhost_readfile(ssh->kh, - data->set.str[STRING_SSH_KNOWNHOSTS], - LIBSSH2_KNOWNHOST_FILE_OPENSSH); - if(rc < 0) - infof(data, "Failed to read known hosts from %s\n", - data->set.str[STRING_SSH_KNOWNHOSTS]); - } -#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ - -#ifdef CURL_LIBSSH2_DEBUG - libssh2_trace(ssh->ssh_session, ~0); - infof(data, "SSH socket: %d\n", (int)sock); -#endif /* CURL_LIBSSH2_DEBUG */ - - state(conn, SSH_INIT); - - result = ssh_multi_statemach(conn, done); - - return result; -} - -/* - *********************************************************************** - * - * scp_perform() - * - * This is the actual DO function for SCP. Get a file according to - * the options previously setup. - */ - -static -CURLcode scp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - *dophase_done = FALSE; /* not done yet */ - - /* start the first command in the DO phase */ - state(conn, SSH_SCP_TRANS_INIT); - - /* run the state-machine */ - result = ssh_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode scp_doing(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result; - result = ssh_multi_statemach(conn, dophase_done); - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - return result; -} - -/* - * The DO function is generic for both protocols. There was previously two - * separate ones but this way means less duplicated code. - */ - -static CURLcode ssh_do(struct connectdata *conn, bool *done) -{ - CURLcode result; - bool connected = 0; - struct Curl_easy *data = conn->data; - struct ssh_conn *sshc = &conn->proto.sshc; - - *done = FALSE; /* default to false */ - - data->req.size = -1; /* make sure this is unknown at this point */ - - sshc->actualcode = CURLE_OK; /* reset error code */ - sshc->secondCreateDirs = 0; /* reset the create dir attempt state - variable */ - - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - Curl_pgrsSetUploadSize(data, -1); - Curl_pgrsSetDownloadSize(data, -1); - - if(conn->handler->protocol & CURLPROTO_SCP) - result = scp_perform(conn, &connected, done); - else - result = sftp_perform(conn, &connected, done); - - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection) -{ - CURLcode result = CURLE_OK; - struct ssh_conn *ssh = &conn->proto.sshc; - (void) dead_connection; - - if(ssh->ssh_session) { - /* only if there's a session still around to use! */ - - state(conn, SSH_SESSION_DISCONNECT); - + if(data->set.ssh_compression) { +#if LIBSSH2_VERSION_NUM >= 0x010208 + if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) +#endif + infof(data, "Failed to enable compression for ssh session\n"); + } + +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + if(data->set.str[STRING_SSH_KNOWNHOSTS]) { + int rc; + ssh->kh = libssh2_knownhost_init(ssh->ssh_session); + if(!ssh->kh) { + libssh2_session_free(ssh->ssh_session); + return CURLE_FAILED_INIT; + } + + /* read all known hosts from there */ + rc = libssh2_knownhost_readfile(ssh->kh, + data->set.str[STRING_SSH_KNOWNHOSTS], + LIBSSH2_KNOWNHOST_FILE_OPENSSH); + if(rc < 0) + infof(data, "Failed to read known hosts from %s\n", + data->set.str[STRING_SSH_KNOWNHOSTS]); + } +#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ + +#ifdef CURL_LIBSSH2_DEBUG + libssh2_trace(ssh->ssh_session, ~0); + infof(data, "SSH socket: %d\n", (int)sock); +#endif /* CURL_LIBSSH2_DEBUG */ + + state(conn, SSH_INIT); + + result = ssh_multi_statemach(conn, done); + + return result; +} + +/* + *********************************************************************** + * + * scp_perform() + * + * This is the actual DO function for SCP. Get a file according to + * the options previously setup. + */ + +static +CURLcode scp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SCP_TRANS_INIT); + + /* run the state-machine */ + result = ssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode scp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result; + result = ssh_multi_statemach(conn, dophase_done); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* + * The DO function is generic for both protocols. There was previously two + * separate ones but this way means less duplicated code. + */ + +static CURLcode ssh_do(struct connectdata *conn, bool *done) +{ + CURLcode result; + bool connected = 0; + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + + *done = FALSE; /* default to false */ + + data->req.size = -1; /* make sure this is unknown at this point */ + + sshc->actualcode = CURLE_OK; /* reset error code */ + sshc->secondCreateDirs = 0; /* reset the create dir attempt state + variable */ + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + if(conn->handler->protocol & CURLPROTO_SCP) + result = scp_perform(conn, &connected, done); + else + result = sftp_perform(conn, &connected, done); + + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection) +{ + CURLcode result = CURLE_OK; + struct ssh_conn *ssh = &conn->proto.sshc; + (void) dead_connection; + + if(ssh->ssh_session) { + /* only if there's a session still around to use! */ + + state(conn, SSH_SESSION_DISCONNECT); + result = ssh_block_statemach(conn, FALSE); - } - - return result; -} - -/* generic done function for both SCP and SFTP called from their specific - done functions */ -static CURLcode ssh_done(struct connectdata *conn, CURLcode status) -{ - CURLcode result = CURLE_OK; + } + + return result; +} + +/* generic done function for both SCP and SFTP called from their specific + done functions */ +static CURLcode ssh_done(struct connectdata *conn, CURLcode status) +{ + CURLcode result = CURLE_OK; struct SSHPROTO *sftp_scp = conn->data->req.p.ssh; - - if(!status) { - /* run the state-machine */ - result = ssh_block_statemach(conn, FALSE); - } - else - result = status; - - if(sftp_scp) - Curl_safefree(sftp_scp->path); - if(Curl_pgrsDone(conn)) - return CURLE_ABORTED_BY_CALLBACK; - - conn->data->req.keepon = 0; /* clear all bits */ - return result; -} - - -static CURLcode scp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - (void)premature; /* not used */ - - if(!status) - state(conn, SSH_SCP_DONE); - - return ssh_done(conn, status); - -} - -static ssize_t scp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, CURLcode *err) -{ - ssize_t nwrite; - (void)sockindex; /* we only support SCP on the fixed known primary socket */ - - /* libssh2_channel_write() returns int! */ - nwrite = (ssize_t) - libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len); - - ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - - if(nwrite == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else if(nwrite < LIBSSH2_ERROR_NONE) { - *err = libssh2_session_error_to_CURLE((int)nwrite); - nwrite = -1; - } - - return nwrite; -} - -static ssize_t scp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len, CURLcode *err) -{ - ssize_t nread; - (void)sockindex; /* we only support SCP on the fixed known primary socket */ - - /* libssh2_channel_read() returns int */ - nread = (ssize_t) - libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len); - - ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - if(nread == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nread = -1; - } - - return nread; -} - -/* - * =============== SFTP =============== - */ - -/* - *********************************************************************** - * - * sftp_perform() - * - * This is the actual DO function for SFTP. Get a file/directory according to - * the options previously setup. - */ - -static -CURLcode sftp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - *dophase_done = FALSE; /* not done yet */ - - /* start the first command in the DO phase */ - state(conn, SSH_SFTP_QUOTE_INIT); - - /* run the state-machine */ - result = ssh_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode sftp_doing(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result = ssh_multi_statemach(conn, dophase_done); - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) -{ - CURLcode result = CURLE_OK; - (void) dead_connection; - - DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); - - if(conn->proto.sshc.ssh_session) { - /* only if there's a session still around to use! */ - state(conn, SSH_SFTP_SHUTDOWN); + + if(!status) { + /* run the state-machine */ result = ssh_block_statemach(conn, FALSE); - } - - DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); - - return result; - -} - -static CURLcode sftp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - - if(!status) { - /* Post quote commands are executed after the SFTP_CLOSE state to avoid - errors that could happen due to open file handles during POSTQUOTE - operation */ - if(!premature && conn->data->set.postquote && !conn->bits.retry) - sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - state(conn, SSH_SFTP_CLOSE); - } - return ssh_done(conn, status); -} - -/* return number of sent bytes */ -static ssize_t sftp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, CURLcode *err) -{ - ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14 - but is changed to ssize_t in 0.15. These days we don't - support libssh2 0.15*/ - (void)sockindex; - - nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len); - - ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - - if(nwrite == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else if(nwrite < LIBSSH2_ERROR_NONE) { - *err = libssh2_session_error_to_CURLE((int)nwrite); - nwrite = -1; - } - - return nwrite; -} - -/* - * Return number of received (decrypted) bytes - * or <0 on error - */ -static ssize_t sftp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len, CURLcode *err) -{ - ssize_t nread; - (void)sockindex; - - nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len); - - ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - - if(nread == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nread = -1; - - } - else if(nread < 0) { - *err = libssh2_session_error_to_CURLE((int)nread); - } - return nread; -} - + } + else + result = status; + + if(sftp_scp) + Curl_safefree(sftp_scp->path); + if(Curl_pgrsDone(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + conn->data->req.keepon = 0; /* clear all bits */ + return result; +} + + +static CURLcode scp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + (void)premature; /* not used */ + + if(!status) + state(conn, SSH_SCP_DONE); + + return ssh_done(conn, status); + +} + +static ssize_t scp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + ssize_t nwrite; + (void)sockindex; /* we only support SCP on the fixed known primary socket */ + + /* libssh2_channel_write() returns int! */ + nwrite = (ssize_t) + libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len); + + ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + + if(nwrite == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } + else if(nwrite < LIBSSH2_ERROR_NONE) { + *err = libssh2_session_error_to_CURLE((int)nwrite); + nwrite = -1; + } + + return nwrite; +} + +static ssize_t scp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void)sockindex; /* we only support SCP on the fixed known primary socket */ + + /* libssh2_channel_read() returns int */ + nread = (ssize_t) + libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len); + + ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + if(nread == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nread = -1; + } + + return nread; +} + +/* + * =============== SFTP =============== + */ + +/* + *********************************************************************** + * + * sftp_perform() + * + * This is the actual DO function for SFTP. Get a file/directory according to + * the options previously setup. + */ + +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SFTP_QUOTE_INIT); + + /* run the state-machine */ + result = ssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = ssh_multi_statemach(conn, dophase_done); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) +{ + CURLcode result = CURLE_OK; + (void) dead_connection; + + DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); + + if(conn->proto.sshc.ssh_session) { + /* only if there's a session still around to use! */ + state(conn, SSH_SFTP_SHUTDOWN); + result = ssh_block_statemach(conn, FALSE); + } + + DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); + + return result; + +} + +static CURLcode sftp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + + if(!status) { + /* Post quote commands are executed after the SFTP_CLOSE state to avoid + errors that could happen due to open file handles during POSTQUOTE + operation */ + if(!premature && conn->data->set.postquote && !conn->bits.retry) + sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; + state(conn, SSH_SFTP_CLOSE); + } + return ssh_done(conn, status); +} + +/* return number of sent bytes */ +static ssize_t sftp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14 + but is changed to ssize_t in 0.15. These days we don't + support libssh2 0.15*/ + (void)sockindex; + + nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len); + + ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + + if(nwrite == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } + else if(nwrite < LIBSSH2_ERROR_NONE) { + *err = libssh2_session_error_to_CURLE((int)nwrite); + nwrite = -1; + } + + return nwrite; +} + +/* + * Return number of received (decrypted) bytes + * or <0 on error + */ +static ssize_t sftp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void)sockindex; + + nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len); + + ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + + if(nread == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nread = -1; + + } + else if(nread < 0) { + *err = libssh2_session_error_to_CURLE((int)nread); + } + return nread; +} + static const char *sftp_libssh2_strerror(unsigned long err) -{ - switch(err) { - case LIBSSH2_FX_NO_SUCH_FILE: - return "No such file or directory"; - - case LIBSSH2_FX_PERMISSION_DENIED: - return "Permission denied"; - - case LIBSSH2_FX_FAILURE: - return "Operation failed"; - - case LIBSSH2_FX_BAD_MESSAGE: - return "Bad message from SFTP server"; - - case LIBSSH2_FX_NO_CONNECTION: - return "Not connected to SFTP server"; - - case LIBSSH2_FX_CONNECTION_LOST: - return "Connection to SFTP server lost"; - - case LIBSSH2_FX_OP_UNSUPPORTED: - return "Operation not supported by SFTP server"; - - case LIBSSH2_FX_INVALID_HANDLE: - return "Invalid handle"; - - case LIBSSH2_FX_NO_SUCH_PATH: - return "No such file or directory"; - - case LIBSSH2_FX_FILE_ALREADY_EXISTS: - return "File already exists"; - - case LIBSSH2_FX_WRITE_PROTECT: - return "File is write protected"; - - case LIBSSH2_FX_NO_MEDIA: - return "No media"; - - case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: - return "Disk full"; - - case LIBSSH2_FX_QUOTA_EXCEEDED: - return "User quota exceeded"; - - case LIBSSH2_FX_UNKNOWN_PRINCIPLE: - return "Unknown principle"; - - case LIBSSH2_FX_LOCK_CONFlICT: - return "File lock conflict"; - - case LIBSSH2_FX_DIR_NOT_EMPTY: - return "Directory not empty"; - - case LIBSSH2_FX_NOT_A_DIRECTORY: - return "Not a directory"; - - case LIBSSH2_FX_INVALID_FILENAME: - return "Invalid filename"; - - case LIBSSH2_FX_LINK_LOOP: - return "Link points to itself"; - } - return "Unknown error in libssh2"; -} - -CURLcode Curl_ssh_init(void) -{ -#ifdef HAVE_LIBSSH2_INIT - if(libssh2_init(0)) { - DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n")); - return CURLE_FAILED_INIT; - } -#endif - return CURLE_OK; -} - -void Curl_ssh_cleanup(void) -{ -#ifdef HAVE_LIBSSH2_EXIT - (void)libssh2_exit(); -#endif -} - -size_t Curl_ssh_version(char *buffer, size_t buflen) -{ - return msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION); -} - -#endif /* USE_LIBSSH2 */ +{ + switch(err) { + case LIBSSH2_FX_NO_SUCH_FILE: + return "No such file or directory"; + + case LIBSSH2_FX_PERMISSION_DENIED: + return "Permission denied"; + + case LIBSSH2_FX_FAILURE: + return "Operation failed"; + + case LIBSSH2_FX_BAD_MESSAGE: + return "Bad message from SFTP server"; + + case LIBSSH2_FX_NO_CONNECTION: + return "Not connected to SFTP server"; + + case LIBSSH2_FX_CONNECTION_LOST: + return "Connection to SFTP server lost"; + + case LIBSSH2_FX_OP_UNSUPPORTED: + return "Operation not supported by SFTP server"; + + case LIBSSH2_FX_INVALID_HANDLE: + return "Invalid handle"; + + case LIBSSH2_FX_NO_SUCH_PATH: + return "No such file or directory"; + + case LIBSSH2_FX_FILE_ALREADY_EXISTS: + return "File already exists"; + + case LIBSSH2_FX_WRITE_PROTECT: + return "File is write protected"; + + case LIBSSH2_FX_NO_MEDIA: + return "No media"; + + case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: + return "Disk full"; + + case LIBSSH2_FX_QUOTA_EXCEEDED: + return "User quota exceeded"; + + case LIBSSH2_FX_UNKNOWN_PRINCIPLE: + return "Unknown principle"; + + case LIBSSH2_FX_LOCK_CONFlICT: + return "File lock conflict"; + + case LIBSSH2_FX_DIR_NOT_EMPTY: + return "Directory not empty"; + + case LIBSSH2_FX_NOT_A_DIRECTORY: + return "Not a directory"; + + case LIBSSH2_FX_INVALID_FILENAME: + return "Invalid filename"; + + case LIBSSH2_FX_LINK_LOOP: + return "Link points to itself"; + } + return "Unknown error in libssh2"; +} + +CURLcode Curl_ssh_init(void) +{ +#ifdef HAVE_LIBSSH2_INIT + if(libssh2_init(0)) { + DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n")); + return CURLE_FAILED_INIT; + } +#endif + return CURLE_OK; +} + +void Curl_ssh_cleanup(void) +{ +#ifdef HAVE_LIBSSH2_EXIT + (void)libssh2_exit(); +#endif +} + +size_t Curl_ssh_version(char *buffer, size_t buflen) +{ + return msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION); +} + +#endif /* USE_LIBSSH2 */ diff --git a/contrib/libs/curl/lib/vtls/gskit.c b/contrib/libs/curl/lib/vtls/gskit.c index b58bd270de..17584c750f 100644 --- a/contrib/libs/curl/lib/vtls/gskit.c +++ b/contrib/libs/curl/lib/vtls/gskit.c @@ -645,7 +645,7 @@ static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf, CURLcode cc = CURLE_RECV_ERROR; if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) { - int buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize; + int buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize; cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle, buf, buffsize, &nread), "gsk_secure_soc_read()", CURLE_RECV_ERROR); @@ -990,8 +990,8 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex) &cdev, &cdec), "gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) == CURLE_OK) { - int i; - + int i; + infof(data, "Server certificate:\n"); p = cdev; for(i = 0; i++ < cdec; p++) @@ -1173,10 +1173,10 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex) if(!BACKEND->handle) return 0; -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) return 0; -#endif +#endif close_one(connssl, conn, sockindex); rc = 0; @@ -1184,8 +1184,8 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex) SSL_SHUTDOWN_TIMEOUT); for(;;) { - ssize_t nread; - + ssize_t nread; + if(what < 0) { /* anything that gets here is fatally bad */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); diff --git a/contrib/libs/curl/lib/vtls/gtls.c b/contrib/libs/curl/lib/vtls/gtls.c index ce654828ab..e848c3f05a 100644 --- a/contrib/libs/curl/lib/vtls/gtls.c +++ b/contrib/libs/curl/lib/vtls/gtls.c @@ -55,7 +55,7 @@ #include "strcase.h" #include "warnless.h" #include "x509asn1.h" -#include "multiif.h" +#include "multiif.h" #include "curl_printf.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -213,8 +213,8 @@ static CURLcode handshake(struct connectdata *conn, for(;;) { timediff_t timeout_ms; - int rc; - + int rc; + /* check allowed time left */ timeout_ms = Curl_timeleft(data, NULL, duringconnect); @@ -227,7 +227,7 @@ static CURLcode handshake(struct connectdata *conn, /* if ssl is expecting something, check if it's available. */ if(connssl->connecting_state == ssl_connect_2_reading || connssl->connecting_state == ssl_connect_2_writing) { - int what; + int what; curl_socket_t writefd = ssl_connect_2_writing == connssl->connecting_state?sockfd:CURL_SOCKET_BAD; curl_socket_t readfd = ssl_connect_2_reading == @@ -766,8 +766,8 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, return result; do { - int ret; - + int ret; + /* Begin Gyrations to get the public key */ gnutls_pubkey_init(&key); @@ -1081,7 +1081,7 @@ gtls_connect_step3(struct connectdata *conn, #define use_addr in_addr #endif unsigned char addrbuf[sizeof(struct use_addr)]; - size_t addrlen = 0; + size_t addrlen = 0; if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0) addrlen = 4; @@ -1091,13 +1091,13 @@ gtls_connect_step3(struct connectdata *conn, #endif if(addrlen) { - unsigned char certaddr[sizeof(struct use_addr)]; - int i; - + unsigned char certaddr[sizeof(struct use_addr)]; + int i; + for(i = 0; ; i++) { - size_t certaddrlen = sizeof(certaddr); - int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr, - &certaddrlen, NULL); + size_t certaddrlen = sizeof(certaddr); + int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr, + &certaddrlen, NULL); /* If this happens, it wasn't an IP address. */ if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) continue; @@ -1262,9 +1262,9 @@ gtls_connect_step3(struct connectdata *conn, } else infof(data, "ALPN, server did not agree to a protocol\n"); - - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } conn->ssl[sockindex].state = ssl_connection_complete; @@ -1284,9 +1284,9 @@ gtls_connect_step3(struct connectdata *conn, connect_sessionid = malloc(connect_idsize); /* get a buffer for it */ if(connect_sessionid) { - bool incache; - void *ssl_sessionid; - + bool incache; + void *ssl_sessionid; + /* extract session ID to the allocated buffer */ gnutls_session_get_data(session, connect_sessionid, &connect_idsize); @@ -1459,7 +1459,7 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) int retval = 0; struct Curl_easy *data = conn->data; -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP /* This has only been tested on the proftpd server, and the mod_tls code sends a close notify alert without waiting for a close notify alert in response. Thus we wait for a close notify alert from the server, but @@ -1467,13 +1467,13 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) gnutls_bye(backend->session, GNUTLS_SHUT_WR); -#endif +#endif if(backend->session) { - ssize_t result; - bool done = FALSE; - char buf[120]; - + ssize_t result; + bool done = FALSE; + char buf[120]; + while(!done) { int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); diff --git a/contrib/libs/curl/lib/vtls/mbedtls.c b/contrib/libs/curl/lib/vtls/mbedtls.c index 626ffea919..e30f660fbb 100644 --- a/contrib/libs/curl/lib/vtls/mbedtls.c +++ b/contrib/libs/curl/lib/vtls/mbedtls.c @@ -63,7 +63,7 @@ #include "parsedate.h" #include "connect.h" /* for the connect timeout */ #include "select.h" -#include "multiif.h" +#include "multiif.h" #error #include "mbedtls_threadlock.h" /* The last 3 #include files should be in this order */ @@ -386,7 +386,7 @@ mbed_connect_step1(struct connectdata *conn, } } - infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port); + infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port); mbedtls_ssl_config_init(&backend->config); @@ -572,8 +572,8 @@ mbed_connect_step2(struct connectdata *conn, return CURLE_OK; } else if(ret) { - char errorbuf[128]; - errorbuf[0] = 0; + char errorbuf[128]; + errorbuf[0] = 0; #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ @@ -588,21 +588,21 @@ mbed_connect_step2(struct connectdata *conn, ret = mbedtls_ssl_get_verify_result(&backend->ssl); - if(!SSL_CONN_CONFIG(verifyhost)) - /* Ignore hostname errors if verifyhost is disabled */ - ret &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH; - + if(!SSL_CONN_CONFIG(verifyhost)) + /* Ignore hostname errors if verifyhost is disabled */ + ret &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH; + if(ret && SSL_CONN_CONFIG(verifypeer)) { if(ret & MBEDTLS_X509_BADCERT_EXPIRED) failf(data, "Cert verify failed: BADCERT_EXPIRED"); - else if(ret & MBEDTLS_X509_BADCERT_REVOKED) + else if(ret & MBEDTLS_X509_BADCERT_REVOKED) failf(data, "Cert verify failed: BADCERT_REVOKED"); - else if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) + else if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); - else if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED) + else if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED) failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); else if(ret & MBEDTLS_X509_BADCERT_FUTURE) @@ -701,8 +701,8 @@ mbed_connect_step2(struct connectdata *conn, else { infof(data, "ALPN, server did not agree to a protocol\n"); } - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } #endif @@ -736,8 +736,8 @@ mbed_connect_step3(struct connectdata *conn, ret = mbedtls_ssl_get_session(&backend->ssl, our_ssl_sessionid); if(ret) { - if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED) - mbedtls_ssl_session_free(our_ssl_sessionid); + if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED) + mbedtls_ssl_session_free(our_ssl_sessionid); free(our_ssl_sessionid); failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret); return CURLE_SSL_CONNECT_ERROR; @@ -751,7 +751,7 @@ mbed_connect_step3(struct connectdata *conn, retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex); Curl_ssl_sessionid_unlock(conn); if(retcode) { - mbedtls_ssl_session_free(our_ssl_sessionid); + mbedtls_ssl_session_free(our_ssl_sessionid); free(our_ssl_sessionid); failf(data, "failed to store ssl session"); return retcode; @@ -839,14 +839,14 @@ static void Curl_mbedtls_session_free(void *ptr) static size_t Curl_mbedtls_version(char *buffer, size_t size) { -#ifdef MBEDTLS_VERSION_C - /* if mbedtls_version_get_number() is available it is better */ +#ifdef MBEDTLS_VERSION_C + /* if mbedtls_version_get_number() is available it is better */ unsigned int version = mbedtls_version_get_number(); return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24, (version>>16)&0xff, (version>>8)&0xff); -#else - return msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING); -#endif +#else + return msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING); +#endif } static CURLcode Curl_mbedtls_random(struct Curl_easy *data, diff --git a/contrib/libs/curl/lib/vtls/mesalink.c b/contrib/libs/curl/lib/vtls/mesalink.c index 134e218800..309786cf83 100644 --- a/contrib/libs/curl/lib/vtls/mesalink.c +++ b/contrib/libs/curl/lib/vtls/mesalink.c @@ -73,17 +73,17 @@ struct ssl_backend_data static Curl_recv mesalink_recv; static Curl_send mesalink_send; -static int do_file_type(const char *type) -{ - if(!type || !type[0]) - return SSL_FILETYPE_PEM; - if(strcasecompare(type, "PEM")) - return SSL_FILETYPE_PEM; - if(strcasecompare(type, "DER")) - return SSL_FILETYPE_ASN1; - return -1; -} - +static int do_file_type(const char *type) +{ + if(!type || !type[0]) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "PEM")) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "DER")) + return SSL_FILETYPE_ASN1; + return -1; +} + /* * This function loads all the client/CA certificates and CRLs. Setup the TLS * layer and do all necessary magic. @@ -150,25 +150,25 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex) } SSL_CTX_set_verify( - BACKEND->ctx, SSL_CONN_CONFIG(verifypeer) ? - SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); + BACKEND->ctx, SSL_CONN_CONFIG(verifypeer) ? + SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); - if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath)) { - if(!SSL_CTX_load_verify_locations(BACKEND->ctx, SSL_CONN_CONFIG(CAfile), - SSL_CONN_CONFIG(CApath))) { - if(SSL_CONN_CONFIG(verifypeer)) { + if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath)) { + if(!SSL_CTX_load_verify_locations(BACKEND->ctx, SSL_CONN_CONFIG(CAfile), + SSL_CONN_CONFIG(CApath))) { + if(SSL_CONN_CONFIG(verifypeer)) { failf(data, "error setting certificate verify locations: " " CAfile: %s CApath: %s", - SSL_CONN_CONFIG(CAfile) ? - SSL_CONN_CONFIG(CAfile) : "none", - SSL_CONN_CONFIG(CApath) ? - SSL_CONN_CONFIG(CApath) : "none"); + SSL_CONN_CONFIG(CAfile) ? + SSL_CONN_CONFIG(CAfile) : "none", + SSL_CONN_CONFIG(CApath) ? + SSL_CONN_CONFIG(CApath) : "none"); return CURLE_SSL_CACERT_BADFILE; } infof(data, - "error setting certificate verify locations," - " continuing anyway:\n"); + "error setting certificate verify locations," + " continuing anyway:\n"); } else { infof(data, "successfully set certificate verify locations:\n"); @@ -180,28 +180,28 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex) } if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) { - int file_type = do_file_type(SSL_SET_OPTION(cert_type)); - + int file_type = do_file_type(SSL_SET_OPTION(cert_type)); + if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx, SSL_SET_OPTION(primary.clientcert), file_type) != 1) { - failf(data, "unable to use client certificate (no key or wrong pass" - " phrase?)"); - return CURLE_SSL_CONNECT_ERROR; - } - - file_type = do_file_type(SSL_SET_OPTION(key_type)); - if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key), - file_type) != 1) { - failf(data, "unable to set private key"); - return CURLE_SSL_CONNECT_ERROR; - } - infof(data, - "client cert: %s\n", - SSL_CONN_CONFIG(clientcert)? - SSL_CONN_CONFIG(clientcert): "none"); - } - + failf(data, "unable to use client certificate (no key or wrong pass" + " phrase?)"); + return CURLE_SSL_CONNECT_ERROR; + } + + file_type = do_file_type(SSL_SET_OPTION(key_type)); + if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key), + file_type) != 1) { + failf(data, "unable to set private key"); + return CURLE_SSL_CONNECT_ERROR; + } + infof(data, + "client cert: %s\n", + SSL_CONN_CONFIG(clientcert)? + SSL_CONN_CONFIG(clientcert): "none"); + } + ciphers = SSL_CONN_CONFIG(cipher_list); if(ciphers) { #ifdef MESALINK_HAVE_CIPHER @@ -301,12 +301,12 @@ mesalink_connect_step2(struct connectdata *conn, int sockindex) if(ret != SSL_SUCCESS) { int detail = SSL_get_error(BACKEND->handle, ret); - if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) { + if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) { connssl->connecting_state = ssl_connect_2_reading; return CURLE_OK; } else { - char error_buffer[MESALINK_MAX_ERROR_SZ]; + char error_buffer[MESALINK_MAX_ERROR_SZ]; failf(data, "SSL_connect failed with error %d: %s", detail, diff --git a/contrib/libs/curl/lib/vtls/nss.c b/contrib/libs/curl/lib/vtls/nss.c index c2fab14914..59649ccc3a 100644 --- a/contrib/libs/curl/lib/vtls/nss.c +++ b/contrib/libs/curl/lib/vtls/nss.c @@ -38,7 +38,7 @@ #include "select.h" #include "vtls.h" #include "llist.h" -#include "multiif.h" +#include "multiif.h" #include "curl_printf.h" #include "nssg.h" #include <nspr.h> @@ -214,19 +214,19 @@ static const struct cipher_s cipherlist[] = { {"dhe_rsa_chacha20_poly1305_sha_256", TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, #endif -#ifdef TLS_AES_256_GCM_SHA384 - {"aes_128_gcm_sha_256", TLS_AES_128_GCM_SHA256}, - {"aes_256_gcm_sha_384", TLS_AES_256_GCM_SHA384}, - {"chacha20_poly1305_sha_256", TLS_CHACHA20_POLY1305_SHA256}, -#endif +#ifdef TLS_AES_256_GCM_SHA384 + {"aes_128_gcm_sha_256", TLS_AES_128_GCM_SHA256}, + {"aes_256_gcm_sha_384", TLS_AES_256_GCM_SHA384}, + {"chacha20_poly1305_sha_256", TLS_CHACHA20_POLY1305_SHA256}, +#endif }; -#if defined(WIN32) +#if defined(WIN32) static const char *pem_library = "nsspem.dll"; static const char *trust_library = "nssckbi.dll"; -#elif defined(__APPLE__) -static const char *pem_library = "libnsspem.dylib"; -static const char *trust_library = "libnssckbi.dylib"; +#elif defined(__APPLE__) +static const char *pem_library = "libnsspem.dylib"; +static const char *trust_library = "libnssckbi.dylib"; #else static const char *pem_library = "libnsspem.so"; static const char *trust_library = "libnssckbi.so"; @@ -384,7 +384,7 @@ static int is_file(const char *filename) return 0; if(stat(filename, &st) == 0) - if(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISCHR(st.st_mode)) + if(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISCHR(st.st_mode)) return 1; return 0; @@ -580,19 +580,19 @@ static CURLcode nss_cache_crl(SECItem *crl_der) /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */ PR_Lock(nss_crllock); - if(SECSuccess != CERT_CacheCRL(db, crl_der)) { - /* unable to cache CRL */ + if(SECSuccess != CERT_CacheCRL(db, crl_der)) { + /* unable to cache CRL */ SECITEM_FreeItem(crl_der, PR_TRUE); PR_Unlock(nss_crllock); - return CURLE_SSL_CRL_BADFILE; + return CURLE_SSL_CRL_BADFILE; } - /* store the CRL item so that we can free it in Curl_nss_cleanup() */ - if(insert_wrapped_ptr(&nss_crl_list, crl_der) != CURLE_OK) { - if(SECSuccess == CERT_UncacheCRL(db, crl_der)) - SECITEM_FreeItem(crl_der, PR_TRUE); + /* store the CRL item so that we can free it in Curl_nss_cleanup() */ + if(insert_wrapped_ptr(&nss_crl_list, crl_der) != CURLE_OK) { + if(SECSuccess == CERT_UncacheCRL(db, crl_der)) + SECITEM_FreeItem(crl_der, PR_TRUE); PR_Unlock(nss_crllock); - return CURLE_OUT_OF_MEMORY; + return CURLE_OUT_OF_MEMORY; } /* we need to clear session cache, so that the CRL could take effect */ @@ -690,10 +690,10 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex, tmp = SECMOD_WaitForAnyTokenEvent(pem_module, 0, 0); if(tmp) PK11_FreeSlot(tmp); - if(!PK11_IsPresent(slot)) { - PK11_FreeSlot(slot); - return CURLE_SSL_CERTPROBLEM; - } + if(!PK11_IsPresent(slot)) { + PK11_FreeSlot(slot); + return CURLE_SSL_CERTPROBLEM; + } status = PK11_Authenticate(slot, PR_TRUE, SSL_SET_OPTION(key_passwd)); PK11_FreeSlot(slot); @@ -856,8 +856,8 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg) !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) { conn->negnpn = CURL_HTTP_VERSION_1_1; } - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } } @@ -1319,8 +1319,8 @@ static void nss_unload_module(SECMODModule **pmod) static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir) { NSSInitParameters initparams; - PRErrorCode err; - const char *err_name; + PRErrorCode err; + const char *err_name; if(nss_context != NULL) return CURLE_OK; @@ -1341,9 +1341,9 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir) if(nss_context != NULL) return CURLE_OK; - err = PR_GetError(); - err_name = nss_error_to_name(err); - infof(data, "Unable to initialize NSS database: %d (%s)\n", err, err_name); + err = PR_GetError(); + err_name = nss_error_to_name(err); + infof(data, "Unable to initialize NSS database: %d (%s)\n", err, err_name); } infof(data, "Initializing NSS with certpath: none\n"); @@ -1353,9 +1353,9 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir) if(nss_context != NULL) return CURLE_OK; - err = PR_GetError(); - err_name = nss_error_to_name(err); - failf(data, "Unable to initialize NSS: %d (%s)", err, err_name); + err = PR_GetError(); + err_name = nss_error_to_name(err); + failf(data, "Unable to initialize NSS: %d (%s)", err, err_name); return CURLE_SSL_CACERT_BADFILE; } @@ -1427,7 +1427,7 @@ static int Curl_nss_init(void) { /* curl_global_init() is not thread-safe so this test is ok */ if(nss_initlock == NULL) { - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); nss_initlock = PR_NewLock(); nss_crllock = PR_NewLock(); nss_findslot_lock = PR_NewLock(); @@ -1743,16 +1743,16 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver, CURLcode result; const long min = SSL_CONN_CONFIG(version); const long max = SSL_CONN_CONFIG(version_max); - SSLVersionRange vrange; + SSLVersionRange vrange; switch(min) { case CURL_SSLVERSION_TLSv1: case CURL_SSLVERSION_DEFAULT: - /* Bump our minimum TLS version if NSS has stricter requirements. */ - if(SSL_VersionRangeGetDefault(ssl_variant_stream, &vrange) != SECSuccess) - return CURLE_SSL_CONNECT_ERROR; - if(sslver->min < vrange.min) - sslver->min = vrange.min; + /* Bump our minimum TLS version if NSS has stricter requirements. */ + if(SSL_VersionRangeGetDefault(ssl_variant_stream, &vrange) != SECSuccess) + return CURLE_SSL_CONNECT_ERROR; + if(sslver->min < vrange.min) + sslver->min = vrange.min; break; default: result = nss_sslver_from_curl(&sslver->min, min); diff --git a/contrib/libs/curl/lib/vtls/openssl.c b/contrib/libs/curl/lib/vtls/openssl.c index c154398027..e9c535f8f4 100644 --- a/contrib/libs/curl/lib/vtls/openssl.c +++ b/contrib/libs/curl/lib/vtls/openssl.c @@ -56,7 +56,7 @@ #include "keylog.h" #include "strcase.h" #include "hostcheck.h" -#include "multiif.h" +#include "multiif.h" #include "strerror.h" #include "curl_printf.h" @@ -76,16 +76,16 @@ #include <openssl/buffer.h> #include <openssl/pkcs12.h> -#ifdef USE_AMISSL -#include "amigaos.h" -#endif - +#ifdef USE_AMISSL +#include "amigaos.h" +#endif + #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP) #include <openssl/ocsp.h> #endif #if (OPENSSL_VERSION_NUMBER >= 0x0090700fL) && /* 0.9.7 or later */ \ - !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_UI_CONSOLE) + !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_UI_CONSOLE) #define USE_OPENSSL_ENGINE #include <openssl/engine.h> #endif @@ -162,10 +162,10 @@ #define HAVE_X509_GET0_SIGNATURE 1 #endif -#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */ -#define HAVE_SSL_GET_SHUTDOWN 1 -#endif - +#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */ +#define HAVE_SSL_GET_SHUTDOWN 1 +#endif + #if OPENSSL_VERSION_NUMBER >= 0x10002003L && \ OPENSSL_VERSION_NUMBER <= 0x10002FFFL && \ !defined(OPENSSL_NO_COMP) @@ -348,11 +348,11 @@ static char *ossl_strerror(unsigned long error, char *buf, size_t size) if(size) *buf = '\0'; -#ifdef OPENSSL_IS_BORINGSSL - ERR_error_string_n((uint32_t)error, buf, size); -#else +#ifdef OPENSSL_IS_BORINGSSL + ERR_error_string_n((uint32_t)error, buf, size); +#else ERR_error_string_n(error, buf, size); -#endif +#endif if(size > 1 && !*buf) { strncpy(buf, (error ? "Unknown error" : "No error"), size); @@ -927,11 +927,11 @@ int cert_stuff(struct connectdata *conn, fail: EVP_PKEY_free(pri); X509_free(x509); -#ifdef USE_AMISSL - sk_X509_pop_free(ca, Curl_amiga_X509_free); -#else +#ifdef USE_AMISSL + sk_X509_pop_free(ca, Curl_amiga_X509_free); +#else sk_X509_pop_free(ca, X509_free); -#endif +#endif if(!cert_done) return 0; /* failure! */ break; @@ -942,11 +942,11 @@ int cert_stuff(struct connectdata *conn, } if((!key_file) && (!key_bio)) { - key_file = cert_file; + key_file = cert_file; key_bio = cert_bio; } - else - file_type = do_file_type(key_type); + else + file_type = do_file_type(key_type); switch(file_type) { case SSL_FILETYPE_PEM: @@ -1136,8 +1136,8 @@ static int Curl_ossl_init(void) ENGINE_load_builtin_engines(); #endif -/* CONF_MFLAGS_DEFAULT_SECTION was introduced some time between 0.9.8b and - 0.9.8e */ +/* CONF_MFLAGS_DEFAULT_SECTION was introduced some time between 0.9.8b and + 0.9.8e */ #ifndef CONF_MFLAGS_DEFAULT_SECTION #define CONF_MFLAGS_DEFAULT_SECTION 0x0 #endif @@ -1391,7 +1391,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) bool done = FALSE; struct ssl_backend_data *backend = connssl->backend; -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP /* This has only been tested on the proftpd server, and the mod_tls code sends a close notify alert without waiting for a close notify alert in response. Thus we wait for a close notify alert from the server, but @@ -1399,7 +1399,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) (void)SSL_shutdown(backend->handle); -#endif +#endif if(backend->handle) { buffsize = (int)sizeof(buf); @@ -1617,13 +1617,13 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL); if(altnames) { -#ifdef OPENSSL_IS_BORINGSSL - size_t numalts; - size_t i; -#else +#ifdef OPENSSL_IS_BORINGSSL + size_t numalts; + size_t i; +#else int numalts; int i; -#endif +#endif bool dnsmatched = FALSE; bool ipmatched = FALSE; @@ -1653,9 +1653,9 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) assumed that the data returned by ASN1_STRING_data() is null terminated or does not contain embedded nulls." But also that "The actual format of the data will depend on the actual string - type itself: for example for an IA5String the data will be ASCII" + type itself: for example for an IA5String the data will be ASCII" - It has been however verified that in 0.9.6 and 0.9.7, IA5String + It has been however verified that in 0.9.6 and 0.9.7, IA5String is always null-terminated. */ if((altlen == strlen(altptr)) && @@ -1720,7 +1720,7 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input is already UTF-8 encoded. We check for this case and copy the raw string manually to avoid the problem. This code can be made - conditional in the future when OpenSSL has been fixed. */ + conditional in the future when OpenSSL has been fixed. */ if(tmp) { if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) { j = ASN1_STRING_length(tmp); @@ -1786,7 +1786,7 @@ static CURLcode verifystatus(struct connectdata *conn, struct ssl_connect_data *connssl) { int i, ocsp_status; - unsigned char *status; + unsigned char *status; const unsigned char *p; CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; @@ -1803,12 +1803,12 @@ static CURLcode verifystatus(struct connectdata *conn, long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status); - if(!status) { + if(!status) { failf(data, "No OCSP response received"); result = CURLE_SSL_INVALIDCERTSTATUS; goto end; } - p = status; + p = status; rsp = d2i_OCSP_RESPONSE(NULL, &p, len); if(!rsp) { failf(data, "Invalid OCSP response"); @@ -2266,101 +2266,101 @@ get_ssl_version_txt(SSL *ssl) } #endif -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ static CURLcode -set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn) +set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn) { - /* first, TLS min version... */ - long curl_ssl_version_min = SSL_CONN_CONFIG(version); - long curl_ssl_version_max; - - /* convert cURL min SSL version option to OpenSSL constant */ + /* first, TLS min version... */ + long curl_ssl_version_min = SSL_CONN_CONFIG(version); + long curl_ssl_version_max; + + /* convert cURL min SSL version option to OpenSSL constant */ #if defined(OPENSSL_IS_BORINGSSL) || defined(LIBRESSL_VERSION_NUMBER) uint16_t ossl_ssl_version_min = 0; uint16_t ossl_ssl_version_max = 0; #else - long ossl_ssl_version_min = 0; - long ossl_ssl_version_max = 0; -#endif - switch(curl_ssl_version_min) { - case CURL_SSLVERSION_TLSv1: /* TLS 1.x */ - case CURL_SSLVERSION_TLSv1_0: - ossl_ssl_version_min = TLS1_VERSION; - break; - case CURL_SSLVERSION_TLSv1_1: - ossl_ssl_version_min = TLS1_1_VERSION; - break; - case CURL_SSLVERSION_TLSv1_2: - ossl_ssl_version_min = TLS1_2_VERSION; - break; -#ifdef TLS1_3_VERSION - case CURL_SSLVERSION_TLSv1_3: - ossl_ssl_version_min = TLS1_3_VERSION; - break; -#endif - } - - /* CURL_SSLVERSION_DEFAULT means that no option was selected. + long ossl_ssl_version_min = 0; + long ossl_ssl_version_max = 0; +#endif + switch(curl_ssl_version_min) { + case CURL_SSLVERSION_TLSv1: /* TLS 1.x */ + case CURL_SSLVERSION_TLSv1_0: + ossl_ssl_version_min = TLS1_VERSION; + break; + case CURL_SSLVERSION_TLSv1_1: + ossl_ssl_version_min = TLS1_1_VERSION; + break; + case CURL_SSLVERSION_TLSv1_2: + ossl_ssl_version_min = TLS1_2_VERSION; + break; +#ifdef TLS1_3_VERSION + case CURL_SSLVERSION_TLSv1_3: + ossl_ssl_version_min = TLS1_3_VERSION; + break; +#endif + } + + /* CURL_SSLVERSION_DEFAULT means that no option was selected. We don't want to pass 0 to SSL_CTX_set_min_proto_version as it would enable all versions down to the lowest supported by the library. So we skip this, and stay with the OS default - */ - if(curl_ssl_version_min != CURL_SSLVERSION_DEFAULT) { - if(!SSL_CTX_set_min_proto_version(ctx, ossl_ssl_version_min)) { - return CURLE_SSL_CONNECT_ERROR; - } - } - - /* ... then, TLS max version */ - curl_ssl_version_max = SSL_CONN_CONFIG(version_max); - - /* convert cURL max SSL version option to OpenSSL constant */ - switch(curl_ssl_version_max) { - case CURL_SSLVERSION_MAX_TLSv1_0: - ossl_ssl_version_max = TLS1_VERSION; - break; - case CURL_SSLVERSION_MAX_TLSv1_1: - ossl_ssl_version_max = TLS1_1_VERSION; - break; - case CURL_SSLVERSION_MAX_TLSv1_2: - ossl_ssl_version_max = TLS1_2_VERSION; - break; -#ifdef TLS1_3_VERSION - case CURL_SSLVERSION_MAX_TLSv1_3: - ossl_ssl_version_max = TLS1_3_VERSION; - break; -#endif - case CURL_SSLVERSION_MAX_NONE: /* none selected */ - case CURL_SSLVERSION_MAX_DEFAULT: /* max selected */ - default: - /* SSL_CTX_set_max_proto_version states that: - setting the maximum to 0 will enable - protocol versions up to the highest version - supported by the library */ - ossl_ssl_version_max = 0; - break; - } - - if(!SSL_CTX_set_max_proto_version(ctx, ossl_ssl_version_max)) { - return CURLE_SSL_CONNECT_ERROR; - } - - return CURLE_OK; -} -#endif - -#ifdef OPENSSL_IS_BORINGSSL -typedef uint32_t ctx_option_t; -#else -typedef long ctx_option_t; -#endif - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */ -static CURLcode -set_ssl_version_min_max_legacy(ctx_option_t *ctx_options, - struct connectdata *conn, int sockindex) -{ + */ + if(curl_ssl_version_min != CURL_SSLVERSION_DEFAULT) { + if(!SSL_CTX_set_min_proto_version(ctx, ossl_ssl_version_min)) { + return CURLE_SSL_CONNECT_ERROR; + } + } + + /* ... then, TLS max version */ + curl_ssl_version_max = SSL_CONN_CONFIG(version_max); + + /* convert cURL max SSL version option to OpenSSL constant */ + switch(curl_ssl_version_max) { + case CURL_SSLVERSION_MAX_TLSv1_0: + ossl_ssl_version_max = TLS1_VERSION; + break; + case CURL_SSLVERSION_MAX_TLSv1_1: + ossl_ssl_version_max = TLS1_1_VERSION; + break; + case CURL_SSLVERSION_MAX_TLSv1_2: + ossl_ssl_version_max = TLS1_2_VERSION; + break; +#ifdef TLS1_3_VERSION + case CURL_SSLVERSION_MAX_TLSv1_3: + ossl_ssl_version_max = TLS1_3_VERSION; + break; +#endif + case CURL_SSLVERSION_MAX_NONE: /* none selected */ + case CURL_SSLVERSION_MAX_DEFAULT: /* max selected */ + default: + /* SSL_CTX_set_max_proto_version states that: + setting the maximum to 0 will enable + protocol versions up to the highest version + supported by the library */ + ossl_ssl_version_max = 0; + break; + } + + if(!SSL_CTX_set_max_proto_version(ctx, ossl_ssl_version_max)) { + return CURLE_SSL_CONNECT_ERROR; + } + + return CURLE_OK; +} +#endif + +#ifdef OPENSSL_IS_BORINGSSL +typedef uint32_t ctx_option_t; +#else +typedef long ctx_option_t; +#endif + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */ +static CURLcode +set_ssl_version_min_max_legacy(ctx_option_t *ctx_options, + struct connectdata *conn, int sockindex) +{ #if (OPENSSL_VERSION_NUMBER < 0x1000100FL) || !defined(TLS1_3_VERSION) /* convoluted #if condition just to avoid compiler warnings on unused variable */ @@ -2431,7 +2431,7 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options, } return CURLE_OK; } -#endif +#endif /* The "new session" callback must return zero if the session can be removed * or non-zero if the session has been put into the session cache. @@ -2498,8 +2498,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) X509_LOOKUP *lookup = NULL; curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - ctx_option_t ctx_options = 0; - + ctx_option_t ctx_options = 0; + #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME bool sni; const char * const hostname = SSL_HOST_NAME(); @@ -2663,66 +2663,66 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) #endif switch(ssl_version) { - /* "--sslv2" option means SSLv2 only, disable all others */ - case CURL_SSLVERSION_SSLv2: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ + /* "--sslv2" option means SSLv2 only, disable all others */ + case CURL_SSLVERSION_SSLv2: +#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION); SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION); -#else - ctx_options |= SSL_OP_NO_SSLv3; - ctx_options |= SSL_OP_NO_TLSv1; -# if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -# ifdef TLS1_3_VERSION - ctx_options |= SSL_OP_NO_TLSv1_3; -# endif -# endif -#endif - break; - - /* "--sslv3" option means SSLv3 only, disable all others */ - case CURL_SSLVERSION_SSLv3: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ +#else + ctx_options |= SSL_OP_NO_SSLv3; + ctx_options |= SSL_OP_NO_TLSv1; +# if OPENSSL_VERSION_NUMBER >= 0x1000100FL + ctx_options |= SSL_OP_NO_TLSv1_1; + ctx_options |= SSL_OP_NO_TLSv1_2; +# ifdef TLS1_3_VERSION + ctx_options |= SSL_OP_NO_TLSv1_3; +# endif +# endif +#endif + break; + + /* "--sslv3" option means SSLv3 only, disable all others */ + case CURL_SSLVERSION_SSLv3: +#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION); SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION); -#else - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_TLSv1; -# if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -# ifdef TLS1_3_VERSION - ctx_options |= SSL_OP_NO_TLSv1_3; -# endif -# endif -#endif - break; - - /* "--tlsv<x.y>" options mean TLS >= version <x.y> */ - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: /* TLS >= version 1.0 */ - case CURL_SSLVERSION_TLSv1_0: /* TLS >= version 1.0 */ - case CURL_SSLVERSION_TLSv1_1: /* TLS >= version 1.1 */ - case CURL_SSLVERSION_TLSv1_2: /* TLS >= version 1.2 */ - case CURL_SSLVERSION_TLSv1_3: /* TLS >= version 1.3 */ - /* asking for any TLS version as the minimum, means no SSL versions - allowed */ - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_SSLv3; - -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ +#else + ctx_options |= SSL_OP_NO_SSLv2; + ctx_options |= SSL_OP_NO_TLSv1; +# if OPENSSL_VERSION_NUMBER >= 0x1000100FL + ctx_options |= SSL_OP_NO_TLSv1_1; + ctx_options |= SSL_OP_NO_TLSv1_2; +# ifdef TLS1_3_VERSION + ctx_options |= SSL_OP_NO_TLSv1_3; +# endif +# endif +#endif + break; + + /* "--tlsv<x.y>" options mean TLS >= version <x.y> */ + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: /* TLS >= version 1.0 */ + case CURL_SSLVERSION_TLSv1_0: /* TLS >= version 1.0 */ + case CURL_SSLVERSION_TLSv1_1: /* TLS >= version 1.1 */ + case CURL_SSLVERSION_TLSv1_2: /* TLS >= version 1.2 */ + case CURL_SSLVERSION_TLSv1_3: /* TLS >= version 1.3 */ + /* asking for any TLS version as the minimum, means no SSL versions + allowed */ + ctx_options |= SSL_OP_NO_SSLv2; + ctx_options |= SSL_OP_NO_SSLv3; + +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ result = set_ssl_version_min_max(backend->ctx, conn); -#else - result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex); +#else + result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex); #endif - if(result != CURLE_OK) - return result; - break; + if(result != CURLE_OK) + return result; + break; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; } SSL_CTX_set_options(backend->ctx, ctx_options); @@ -3273,12 +3273,12 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) connssl->connecting_state = ssl_connect_2_writing; return CURLE_OK; } -#ifdef SSL_ERROR_WANT_ASYNC - if(SSL_ERROR_WANT_ASYNC == detail) { - connssl->connecting_state = ssl_connect_2; - return CURLE_OK; - } -#endif +#ifdef SSL_ERROR_WANT_ASYNC + if(SSL_ERROR_WANT_ASYNC == detail) { + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; + } +#endif else { /* untreated error */ unsigned long errdetail; @@ -3384,9 +3384,9 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) } else infof(data, "ALPN, server did not agree to a protocol\n"); - - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } #endif @@ -3485,12 +3485,12 @@ static void X509V3_ext(struct Curl_easy *data, } } -#ifdef OPENSSL_IS_BORINGSSL -typedef size_t numcert_t; -#else -typedef int numcert_t; -#endif - +#ifdef OPENSSL_IS_BORINGSSL +typedef size_t numcert_t; +#else +typedef int numcert_t; +#endif + static CURLcode get_cert_chain(struct connectdata *conn, struct ssl_connect_data *connssl) { @@ -3498,7 +3498,7 @@ static CURLcode get_cert_chain(struct connectdata *conn, STACK_OF(X509) *sk; int i; struct Curl_easy *data = conn->data; - numcert_t numcerts; + numcert_t numcerts; BIO *mem; struct ssl_backend_data *backend = connssl->backend; @@ -3509,14 +3509,14 @@ static CURLcode get_cert_chain(struct connectdata *conn, numcerts = sk_X509_num(sk); - result = Curl_ssl_init_certinfo(data, (int)numcerts); + result = Curl_ssl_init_certinfo(data, (int)numcerts); if(result) { return result; } mem = BIO_new(BIO_s_mem()); - for(i = 0; i < (int)numcerts; i++) { + for(i = 0; i < (int)numcerts; i++) { ASN1_INTEGER *num; X509 *x = sk_X509_value(sk, i); EVP_PKEY *pubkey = NULL; @@ -3542,25 +3542,25 @@ static CURLcode get_cert_chain(struct connectdata *conn, #if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS) { - const X509_ALGOR *sigalg = NULL; - X509_PUBKEY *xpubkey = NULL; - ASN1_OBJECT *pubkeyoid = NULL; - - X509_get0_signature(&psig, &sigalg, x); - if(sigalg) { - i2a_ASN1_OBJECT(mem, sigalg->algorithm); - push_certinfo("Signature Algorithm", i); - } - - xpubkey = X509_get_X509_PUBKEY(x); - if(xpubkey) { - X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey); - if(pubkeyoid) { - i2a_ASN1_OBJECT(mem, pubkeyoid); + const X509_ALGOR *sigalg = NULL; + X509_PUBKEY *xpubkey = NULL; + ASN1_OBJECT *pubkeyoid = NULL; + + X509_get0_signature(&psig, &sigalg, x); + if(sigalg) { + i2a_ASN1_OBJECT(mem, sigalg->algorithm); + push_certinfo("Signature Algorithm", i); + } + + xpubkey = X509_get_X509_PUBKEY(x); + if(xpubkey) { + X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey); + if(pubkeyoid) { + i2a_ASN1_OBJECT(mem, pubkeyoid); push_certinfo("Public Key Algorithm", i); } } - + X509V3_ext(data, i, X509_get0_extensions(x)); } #else @@ -3612,7 +3612,7 @@ static CURLcode get_cert_chain(struct connectdata *conn, const BIGNUM *e; RSA_get0_key(rsa, &n, &e, NULL); - BIO_printf(mem, "%d", BN_num_bits(n)); + BIO_printf(mem, "%d", BN_num_bits(n)); push_certinfo("RSA Public Key", i); print_pubkey_BN(rsa, n, i); print_pubkey_BN(rsa, e, i); @@ -4234,9 +4234,9 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ switch(err) { case SSL_ERROR_NONE: /* this is not an error */ - break; + break; case SSL_ERROR_ZERO_RETURN: /* no more data */ - /* close_notify alert */ + /* close_notify alert */ if(num == FIRSTSOCKET) /* mark the connection for close if it is indeed the control connection */ @@ -4324,12 +4324,12 @@ static size_t Curl_ossl_version(char *buffer, size_t size) #endif #elif defined(OPENSSL_IS_BORINGSSL) return msnprintf(buffer, size, OSSL_PACKAGE); -#elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING) - return msnprintf(buffer, size, "%s/%s", - OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); -#else +#elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING) + return msnprintf(buffer, size, "%s/%s", + OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); +#else /* not LibreSSL, BoringSSL and not using OpenSSL_version */ - + char sub[3]; unsigned long ssleay_value; sub[2]='\0'; @@ -4355,11 +4355,11 @@ static size_t Curl_ossl_version(char *buffer, size_t size) sub[0]='\0'; } - return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s" -#ifdef OPENSSL_FIPS - "-fips" -#endif - , + return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s" +#ifdef OPENSSL_FIPS + "-fips" +#endif + , OSSL_PACKAGE, (ssleay_value>>28)&0xf, (ssleay_value>>20)&0xff, diff --git a/contrib/libs/curl/lib/vtls/schannel.c b/contrib/libs/curl/lib/vtls/schannel.c index fe0c9f1122..d7bc38917f 100644 --- a/contrib/libs/curl/lib/vtls/schannel.c +++ b/contrib/libs/curl/lib/vtls/schannel.c @@ -49,7 +49,7 @@ #include "warnless.h" #include "x509asn1.h" #include "curl_printf.h" -#include "multiif.h" +#include "multiif.h" #include "version_win32.h" /* The last #include file should be: */ @@ -316,9 +316,9 @@ get_alg_id_by_name(char *name) #ifdef CALG_ECDSA CIPHEROPTION(CALG_ECDSA); #endif -#ifdef CALG_ECDH_EPHEM - CIPHEROPTION(CALG_ECDH_EPHEM); -#endif +#ifdef CALG_ECDH_EPHEM + CIPHEROPTION(CALG_ECDH_EPHEM); +#endif return 0; } @@ -353,7 +353,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, TCHAR **thumbprint) { TCHAR *sep; - TCHAR *store_path_start; + TCHAR *store_path_start; size_t store_name_len; sep = _tcschr(path, TEXT('\\')); @@ -384,9 +384,9 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, else return CURLE_SSL_CERTPROBLEM; - store_path_start = sep + 1; + store_path_start = sep + 1; - sep = _tcschr(store_path_start, TEXT('\\')); + sep = _tcschr(store_path_start, TEXT('\\')); if(sep == NULL) return CURLE_SSL_CERTPROBLEM; @@ -394,11 +394,11 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) return CURLE_SSL_CERTPROBLEM; - *sep = TEXT('\0'); - *store_path = _tcsdup(store_path_start); - *sep = TEXT('\\'); - if(*store_path == NULL) - return CURLE_OUT_OF_MEMORY; + *sep = TEXT('\0'); + *store_path = _tcsdup(store_path_start); + *sep = TEXT('\\'); + if(*store_path == NULL) + return CURLE_OUT_OF_MEMORY; return CURLE_OK; } @@ -434,9 +434,9 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) char * const hostname = conn->host.name; #endif - DEBUGF(infof(data, - "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", - hostname, conn->remote_port)); + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", + hostname, conn->remote_port)); if(curlx_verify_windows_version(5, 1, PLATFORM_WINNT, VERSION_LESS_THAN_EQUAL)) { @@ -496,13 +496,13 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) Curl_ssl_sessionid_lock(conn); if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) { BACKEND->cred = old_cred; - DEBUGF(infof(data, "schannel: re-using existing credential handle\n")); + DEBUGF(infof(data, "schannel: re-using existing credential handle\n")); /* increment the reference counter of the credential/session handle */ BACKEND->cred->refcount++; - DEBUGF(infof(data, - "schannel: incremented credential handle refcount = %d\n", - BACKEND->cred->refcount)); + DEBUGF(infof(data, + "schannel: incremented credential handle refcount = %d\n", + BACKEND->cred->refcount)); } Curl_ssl_sessionid_unlock(conn); } @@ -524,8 +524,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE; - DEBUGF(infof(data, "schannel: disabled server certificate revocation " - "checks\n")); + DEBUGF(infof(data, "schannel: disabled server certificate revocation " + "checks\n")); } else if(data->set.ssl.revoke_best_effort) { schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | @@ -536,23 +536,23 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) else { schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; - DEBUGF(infof(data, - "schannel: checking server certificate revocation\n")); + DEBUGF(infof(data, + "schannel: checking server certificate revocation\n")); } } else { schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE; - DEBUGF(infof(data, - "schannel: disabled server cert revocation checks\n")); + DEBUGF(infof(data, + "schannel: disabled server cert revocation checks\n")); } if(!conn->ssl_config.verifyhost) { schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK; - DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from " - "comparing the supplied target name with the subject " - "names in server certificates.\n")); + DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from " + "comparing the supplied target name with the subject " + "names in server certificates.\n")); } switch(conn->ssl_config.version) { @@ -806,9 +806,9 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) CertFreeCertificateContext(client_certs[0]); if(sspi_status != SEC_E_OK) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: AcquireCredentialsHandle failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); Curl_safefree(BACKEND->cred); switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: @@ -923,7 +923,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) curlx_unicodefree(host_name); if(sspi_status != SEC_I_CONTINUE_NEEDED) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; Curl_safefree(BACKEND->ctxt); switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: @@ -952,8 +952,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) } } - DEBUGF(infof(data, "schannel: sending initial handshake data: " - "sending %lu bytes...\n", outbuf.cbBuffer)); + DEBUGF(infof(data, "schannel: sending initial handshake data: " + "sending %lu bytes...\n", outbuf.cbBuffer)); /* send initial handshake data which is now stored in output buffer */ result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer, @@ -965,8 +965,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) return CURLE_SSL_CONNECT_ERROR; } - DEBUGF(infof(data, "schannel: sent initial handshake data: " - "sent %zd bytes\n", written)); + DEBUGF(infof(data, "schannel: sent initial handshake data: " + "sent %zd bytes\n", written)); BACKEND->recv_unrecoverable_err = CURLE_OK; BACKEND->recv_sspi_close_notify = false; @@ -1004,9 +1004,9 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; - DEBUGF(infof(data, - "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n", - hostname, conn->remote_port)); + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n", + hostname, conn->remote_port)); if(!BACKEND->cred || !BACKEND->ctxt) return CURLE_SSL_CONNECT_ERROR; @@ -1038,7 +1038,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) if(BACKEND->encdata_length - BACKEND->encdata_offset < CURL_SCHANNEL_BUFFER_FREE_SIZE) { /* increase internal encrypted data buffer */ - size_t reallocated_length = BACKEND->encdata_offset + + size_t reallocated_length = BACKEND->encdata_offset + CURL_SCHANNEL_BUFFER_FREE_SIZE; reallocated_buffer = realloc(BACKEND->encdata_buffer, reallocated_length); @@ -1054,7 +1054,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) } for(;;) { - TCHAR *host_name; + TCHAR *host_name; if(doread) { /* read encrypted handshake data from socket */ result = Curl_read_plain(conn->sock[sockindex], @@ -1066,8 +1066,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) if(result == CURLE_AGAIN) { if(connssl->connecting_state != ssl_connect_2_writing) connssl->connecting_state = ssl_connect_2_reading; - DEBUGF(infof(data, "schannel: failed to receive handshake, " - "need more data\n")); + DEBUGF(infof(data, "schannel: failed to receive handshake, " + "need more data\n")); return CURLE_OK; } else if((result != CURLE_OK) || (nread == 0)) { @@ -1079,12 +1079,12 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) /* increase encrypted data buffer offset */ BACKEND->encdata_offset += nread; BACKEND->encdata_is_incomplete = false; - DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); + DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); } - DEBUGF(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length)); + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); /* setup input buffers */ InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset), @@ -1127,8 +1127,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) { BACKEND->encdata_is_incomplete = true; connssl->connecting_state = ssl_connect_2_reading; - DEBUGF(infof(data, - "schannel: received incomplete message, need more data\n")); + DEBUGF(infof(data, + "schannel: received incomplete message, need more data\n")); return CURLE_OK; } @@ -1139,8 +1139,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) !(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) { BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; connssl->connecting_state = ssl_connect_2_writing; - DEBUGF(infof(data, - "schannel: a client certificate has been requested\n")); + DEBUGF(infof(data, + "schannel: a client certificate has been requested\n")); return CURLE_OK; } @@ -1149,8 +1149,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) for(i = 0; i < 3; i++) { /* search for handshake tokens that need to be send */ if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) { - DEBUGF(infof(data, "schannel: sending next handshake data: " - "sending %lu bytes...\n", outbuf[i].cbBuffer)); + DEBUGF(infof(data, "schannel: sending next handshake data: " + "sending %lu bytes...\n", outbuf[i].cbBuffer)); /* send handshake token to server */ result = Curl_write_plain(conn, conn->sock[sockindex], @@ -1171,7 +1171,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) } } else { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; switch(sspi_status) { case SEC_E_INSUFFICIENT_MEMORY: failf(data, "schannel: next InitializeSecurityContext failed: %s", @@ -1205,8 +1205,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) /* check if there was additional remaining encrypted data */ if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) { - DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", - inbuf[1].cbBuffer)); + DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", + inbuf[1].cbBuffer)); /* There are two cases where we could be getting extra data here: 1) If we're renegotiating a connection and the handshake is already @@ -1245,7 +1245,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) /* check if the handshake is complete */ if(sspi_status == SEC_E_OK) { connssl->connecting_state = ssl_connect_3; - DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n")); + DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n")); } pubkey_ptr = SSL_IS_PROXY() ? @@ -1334,7 +1334,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) struct ssl_connect_data *connssl = &conn->ssl[sockindex]; SECURITY_STATUS sspi_status = SEC_E_OK; CERT_CONTEXT *ccert_context = NULL; -#ifdef DEBUGBUILD +#ifdef DEBUGBUILD const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; #endif @@ -1344,9 +1344,9 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - DEBUGF(infof(data, - "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n", - hostname, conn->remote_port)); + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n", + hostname, conn->remote_port)); if(!BACKEND->cred) return CURLE_SSL_CONNECT_ERROR; @@ -1400,8 +1400,8 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) } else infof(data, "ALPN, server did not agree to a protocol\n"); - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } #endif @@ -1415,8 +1415,8 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) sockindex)); if(incache) { if(old_cred != BACKEND->cred) { - DEBUGF(infof(data, - "schannel: old credential handle is stale, removing\n")); + DEBUGF(infof(data, + "schannel: old credential handle is stale, removing\n")); /* we're not taking old_cred ownership here, no refcount++ is needed */ Curl_ssl_delsessionid(conn, (void *)old_cred); incache = FALSE; @@ -1434,8 +1434,8 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) else { /* this cred session is now also referenced by sessionid cache */ BACKEND->cred->refcount++; - DEBUGF(infof(data, - "schannel: stored credential handle in session cache\n")); + DEBUGF(infof(data, + "schannel: stored credential handle in session cache\n")); } } Curl_ssl_sessionid_unlock(conn); @@ -1575,16 +1575,16 @@ schannel_connect_common(struct connectdata *conn, int sockindex, connssl->state = ssl_connection_complete; conn->recv[sockindex] = schannel_recv; conn->send[sockindex] = schannel_send; - -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - /* When SSPI is used in combination with Schannel - * we need the Schannel context to create the Schannel - * binding to pass the IIS extended protection checks. - * Available on Windows 7 or later. - */ - conn->sslContext = &BACKEND->ctxt->ctxt_handle; -#endif - + +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + /* When SSPI is used in combination with Schannel + * we need the Schannel context to create the Schannel + * binding to pass the IIS extended protection checks. + * Available on Windows 7 or later. + */ + conn->sslContext = &BACKEND->ctxt->ctxt_handle; +#endif + *done = TRUE; } else @@ -1766,7 +1766,7 @@ schannel_recv(struct connectdata *conn, int sockindex, * handled in the cleanup. */ - DEBUGF(infof(data, "schannel: client wants to read %zu bytes\n", len)); + DEBUGF(infof(data, "schannel: client wants to read %zu bytes\n", len)); *err = CURLE_OK; if(len && len <= BACKEND->decdata_offset) { @@ -1811,13 +1811,13 @@ schannel_recv(struct connectdata *conn, int sockindex, BACKEND->encdata_buffer = reallocated_buffer; BACKEND->encdata_length = reallocated_length; size = BACKEND->encdata_length - BACKEND->encdata_offset; - DEBUGF(infof(data, "schannel: encdata_buffer resized %zu\n", - BACKEND->encdata_length)); + DEBUGF(infof(data, "schannel: encdata_buffer resized %zu\n", + BACKEND->encdata_length)); } - DEBUGF(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length)); + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); /* read encrypted data from socket */ *err = Curl_read_plain(conn->sock[sockindex], @@ -1827,8 +1827,8 @@ schannel_recv(struct connectdata *conn, int sockindex, if(*err) { nread = -1; if(*err == CURLE_AGAIN) - DEBUGF(infof(data, - "schannel: Curl_read_plain returned CURLE_AGAIN\n")); + DEBUGF(infof(data, + "schannel: Curl_read_plain returned CURLE_AGAIN\n")); else if(*err == CURLE_RECV_ERROR) infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n"); else @@ -1836,18 +1836,18 @@ schannel_recv(struct connectdata *conn, int sockindex, } else if(nread == 0) { BACKEND->recv_connection_closed = true; - DEBUGF(infof(data, "schannel: server closed the connection\n")); + DEBUGF(infof(data, "schannel: server closed the connection\n")); } else if(nread > 0) { BACKEND->encdata_offset += (size_t)nread; BACKEND->encdata_is_incomplete = false; - DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); + DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); } } - DEBUGF(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length)); + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); /* decrypt loop */ while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK && @@ -1875,8 +1875,8 @@ schannel_recv(struct connectdata *conn, int sockindex, /* check for successfully decrypted data, even before actual renegotiation or shutdown of the connection context */ if(inbuf[1].BufferType == SECBUFFER_DATA) { - DEBUGF(infof(data, "schannel: decrypted data length: %lu\n", - inbuf[1].cbBuffer)); + DEBUGF(infof(data, "schannel: decrypted data length: %lu\n", + inbuf[1].cbBuffer)); /* increase buffer in order to fit the received amount of data */ size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ? @@ -1908,16 +1908,16 @@ schannel_recv(struct connectdata *conn, int sockindex, BACKEND->decdata_offset += size; } - DEBUGF(infof(data, "schannel: decrypted data added: %zu\n", size)); - DEBUGF(infof(data, - "schannel: decrypted cached: offset %zu length %zu\n", - BACKEND->decdata_offset, BACKEND->decdata_length)); + DEBUGF(infof(data, "schannel: decrypted data added: %zu\n", size)); + DEBUGF(infof(data, + "schannel: decrypted cached: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); } /* check for remaining encrypted data */ if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) { - DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", - inbuf[3].cbBuffer)); + DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", + inbuf[3].cbBuffer)); /* check if the remaining data is less than the total amount * and therefore begins after the already processed data @@ -1931,9 +1931,9 @@ schannel_recv(struct connectdata *conn, int sockindex, BACKEND->encdata_offset = inbuf[3].cbBuffer; } - DEBUGF(infof(data, - "schannel: encrypted cached: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length)); + DEBUGF(infof(data, + "schannel: encrypted cached: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); } else { /* reset encrypted buffer offset, because there is no data remaining */ @@ -1988,26 +1988,26 @@ schannel_recv(struct connectdata *conn, int sockindex, } else { #ifndef CURL_DISABLE_VERBOSE_STRINGS - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; #endif *err = CURLE_RECV_ERROR; infof(data, "schannel: failed to read data from server: %s\n", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); goto cleanup; } } - DEBUGF(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu\n", - BACKEND->encdata_offset, BACKEND->encdata_length)); + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); - DEBUGF(infof(data, - "schannel: decrypted data buffer: offset %zu length %zu\n", - BACKEND->decdata_offset, BACKEND->decdata_length)); + DEBUGF(infof(data, + "schannel: decrypted data buffer: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); cleanup: /* Warning- there is no guarantee the encdata state is valid at this point */ - DEBUGF(infof(data, "schannel: schannel_recv cleanup\n")); + DEBUGF(infof(data, "schannel: schannel_recv cleanup\n")); /* Error if the connection has closed without a close_notify. @@ -2043,10 +2043,10 @@ schannel_recv(struct connectdata *conn, int sockindex, memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size, BACKEND->decdata_offset - size); BACKEND->decdata_offset -= size; - DEBUGF(infof(data, "schannel: decrypted data returned %zu\n", size)); - DEBUGF(infof(data, - "schannel: decrypted data buffer: offset %zu length %zu\n", - BACKEND->decdata_offset, BACKEND->decdata_length)); + DEBUGF(infof(data, "schannel: decrypted data returned %zu\n", size)); + DEBUGF(infof(data, + "schannel: decrypted data buffer: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); *err = CURLE_OK; return (ssize_t)size; } @@ -2129,8 +2129,8 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) char * const hostname = conn->host.name; #endif - DEBUGASSERT(data); - + DEBUGASSERT(data); + infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n", hostname, conn->remote_port); @@ -2150,11 +2150,11 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle, &BuffDesc); - if(sspi_status != SEC_E_OK) { - char buffer[STRERROR_LEN]; + if(sspi_status != SEC_E_OK) { + char buffer[STRERROR_LEN]; failf(data, "schannel: ApplyControlToken failure: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - } + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + } host_name = curlx_convert_UTF8_to_tchar(hostname); if(!host_name) @@ -2196,18 +2196,18 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) /* free SSPI Schannel API security context handle */ if(BACKEND->ctxt) { - DEBUGF(infof(data, "schannel: clear security context handle\n")); + DEBUGF(infof(data, "schannel: clear security context handle\n")); s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle); Curl_safefree(BACKEND->ctxt); } /* free SSPI Schannel API credential handle */ if(BACKEND->cred) { - /* - * When this function is called from Curl_schannel_close() the connection - * might not have an associated transfer so the check for conn->data is - * necessary. - */ + /* + * When this function is called from Curl_schannel_close() the connection + * might not have an associated transfer so the check for conn->data is + * necessary. + */ Curl_ssl_sessionid_lock(conn); Curl_schannel_session_free(BACKEND->cred); Curl_ssl_sessionid_unlock(conn); @@ -2244,7 +2244,7 @@ static void Curl_schannel_cleanup(void) static size_t Curl_schannel_version(char *buffer, size_t size) { - size = msnprintf(buffer, size, "Schannel"); + size = msnprintf(buffer, size, "Schannel"); return size; } @@ -2284,21 +2284,21 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, return CURLE_OK; do { - SECURITY_STATUS sspi_status; - const char *x509_der; - DWORD x509_der_len; + SECURITY_STATUS sspi_status; + const char *x509_der; + DWORD x509_der_len; struct Curl_X509certificate x509_parsed; struct Curl_asn1Element *pubkey; - sspi_status = - s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); - - if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { - char buffer[STRERROR_LEN]; + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); + + if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); break; /* failed */ } @@ -2335,11 +2335,11 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, } static void Curl_schannel_checksum(const unsigned char *input, - size_t inputlen, - unsigned char *checksum, - size_t checksumlen, - DWORD provType, - const unsigned int algId) + size_t inputlen, + unsigned char *checksum, + size_t checksumlen, + DWORD provType, + const unsigned int algId) { HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; @@ -2389,9 +2389,9 @@ static CURLcode Curl_schannel_md5sum(unsigned char *input, unsigned char *md5sum, size_t md5len) { - Curl_schannel_checksum(input, inputlen, md5sum, md5len, - PROV_RSA_FULL, CALG_MD5); - return CURLE_OK; + Curl_schannel_checksum(input, inputlen, md5sum, md5len, + PROV_RSA_FULL, CALG_MD5); + return CURLE_OK; } static CURLcode Curl_schannel_sha256sum(const unsigned char *input, @@ -2399,9 +2399,9 @@ static CURLcode Curl_schannel_sha256sum(const unsigned char *input, unsigned char *sha256sum, size_t sha256len) { - Curl_schannel_checksum(input, inputlen, sha256sum, sha256len, - PROV_RSA_AES, CALG_SHA_256); - return CURLE_OK; + Curl_schannel_checksum(input, inputlen, sha256sum, sha256len, + PROV_RSA_AES, CALG_SHA_256); + return CURLE_OK; } static void *Curl_schannel_get_internals(struct ssl_connect_data *connssl, diff --git a/contrib/libs/curl/lib/vtls/schannel_verify.c b/contrib/libs/curl/lib/vtls/schannel_verify.c index 53c7da17e1..31b3b2f02f 100644 --- a/contrib/libs/curl/lib/vtls/schannel_verify.c +++ b/contrib/libs/curl/lib/vtls/schannel_verify.c @@ -87,7 +87,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, LARGE_INTEGER file_size; char *ca_file_buffer = NULL; char *current_ca_file_ptr = NULL; - TCHAR *ca_file_tstr = NULL; + TCHAR *ca_file_tstr = NULL; size_t ca_file_bufsize = 0; DWORD total_bytes_read = 0; bool more_certs = 0; @@ -96,7 +96,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, ca_file_tstr = curlx_convert_UTF8_to_tchar((char *)ca_file); if(!ca_file_tstr) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: invalid path name for CA file '%s': %s", ca_file, @@ -118,7 +118,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, FILE_ATTRIBUTE_NORMAL, NULL); if(ca_file_handle == INVALID_HANDLE_VALUE) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to open CA file '%s': %s", ca_file, @@ -128,7 +128,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, } if(!GetFileSizeEx(ca_file_handle, &file_size)) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to determine size of CA file '%s': %s", ca_file, @@ -159,7 +159,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read, bytes_to_read, &bytes_read, NULL)) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to read from CA file '%s': %s", ca_file, @@ -222,11 +222,11 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, NULL, NULL, (const void **)&cert_context)) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to extract certificate from CA file " "'%s': %s", - ca_file, + ca_file, Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; @@ -251,11 +251,11 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, NULL); CertFreeCertificateContext(cert_context); if(!add_cert_result) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to add certificate from CA file '%s' " "to certificate store: %s", - ca_file, + ca_file, Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; @@ -529,7 +529,7 @@ cleanup: CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) { - SECURITY_STATUS sspi_status; + SECURITY_STATUS sspi_status; struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; CURLcode result = CURLE_OK; @@ -545,15 +545,15 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) const char * const conn_hostname = conn->host.name; #endif - sspi_status = - s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); - if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { - char buffer[STRERROR_LEN]; + if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); result = CURLE_PEER_FAILED_VERIFICATION; } @@ -577,7 +577,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CERT_STORE_CREATE_NEW_FLAG, NULL); if(!trust_store) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate store: %s", Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; @@ -605,7 +605,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CertCreateCertificateChainEngine( (CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine); if(!create_engine_result) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate chain engine: %s", Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); @@ -629,7 +629,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CERT_CHAIN_REVOCATION_CHECK_CHAIN), NULL, &pChainContext)) { - char buffer[STRERROR_LEN]; + char buffer[STRERROR_LEN]; failf(data, "schannel: CertGetCertificateChain failed: %s", Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); pChainContext = NULL; diff --git a/contrib/libs/curl/lib/vtls/sectransp.c b/contrib/libs/curl/lib/vtls/sectransp.c index eed4cb14a2..8ef60cb1f3 100644 --- a/contrib/libs/curl/lib/vtls/sectransp.c +++ b/contrib/libs/curl/lib/vtls/sectransp.c @@ -1,1145 +1,1145 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>. +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>. * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all iOS and macOS SecureTransport-specific code for the - * TLS/SSL layer. No code but vtls.c should ever call or use these functions. - */ - -#include "curl_setup.h" - -#include "urldata.h" /* for the Curl_easy definition */ -#include "curl_base64.h" -#include "strtok.h" -#include "multiif.h" - -#ifdef USE_SECTRANSP - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wtautological-pointer-compare" -#endif /* __clang__ */ - -#include <limits.h> - -#include <Security/Security.h> -/* For some reason, when building for iOS, the omnibus header above does - * not include SecureTransport.h as of iOS SDK 5.1. */ -#include <Security/SecureTransport.h> -#include <CoreFoundation/CoreFoundation.h> -#include <CommonCrypto/CommonDigest.h> - -/* The Security framework has changed greatly between iOS and different macOS - versions, and we will try to support as many of them as we can (back to - Leopard and iOS 5) by using macros and weak-linking. - - In general, you want to build this using the most recent OS SDK, since some - features require curl to be built against the latest SDK. TLS 1.1 and 1.2 - support, for instance, require the macOS 10.8 SDK or later. TLS 1.3 - requires the macOS 10.13 or iOS 11 SDK or later. */ -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 -#error "The Secure Transport back-end requires Leopard or later." -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */ - -#define CURL_BUILD_IOS 0 -#define CURL_BUILD_IOS_7 0 -#define CURL_BUILD_IOS_9 0 -#define CURL_BUILD_IOS_11 0 -#define CURL_BUILD_MAC 1 -/* This is the maximum API level we are allowed to use when building: */ -#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 -#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 -#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 -#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 -#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 -#define CURL_BUILD_MAC_10_11 MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 -#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 -/* These macros mean "the following code is present to allow runtime backward - compatibility with at least this cat or earlier": - (You set this at build-time using the compiler command line option + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all iOS and macOS SecureTransport-specific code for the + * TLS/SSL layer. No code but vtls.c should ever call or use these functions. + */ + +#include "curl_setup.h" + +#include "urldata.h" /* for the Curl_easy definition */ +#include "curl_base64.h" +#include "strtok.h" +#include "multiif.h" + +#ifdef USE_SECTRANSP + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wtautological-pointer-compare" +#endif /* __clang__ */ + +#include <limits.h> + +#include <Security/Security.h> +/* For some reason, when building for iOS, the omnibus header above does + * not include SecureTransport.h as of iOS SDK 5.1. */ +#include <Security/SecureTransport.h> +#include <CoreFoundation/CoreFoundation.h> +#include <CommonCrypto/CommonDigest.h> + +/* The Security framework has changed greatly between iOS and different macOS + versions, and we will try to support as many of them as we can (back to + Leopard and iOS 5) by using macros and weak-linking. + + In general, you want to build this using the most recent OS SDK, since some + features require curl to be built against the latest SDK. TLS 1.1 and 1.2 + support, for instance, require the macOS 10.8 SDK or later. TLS 1.3 + requires the macOS 10.13 or iOS 11 SDK or later. */ +#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) + +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 +#error "The Secure Transport back-end requires Leopard or later." +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */ + +#define CURL_BUILD_IOS 0 +#define CURL_BUILD_IOS_7 0 +#define CURL_BUILD_IOS_9 0 +#define CURL_BUILD_IOS_11 0 +#define CURL_BUILD_MAC 1 +/* This is the maximum API level we are allowed to use when building: */ +#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 +#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 +#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 +#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 +#define CURL_BUILD_MAC_10_11 MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 +#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 +/* These macros mean "the following code is present to allow runtime backward + compatibility with at least this cat or earlier": + (You set this at build-time using the compiler command line option "-mmacosx-version-min.") */ -#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 -#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060 -#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 -#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080 -#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 - -#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE -#define CURL_BUILD_IOS 1 -#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 -#define CURL_BUILD_IOS_9 __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 -#define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 -#define CURL_BUILD_MAC 0 -#define CURL_BUILD_MAC_10_5 0 -#define CURL_BUILD_MAC_10_6 0 -#define CURL_BUILD_MAC_10_7 0 -#define CURL_BUILD_MAC_10_8 0 -#define CURL_BUILD_MAC_10_9 0 -#define CURL_BUILD_MAC_10_11 0 -#define CURL_BUILD_MAC_10_13 0 -#define CURL_SUPPORT_MAC_10_5 0 -#define CURL_SUPPORT_MAC_10_6 0 -#define CURL_SUPPORT_MAC_10_7 0 -#define CURL_SUPPORT_MAC_10_8 0 -#define CURL_SUPPORT_MAC_10_9 0 - -#else -#error "The Secure Transport back-end requires iOS or macOS." -#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */ - -#if CURL_BUILD_MAC -#include <sys/sysctl.h> -#endif /* CURL_BUILD_MAC */ - -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "connect.h" -#include "select.h" -#include "vtls.h" -#include "sectransp.h" -#include "curl_printf.h" -#include "strdup.h" - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* From MacTypes.h (which we can't include because it isn't present in iOS: */ -#define ioErr -36 -#define paramErr -50 - -struct ssl_backend_data { - SSLContextRef ssl_ctx; - curl_socket_t ssl_sockfd; - bool ssl_direction; /* true if writing, false if reading */ - size_t ssl_write_buffered_length; -}; - -/* pinned public key support tests */ - -/* version 1 supports macOS 10.12+ and iOS 10+ */ -#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \ - (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)) -#define SECTRANSP_PINNEDPUBKEY_V1 1 -#endif - -/* version 2 supports MacOSX 10.7+ */ -#if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) -#define SECTRANSP_PINNEDPUBKEY_V2 1 -#endif - -#if defined(SECTRANSP_PINNEDPUBKEY_V1) || defined(SECTRANSP_PINNEDPUBKEY_V2) -/* this backend supports CURLOPT_PINNEDPUBLICKEY */ -#define SECTRANSP_PINNEDPUBKEY 1 -#endif /* SECTRANSP_PINNEDPUBKEY */ - -#ifdef SECTRANSP_PINNEDPUBKEY -/* both new and old APIs return rsa keys missing the spki header (not DER) */ -static const unsigned char rsa4096SpkiHeader[] = { - 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00}; - -static const unsigned char rsa2048SpkiHeader[] = { - 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00}; -#ifdef SECTRANSP_PINNEDPUBKEY_V1 -/* the *new* version doesn't return DER encoded ecdsa certs like the old... */ -static const unsigned char ecDsaSecp256r1SpkiHeader[] = { - 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, - 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, - 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, - 0x42, 0x00}; - -static const unsigned char ecDsaSecp384r1SpkiHeader[] = { - 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, - 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, - 0x00, 0x22, 0x03, 0x62, 0x00}; -#endif /* SECTRANSP_PINNEDPUBKEY_V1 */ -#endif /* SECTRANSP_PINNEDPUBKEY */ - -/* The following two functions were ripped from Apple sample code, - * with some modifications: */ -static OSStatus SocketRead(SSLConnectionRef connection, - void *data, /* owned by - * caller, data - * RETURNED */ - size_t *dataLength) /* IN/OUT */ -{ - size_t bytesToGo = *dataLength; - size_t initLen = bytesToGo; - UInt8 *currData = (UInt8 *)data; - /*int sock = *(int *)connection;*/ - struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; +#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 +#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060 +#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 +#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080 +#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 + +#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE +#define CURL_BUILD_IOS 1 +#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 +#define CURL_BUILD_IOS_9 __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 +#define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 +#define CURL_BUILD_MAC 0 +#define CURL_BUILD_MAC_10_5 0 +#define CURL_BUILD_MAC_10_6 0 +#define CURL_BUILD_MAC_10_7 0 +#define CURL_BUILD_MAC_10_8 0 +#define CURL_BUILD_MAC_10_9 0 +#define CURL_BUILD_MAC_10_11 0 +#define CURL_BUILD_MAC_10_13 0 +#define CURL_SUPPORT_MAC_10_5 0 +#define CURL_SUPPORT_MAC_10_6 0 +#define CURL_SUPPORT_MAC_10_7 0 +#define CURL_SUPPORT_MAC_10_8 0 +#define CURL_SUPPORT_MAC_10_9 0 + +#else +#error "The Secure Transport back-end requires iOS or macOS." +#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */ + +#if CURL_BUILD_MAC +#include <sys/sysctl.h> +#endif /* CURL_BUILD_MAC */ + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "connect.h" +#include "select.h" +#include "vtls.h" +#include "sectransp.h" +#include "curl_printf.h" +#include "strdup.h" + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* From MacTypes.h (which we can't include because it isn't present in iOS: */ +#define ioErr -36 +#define paramErr -50 + +struct ssl_backend_data { + SSLContextRef ssl_ctx; + curl_socket_t ssl_sockfd; + bool ssl_direction; /* true if writing, false if reading */ + size_t ssl_write_buffered_length; +}; + +/* pinned public key support tests */ + +/* version 1 supports macOS 10.12+ and iOS 10+ */ +#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \ + (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)) +#define SECTRANSP_PINNEDPUBKEY_V1 1 +#endif + +/* version 2 supports MacOSX 10.7+ */ +#if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) +#define SECTRANSP_PINNEDPUBKEY_V2 1 +#endif + +#if defined(SECTRANSP_PINNEDPUBKEY_V1) || defined(SECTRANSP_PINNEDPUBKEY_V2) +/* this backend supports CURLOPT_PINNEDPUBLICKEY */ +#define SECTRANSP_PINNEDPUBKEY 1 +#endif /* SECTRANSP_PINNEDPUBKEY */ + +#ifdef SECTRANSP_PINNEDPUBKEY +/* both new and old APIs return rsa keys missing the spki header (not DER) */ +static const unsigned char rsa4096SpkiHeader[] = { + 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00}; + +static const unsigned char rsa2048SpkiHeader[] = { + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00}; +#ifdef SECTRANSP_PINNEDPUBKEY_V1 +/* the *new* version doesn't return DER encoded ecdsa certs like the old... */ +static const unsigned char ecDsaSecp256r1SpkiHeader[] = { + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00}; + +static const unsigned char ecDsaSecp384r1SpkiHeader[] = { + 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, + 0x00, 0x22, 0x03, 0x62, 0x00}; +#endif /* SECTRANSP_PINNEDPUBKEY_V1 */ +#endif /* SECTRANSP_PINNEDPUBKEY */ + +/* The following two functions were ripped from Apple sample code, + * with some modifications: */ +static OSStatus SocketRead(SSLConnectionRef connection, + void *data, /* owned by + * caller, data + * RETURNED */ + size_t *dataLength) /* IN/OUT */ +{ + size_t bytesToGo = *dataLength; + size_t initLen = bytesToGo; + UInt8 *currData = (UInt8 *)data; + /*int sock = *(int *)connection;*/ + struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; struct ssl_backend_data *backend = connssl->backend; int sock = backend->ssl_sockfd; - OSStatus rtn = noErr; - size_t bytesRead; - ssize_t rrtn; - int theErr; - - *dataLength = 0; - - for(;;) { - bytesRead = 0; - rrtn = read(sock, currData, bytesToGo); - if(rrtn <= 0) { - /* this is guesswork... */ - theErr = errno; - if(rrtn == 0) { /* EOF = server hung up */ - /* the framework will turn this into errSSLClosedNoNotify */ - rtn = errSSLClosedGraceful; - } - else /* do the switch */ - switch(theErr) { - case ENOENT: - /* connection closed */ - rtn = errSSLClosedGraceful; - break; - case ECONNRESET: - rtn = errSSLClosedAbort; - break; - case EAGAIN: - rtn = errSSLWouldBlock; + OSStatus rtn = noErr; + size_t bytesRead; + ssize_t rrtn; + int theErr; + + *dataLength = 0; + + for(;;) { + bytesRead = 0; + rrtn = read(sock, currData, bytesToGo); + if(rrtn <= 0) { + /* this is guesswork... */ + theErr = errno; + if(rrtn == 0) { /* EOF = server hung up */ + /* the framework will turn this into errSSLClosedNoNotify */ + rtn = errSSLClosedGraceful; + } + else /* do the switch */ + switch(theErr) { + case ENOENT: + /* connection closed */ + rtn = errSSLClosedGraceful; + break; + case ECONNRESET: + rtn = errSSLClosedAbort; + break; + case EAGAIN: + rtn = errSSLWouldBlock; backend->ssl_direction = false; - break; - default: - rtn = ioErr; - break; - } - break; - } - else { - bytesRead = rrtn; - } - bytesToGo -= bytesRead; - currData += bytesRead; - - if(bytesToGo == 0) { - /* filled buffer with incoming data, done */ - break; - } - } - *dataLength = initLen - bytesToGo; - - return rtn; -} - -static OSStatus SocketWrite(SSLConnectionRef connection, - const void *data, - size_t *dataLength) /* IN/OUT */ -{ - size_t bytesSent = 0; - /*int sock = *(int *)connection;*/ - struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; + break; + default: + rtn = ioErr; + break; + } + break; + } + else { + bytesRead = rrtn; + } + bytesToGo -= bytesRead; + currData += bytesRead; + + if(bytesToGo == 0) { + /* filled buffer with incoming data, done */ + break; + } + } + *dataLength = initLen - bytesToGo; + + return rtn; +} + +static OSStatus SocketWrite(SSLConnectionRef connection, + const void *data, + size_t *dataLength) /* IN/OUT */ +{ + size_t bytesSent = 0; + /*int sock = *(int *)connection;*/ + struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; struct ssl_backend_data *backend = connssl->backend; int sock = backend->ssl_sockfd; - ssize_t length; - size_t dataLen = *dataLength; - const UInt8 *dataPtr = (UInt8 *)data; - OSStatus ortn; - int theErr; - - *dataLength = 0; - - do { - length = write(sock, - (char *)dataPtr + bytesSent, - dataLen - bytesSent); - } while((length > 0) && - ( (bytesSent += length) < dataLen) ); - - if(length <= 0) { - theErr = errno; - if(theErr == EAGAIN) { - ortn = errSSLWouldBlock; + ssize_t length; + size_t dataLen = *dataLength; + const UInt8 *dataPtr = (UInt8 *)data; + OSStatus ortn; + int theErr; + + *dataLength = 0; + + do { + length = write(sock, + (char *)dataPtr + bytesSent, + dataLen - bytesSent); + } while((length > 0) && + ( (bytesSent += length) < dataLen) ); + + if(length <= 0) { + theErr = errno; + if(theErr == EAGAIN) { + ortn = errSSLWouldBlock; backend->ssl_direction = true; - } - else { - ortn = ioErr; - } - } - else { - ortn = noErr; - } - *dataLength = bytesSent; - return ortn; -} - -#ifndef CURL_DISABLE_VERBOSE_STRINGS -CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) -{ - switch(cipher) { - /* SSL version 3.0 */ - case SSL_RSA_WITH_NULL_MD5: - return "SSL_RSA_WITH_NULL_MD5"; - break; - case SSL_RSA_WITH_NULL_SHA: - return "SSL_RSA_WITH_NULL_SHA"; - break; - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - return "SSL_RSA_EXPORT_WITH_RC4_40_MD5"; - break; - case SSL_RSA_WITH_RC4_128_MD5: - return "SSL_RSA_WITH_RC4_128_MD5"; - break; - case SSL_RSA_WITH_RC4_128_SHA: - return "SSL_RSA_WITH_RC4_128_SHA"; - break; - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; - break; - case SSL_RSA_WITH_IDEA_CBC_SHA: - return "SSL_RSA_WITH_IDEA_CBC_SHA"; - break; - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_RSA_WITH_DES_CBC_SHA: - return "SSL_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_DSS_WITH_DES_CBC_SHA: - return "SSL_DH_DSS_WITH_DES_CBC_SHA"; - break; - case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_RSA_WITH_DES_CBC_SHA: - return "SSL_DH_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - return "SSL_DHE_DSS_WITH_DES_CBC_SHA"; - break; - case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - return "SSL_DHE_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"; - break; - case SSL_DH_anon_WITH_RC4_128_MD5: - return "SSL_DH_anon_WITH_RC4_128_MD5"; - break; - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_anon_WITH_DES_CBC_SHA: - return "SSL_DH_anon_WITH_DES_CBC_SHA"; - break; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; - break; - case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: - return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; - break; - /* TLS 1.0 with AES (RFC 3268) - (Apparently these are used in SSLv3 implementations as well.) */ - case TLS_RSA_WITH_AES_128_CBC_SHA: - return "TLS_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - return "TLS_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - break; - /* SSL version 2.0 */ - case SSL_RSA_WITH_RC2_CBC_MD5: - return "SSL_RSA_WITH_RC2_CBC_MD5"; - break; - case SSL_RSA_WITH_IDEA_CBC_MD5: - return "SSL_RSA_WITH_IDEA_CBC_MD5"; - break; - case SSL_RSA_WITH_DES_CBC_MD5: - return "SSL_RSA_WITH_DES_CBC_MD5"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_MD5: - return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; - break; - } - return "SSL_NULL_WITH_NULL_NULL"; -} - -CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) -{ - switch(cipher) { - /* TLS 1.0 with AES (RFC 3268) */ - case TLS_RSA_WITH_AES_128_CBC_SHA: - return "TLS_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - return "TLS_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - break; -#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS - /* TLS 1.0 with ECDSA (RFC 4492) */ - case TLS_ECDH_ECDSA_WITH_NULL_SHA: - return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_NULL_SHA: - return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_NULL_SHA: - return "TLS_ECDH_RSA_WITH_NULL_SHA"; - break; - case TLS_ECDH_RSA_WITH_RC4_128_SHA: - return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_NULL_SHA: - return "TLS_ECDHE_RSA_WITH_NULL_SHA"; - break; - case TLS_ECDHE_RSA_WITH_RC4_128_SHA: - return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_NULL_SHA: - return "TLS_ECDH_anon_WITH_NULL_SHA"; - break; - case TLS_ECDH_anon_WITH_RC4_128_SHA: - return "TLS_ECDH_anon_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; - break; -#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - /* TLS 1.2 (RFC 5246) */ - case TLS_RSA_WITH_NULL_MD5: - return "TLS_RSA_WITH_NULL_MD5"; - break; - case TLS_RSA_WITH_NULL_SHA: - return "TLS_RSA_WITH_NULL_SHA"; - break; - case TLS_RSA_WITH_RC4_128_MD5: - return "TLS_RSA_WITH_RC4_128_MD5"; - break; - case TLS_RSA_WITH_RC4_128_SHA: - return "TLS_RSA_WITH_RC4_128_SHA"; - break; - case TLS_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_RSA_WITH_NULL_SHA256: - return "TLS_RSA_WITH_NULL_SHA256"; - break; - case TLS_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_anon_WITH_RC4_128_MD5: - return "TLS_DH_anon_WITH_RC4_128_MD5"; - break; - case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA256: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA256: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; - break; - /* TLS 1.2 with AES GCM (RFC 5288) */ - case TLS_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_anon_WITH_AES_128_GCM_SHA256: - return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_anon_WITH_AES_256_GCM_SHA384: - return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; - break; - /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */ - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: - return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; - break; -#else - case SSL_RSA_WITH_NULL_MD5: - return "TLS_RSA_WITH_NULL_MD5"; - break; - case SSL_RSA_WITH_NULL_SHA: - return "TLS_RSA_WITH_NULL_SHA"; - break; - case SSL_RSA_WITH_RC4_128_MD5: - return "TLS_RSA_WITH_RC4_128_MD5"; - break; - case SSL_RSA_WITH_RC4_128_SHA: - return "TLS_RSA_WITH_RC4_128_SHA"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_anon_WITH_RC4_128_MD5: - return "TLS_DH_anon_WITH_RC4_128_MD5"; - break; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 - /* TLS PSK (RFC 4279): */ - case TLS_PSK_WITH_RC4_128_SHA: - return "TLS_PSK_WITH_RC4_128_SHA"; - break; - case TLS_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_PSK_WITH_AES_128_CBC_SHA: - return "TLS_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_PSK_WITH_AES_256_CBC_SHA: - return "TLS_PSK_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_RC4_128_SHA: - return "TLS_DHE_PSK_WITH_RC4_128_SHA"; - break; - case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: - return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: - return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_RC4_128_SHA: - return "TLS_RSA_PSK_WITH_RC4_128_SHA"; - break; - case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: - return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: - return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; - break; - /* More TLS PSK (RFC 4785): */ - case TLS_PSK_WITH_NULL_SHA: - return "TLS_PSK_WITH_NULL_SHA"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA: - return "TLS_DHE_PSK_WITH_NULL_SHA"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA: - return "TLS_RSA_PSK_WITH_NULL_SHA"; - break; - /* Even more TLS PSK (RFC 5487): */ - case TLS_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_PSK_WITH_NULL_SHA256: - return "TLS_PSK_WITH_NULL_SHA256"; - break; - case TLS_PSK_WITH_NULL_SHA384: - return "TLS_PSK_WITH_NULL_SHA384"; - break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA256: - return "TLS_DHE_PSK_WITH_NULL_SHA256"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA384: - return "TLS_RSA_PSK_WITH_NULL_SHA384"; - break; - case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA256: - return "TLS_RSA_PSK_WITH_NULL_SHA256"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA384: - return "TLS_RSA_PSK_WITH_NULL_SHA384"; - break; -#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ -#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 - /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */ - case TLS_AES_128_GCM_SHA256: - return "TLS_AES_128_GCM_SHA256"; - break; - case TLS_AES_256_GCM_SHA384: - return "TLS_AES_256_GCM_SHA384"; - break; - case TLS_CHACHA20_POLY1305_SHA256: - return "TLS_CHACHA20_POLY1305_SHA256"; - break; - case TLS_AES_128_CCM_SHA256: - return "TLS_AES_128_CCM_SHA256"; - break; - case TLS_AES_128_CCM_8_SHA256: - return "TLS_AES_128_CCM_8_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"; - break; -#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ - } - return "TLS_NULL_WITH_NULL_NULL"; -} -#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ - -#if CURL_BUILD_MAC -CF_INLINE void GetDarwinVersionNumber(int *major, int *minor) -{ - int mib[2]; - char *os_version; - size_t os_version_len; - char *os_version_major, *os_version_minor; - char *tok_buf; - - /* Get the Darwin kernel version from the kernel using sysctl(): */ - mib[0] = CTL_KERN; - mib[1] = KERN_OSRELEASE; - if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1) - return; - os_version = malloc(os_version_len*sizeof(char)); - if(!os_version) - return; - if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) { - free(os_version); - return; - } - - /* Parse the version: */ - os_version_major = strtok_r(os_version, ".", &tok_buf); - os_version_minor = strtok_r(NULL, ".", &tok_buf); - *major = atoi(os_version_major); - *minor = atoi(os_version_minor); - free(os_version); -} -#endif /* CURL_BUILD_MAC */ - -/* Apple provides a myriad of ways of getting information about a certificate - into a string. Some aren't available under iOS or newer cats. So here's - a unified function for getting a string describing the certificate that - ought to work in all cats starting with Leopard. */ -CF_INLINE CFStringRef getsubject(SecCertificateRef cert) -{ - CFStringRef server_cert_summary = CFSTR("(null)"); - -#if CURL_BUILD_IOS - /* iOS: There's only one way to do this. */ - server_cert_summary = SecCertificateCopySubjectSummary(cert); -#else -#if CURL_BUILD_MAC_10_7 - /* Lion & later: Get the long description if we can. */ - if(SecCertificateCopyLongDescription != NULL) - server_cert_summary = - SecCertificateCopyLongDescription(NULL, cert, NULL); - else -#endif /* CURL_BUILD_MAC_10_7 */ -#if CURL_BUILD_MAC_10_6 - /* Snow Leopard: Get the certificate summary. */ - if(SecCertificateCopySubjectSummary != NULL) - server_cert_summary = SecCertificateCopySubjectSummary(cert); - else -#endif /* CURL_BUILD_MAC_10_6 */ - /* Leopard is as far back as we go... */ - (void)SecCertificateCopyCommonName(cert, &server_cert_summary); -#endif /* CURL_BUILD_IOS */ - return server_cert_summary; -} - -static CURLcode CopyCertSubject(struct Curl_easy *data, - SecCertificateRef cert, char **certp) -{ - CFStringRef c = getsubject(cert); - CURLcode result = CURLE_OK; - const char *direct; - char *cbuf = NULL; - *certp = NULL; - - if(!c) { - failf(data, "SSL: invalid CA certificate subject"); - return CURLE_PEER_FAILED_VERIFICATION; - } - - /* If the subject is already available as UTF-8 encoded (ie 'direct') then - use that, else convert it. */ - direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8); - if(direct) { - *certp = strdup(direct); - if(!*certp) { - failf(data, "SSL: out of memory"); - result = CURLE_OUT_OF_MEMORY; - } - } - else { - size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1; - cbuf = calloc(cbuf_size, 1); - if(cbuf) { - if(!CFStringGetCString(c, cbuf, cbuf_size, - kCFStringEncodingUTF8)) { - failf(data, "SSL: invalid CA certificate subject"); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else - /* pass back the buffer */ - *certp = cbuf; - } - else { - failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size); - result = CURLE_OUT_OF_MEMORY; - } - } - if(result) - free(cbuf); - CFRelease(c); - return result; -} - -#if CURL_SUPPORT_MAC_10_6 -/* The SecKeychainSearch API was deprecated in Lion, and using it will raise - deprecation warnings, so let's not compile this unless it's necessary: */ -static OSStatus CopyIdentityWithLabelOldSchool(char *label, - SecIdentityRef *out_c_a_k) -{ - OSStatus status = errSecItemNotFound; - SecKeychainAttributeList attr_list; - SecKeychainAttribute attr; - SecKeychainSearchRef search = NULL; - SecCertificateRef cert = NULL; - - /* Set up the attribute list: */ - attr_list.count = 1L; - attr_list.attr = &attr; - - /* Set up our lone search criterion: */ - attr.tag = kSecLabelItemAttr; - attr.data = label; - attr.length = (UInt32)strlen(label); - - /* Start searching: */ - status = SecKeychainSearchCreateFromAttributes(NULL, - kSecCertificateItemClass, - &attr_list, - &search); - if(status == noErr) { - status = SecKeychainSearchCopyNext(search, - (SecKeychainItemRef *)&cert); - if(status == noErr && cert) { - /* If we found a certificate, does it have a private key? */ - status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k); - CFRelease(cert); - } - } - - if(search) - CFRelease(search); - return status; -} -#endif /* CURL_SUPPORT_MAC_10_6 */ - -static OSStatus CopyIdentityWithLabel(char *label, - SecIdentityRef *out_cert_and_key) -{ - OSStatus status = errSecItemNotFound; - -#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS - CFArrayRef keys_list; - CFIndex keys_list_count; - CFIndex i; - CFStringRef common_name; - - /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. - kSecClassIdentity was introduced in Lion. If both exist, let's use them - to find the certificate. */ - if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { - CFTypeRef keys[5]; - CFTypeRef values[5]; - CFDictionaryRef query_dict; - CFStringRef label_cf = CFStringCreateWithCString(NULL, label, - kCFStringEncodingUTF8); - - /* Set up our search criteria and expected results: */ - values[0] = kSecClassIdentity; /* we want a certificate and a key */ - keys[0] = kSecClass; - values[1] = kCFBooleanTrue; /* we want a reference */ - keys[1] = kSecReturnRef; - values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the - * label matching below worked correctly */ - keys[2] = kSecMatchLimit; - /* identity searches need a SecPolicyRef in order to work */ - values[3] = SecPolicyCreateSSL(false, NULL); - keys[3] = kSecMatchPolicy; - /* match the name of the certificate (doesn't work in macOS 10.12.1) */ - values[4] = label_cf; - keys[4] = kSecAttrLabel; - query_dict = CFDictionaryCreate(NULL, (const void **)keys, - (const void **)values, 5L, - &kCFCopyStringDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease(values[3]); - - /* Do we have a match? */ - status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list); - - /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity, - * we need to find the correct identity ourselves */ - if(status == noErr) { - keys_list_count = CFArrayGetCount(keys_list); - *out_cert_and_key = NULL; - status = 1; - for(i = 0; i<keys_list_count; i++) { - OSStatus err = noErr; - SecCertificateRef cert = NULL; - SecIdentityRef identity = - (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i); - err = SecIdentityCopyCertificate(identity, &cert); - if(err == noErr) { -#if CURL_BUILD_IOS - common_name = SecCertificateCopySubjectSummary(cert); -#elif CURL_BUILD_MAC_10_7 - SecCertificateCopyCommonName(cert, &common_name); -#endif - if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) { - CFRelease(cert); - CFRelease(common_name); - CFRetain(identity); - *out_cert_and_key = identity; - status = noErr; - break; - } - CFRelease(common_name); - } - CFRelease(cert); - } - } - - if(keys_list) - CFRelease(keys_list); - CFRelease(query_dict); - CFRelease(label_cf); - } - else { -#if CURL_SUPPORT_MAC_10_6 - /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */ - status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key); -#endif /* CURL_SUPPORT_MAC_10_6 */ - } -#elif CURL_SUPPORT_MAC_10_6 - /* For developers building on older cats, we have no choice but to fall back - to SecKeychainSearch. */ - status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key); -#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ - return status; -} - -static OSStatus CopyIdentityFromPKCS12File(const char *cPath, + } + else { + ortn = ioErr; + } + } + else { + ortn = noErr; + } + *dataLength = bytesSent; + return ortn; +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) +{ + switch(cipher) { + /* SSL version 3.0 */ + case SSL_RSA_WITH_NULL_MD5: + return "SSL_RSA_WITH_NULL_MD5"; + break; + case SSL_RSA_WITH_NULL_SHA: + return "SSL_RSA_WITH_NULL_SHA"; + break; + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + return "SSL_RSA_EXPORT_WITH_RC4_40_MD5"; + break; + case SSL_RSA_WITH_RC4_128_MD5: + return "SSL_RSA_WITH_RC4_128_MD5"; + break; + case SSL_RSA_WITH_RC4_128_SHA: + return "SSL_RSA_WITH_RC4_128_SHA"; + break; + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; + break; + case SSL_RSA_WITH_IDEA_CBC_SHA: + return "SSL_RSA_WITH_IDEA_CBC_SHA"; + break; + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_RSA_WITH_DES_CBC_SHA: + return "SSL_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_DSS_WITH_DES_CBC_SHA: + return "SSL_DH_DSS_WITH_DES_CBC_SHA"; + break; + case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_RSA_WITH_DES_CBC_SHA: + return "SSL_DH_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DHE_DSS_WITH_DES_CBC_SHA: + return "SSL_DHE_DSS_WITH_DES_CBC_SHA"; + break; + case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DHE_RSA_WITH_DES_CBC_SHA: + return "SSL_DHE_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: + return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"; + break; + case SSL_DH_anon_WITH_RC4_128_MD5: + return "SSL_DH_anon_WITH_RC4_128_MD5"; + break; + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_anon_WITH_DES_CBC_SHA: + return "SSL_DH_anon_WITH_DES_CBC_SHA"; + break; + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_FORTEZZA_DMS_WITH_NULL_SHA: + return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; + break; + case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: + return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; + break; + /* TLS 1.0 with AES (RFC 3268) + (Apparently these are used in SSLv3 implementations as well.) */ + case TLS_RSA_WITH_AES_128_CBC_SHA: + return "TLS_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA: + return "TLS_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; + break; + /* SSL version 2.0 */ + case SSL_RSA_WITH_RC2_CBC_MD5: + return "SSL_RSA_WITH_RC2_CBC_MD5"; + break; + case SSL_RSA_WITH_IDEA_CBC_MD5: + return "SSL_RSA_WITH_IDEA_CBC_MD5"; + break; + case SSL_RSA_WITH_DES_CBC_MD5: + return "SSL_RSA_WITH_DES_CBC_MD5"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_MD5: + return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; + break; + } + return "SSL_NULL_WITH_NULL_NULL"; +} + +CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) +{ + switch(cipher) { + /* TLS 1.0 with AES (RFC 3268) */ + case TLS_RSA_WITH_AES_128_CBC_SHA: + return "TLS_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA: + return "TLS_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; + break; +#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS + /* TLS 1.0 with ECDSA (RFC 4492) */ + case TLS_ECDH_ECDSA_WITH_NULL_SHA: + return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_NULL_SHA: + return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_NULL_SHA: + return "TLS_ECDH_RSA_WITH_NULL_SHA"; + break; + case TLS_ECDH_RSA_WITH_RC4_128_SHA: + return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_NULL_SHA: + return "TLS_ECDHE_RSA_WITH_NULL_SHA"; + break; + case TLS_ECDHE_RSA_WITH_RC4_128_SHA: + return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_NULL_SHA: + return "TLS_ECDH_anon_WITH_NULL_SHA"; + break; + case TLS_ECDH_anon_WITH_RC4_128_SHA: + return "TLS_ECDH_anon_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; + break; +#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* TLS 1.2 (RFC 5246) */ + case TLS_RSA_WITH_NULL_MD5: + return "TLS_RSA_WITH_NULL_MD5"; + break; + case TLS_RSA_WITH_NULL_SHA: + return "TLS_RSA_WITH_NULL_SHA"; + break; + case TLS_RSA_WITH_RC4_128_MD5: + return "TLS_RSA_WITH_RC4_128_MD5"; + break; + case TLS_RSA_WITH_RC4_128_SHA: + return "TLS_RSA_WITH_RC4_128_SHA"; + break; + case TLS_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_RSA_WITH_NULL_SHA256: + return "TLS_RSA_WITH_NULL_SHA256"; + break; + case TLS_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_anon_WITH_RC4_128_MD5: + return "TLS_DH_anon_WITH_RC4_128_MD5"; + break; + case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA256: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA256: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; + break; + /* TLS 1.2 with AES GCM (RFC 5288) */ + case TLS_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_anon_WITH_AES_128_GCM_SHA256: + return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_anon_WITH_AES_256_GCM_SHA384: + return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; + break; + /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */ + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: + return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; + break; +#else + case SSL_RSA_WITH_NULL_MD5: + return "TLS_RSA_WITH_NULL_MD5"; + break; + case SSL_RSA_WITH_NULL_SHA: + return "TLS_RSA_WITH_NULL_SHA"; + break; + case SSL_RSA_WITH_RC4_128_MD5: + return "TLS_RSA_WITH_RC4_128_MD5"; + break; + case SSL_RSA_WITH_RC4_128_SHA: + return "TLS_RSA_WITH_RC4_128_SHA"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_anon_WITH_RC4_128_MD5: + return "TLS_DH_anon_WITH_RC4_128_MD5"; + break; + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* TLS PSK (RFC 4279): */ + case TLS_PSK_WITH_RC4_128_SHA: + return "TLS_PSK_WITH_RC4_128_SHA"; + break; + case TLS_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_PSK_WITH_AES_128_CBC_SHA: + return "TLS_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_PSK_WITH_AES_256_CBC_SHA: + return "TLS_PSK_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_RC4_128_SHA: + return "TLS_DHE_PSK_WITH_RC4_128_SHA"; + break; + case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_RC4_128_SHA: + return "TLS_RSA_PSK_WITH_RC4_128_SHA"; + break; + case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; + break; + /* More TLS PSK (RFC 4785): */ + case TLS_PSK_WITH_NULL_SHA: + return "TLS_PSK_WITH_NULL_SHA"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA: + return "TLS_DHE_PSK_WITH_NULL_SHA"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA: + return "TLS_RSA_PSK_WITH_NULL_SHA"; + break; + /* Even more TLS PSK (RFC 5487): */ + case TLS_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_PSK_WITH_NULL_SHA256: + return "TLS_PSK_WITH_NULL_SHA256"; + break; + case TLS_PSK_WITH_NULL_SHA384: + return "TLS_PSK_WITH_NULL_SHA384"; + break; + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA256: + return "TLS_DHE_PSK_WITH_NULL_SHA256"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA384: + return "TLS_RSA_PSK_WITH_NULL_SHA384"; + break; + case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA256: + return "TLS_RSA_PSK_WITH_NULL_SHA256"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA384: + return "TLS_RSA_PSK_WITH_NULL_SHA384"; + break; +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ +#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 + /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */ + case TLS_AES_128_GCM_SHA256: + return "TLS_AES_128_GCM_SHA256"; + break; + case TLS_AES_256_GCM_SHA384: + return "TLS_AES_256_GCM_SHA384"; + break; + case TLS_CHACHA20_POLY1305_SHA256: + return "TLS_CHACHA20_POLY1305_SHA256"; + break; + case TLS_AES_128_CCM_SHA256: + return "TLS_AES_128_CCM_SHA256"; + break; + case TLS_AES_128_CCM_8_SHA256: + return "TLS_AES_128_CCM_8_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"; + break; +#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + } + return "TLS_NULL_WITH_NULL_NULL"; +} +#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ + +#if CURL_BUILD_MAC +CF_INLINE void GetDarwinVersionNumber(int *major, int *minor) +{ + int mib[2]; + char *os_version; + size_t os_version_len; + char *os_version_major, *os_version_minor; + char *tok_buf; + + /* Get the Darwin kernel version from the kernel using sysctl(): */ + mib[0] = CTL_KERN; + mib[1] = KERN_OSRELEASE; + if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1) + return; + os_version = malloc(os_version_len*sizeof(char)); + if(!os_version) + return; + if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) { + free(os_version); + return; + } + + /* Parse the version: */ + os_version_major = strtok_r(os_version, ".", &tok_buf); + os_version_minor = strtok_r(NULL, ".", &tok_buf); + *major = atoi(os_version_major); + *minor = atoi(os_version_minor); + free(os_version); +} +#endif /* CURL_BUILD_MAC */ + +/* Apple provides a myriad of ways of getting information about a certificate + into a string. Some aren't available under iOS or newer cats. So here's + a unified function for getting a string describing the certificate that + ought to work in all cats starting with Leopard. */ +CF_INLINE CFStringRef getsubject(SecCertificateRef cert) +{ + CFStringRef server_cert_summary = CFSTR("(null)"); + +#if CURL_BUILD_IOS + /* iOS: There's only one way to do this. */ + server_cert_summary = SecCertificateCopySubjectSummary(cert); +#else +#if CURL_BUILD_MAC_10_7 + /* Lion & later: Get the long description if we can. */ + if(SecCertificateCopyLongDescription != NULL) + server_cert_summary = + SecCertificateCopyLongDescription(NULL, cert, NULL); + else +#endif /* CURL_BUILD_MAC_10_7 */ +#if CURL_BUILD_MAC_10_6 + /* Snow Leopard: Get the certificate summary. */ + if(SecCertificateCopySubjectSummary != NULL) + server_cert_summary = SecCertificateCopySubjectSummary(cert); + else +#endif /* CURL_BUILD_MAC_10_6 */ + /* Leopard is as far back as we go... */ + (void)SecCertificateCopyCommonName(cert, &server_cert_summary); +#endif /* CURL_BUILD_IOS */ + return server_cert_summary; +} + +static CURLcode CopyCertSubject(struct Curl_easy *data, + SecCertificateRef cert, char **certp) +{ + CFStringRef c = getsubject(cert); + CURLcode result = CURLE_OK; + const char *direct; + char *cbuf = NULL; + *certp = NULL; + + if(!c) { + failf(data, "SSL: invalid CA certificate subject"); + return CURLE_PEER_FAILED_VERIFICATION; + } + + /* If the subject is already available as UTF-8 encoded (ie 'direct') then + use that, else convert it. */ + direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8); + if(direct) { + *certp = strdup(direct); + if(!*certp) { + failf(data, "SSL: out of memory"); + result = CURLE_OUT_OF_MEMORY; + } + } + else { + size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1; + cbuf = calloc(cbuf_size, 1); + if(cbuf) { + if(!CFStringGetCString(c, cbuf, cbuf_size, + kCFStringEncodingUTF8)) { + failf(data, "SSL: invalid CA certificate subject"); + result = CURLE_PEER_FAILED_VERIFICATION; + } + else + /* pass back the buffer */ + *certp = cbuf; + } + else { + failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size); + result = CURLE_OUT_OF_MEMORY; + } + } + if(result) + free(cbuf); + CFRelease(c); + return result; +} + +#if CURL_SUPPORT_MAC_10_6 +/* The SecKeychainSearch API was deprecated in Lion, and using it will raise + deprecation warnings, so let's not compile this unless it's necessary: */ +static OSStatus CopyIdentityWithLabelOldSchool(char *label, + SecIdentityRef *out_c_a_k) +{ + OSStatus status = errSecItemNotFound; + SecKeychainAttributeList attr_list; + SecKeychainAttribute attr; + SecKeychainSearchRef search = NULL; + SecCertificateRef cert = NULL; + + /* Set up the attribute list: */ + attr_list.count = 1L; + attr_list.attr = &attr; + + /* Set up our lone search criterion: */ + attr.tag = kSecLabelItemAttr; + attr.data = label; + attr.length = (UInt32)strlen(label); + + /* Start searching: */ + status = SecKeychainSearchCreateFromAttributes(NULL, + kSecCertificateItemClass, + &attr_list, + &search); + if(status == noErr) { + status = SecKeychainSearchCopyNext(search, + (SecKeychainItemRef *)&cert); + if(status == noErr && cert) { + /* If we found a certificate, does it have a private key? */ + status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k); + CFRelease(cert); + } + } + + if(search) + CFRelease(search); + return status; +} +#endif /* CURL_SUPPORT_MAC_10_6 */ + +static OSStatus CopyIdentityWithLabel(char *label, + SecIdentityRef *out_cert_and_key) +{ + OSStatus status = errSecItemNotFound; + +#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS + CFArrayRef keys_list; + CFIndex keys_list_count; + CFIndex i; + CFStringRef common_name; + + /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. + kSecClassIdentity was introduced in Lion. If both exist, let's use them + to find the certificate. */ + if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { + CFTypeRef keys[5]; + CFTypeRef values[5]; + CFDictionaryRef query_dict; + CFStringRef label_cf = CFStringCreateWithCString(NULL, label, + kCFStringEncodingUTF8); + + /* Set up our search criteria and expected results: */ + values[0] = kSecClassIdentity; /* we want a certificate and a key */ + keys[0] = kSecClass; + values[1] = kCFBooleanTrue; /* we want a reference */ + keys[1] = kSecReturnRef; + values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the + * label matching below worked correctly */ + keys[2] = kSecMatchLimit; + /* identity searches need a SecPolicyRef in order to work */ + values[3] = SecPolicyCreateSSL(false, NULL); + keys[3] = kSecMatchPolicy; + /* match the name of the certificate (doesn't work in macOS 10.12.1) */ + values[4] = label_cf; + keys[4] = kSecAttrLabel; + query_dict = CFDictionaryCreate(NULL, (const void **)keys, + (const void **)values, 5L, + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease(values[3]); + + /* Do we have a match? */ + status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list); + + /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity, + * we need to find the correct identity ourselves */ + if(status == noErr) { + keys_list_count = CFArrayGetCount(keys_list); + *out_cert_and_key = NULL; + status = 1; + for(i = 0; i<keys_list_count; i++) { + OSStatus err = noErr; + SecCertificateRef cert = NULL; + SecIdentityRef identity = + (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i); + err = SecIdentityCopyCertificate(identity, &cert); + if(err == noErr) { +#if CURL_BUILD_IOS + common_name = SecCertificateCopySubjectSummary(cert); +#elif CURL_BUILD_MAC_10_7 + SecCertificateCopyCommonName(cert, &common_name); +#endif + if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) { + CFRelease(cert); + CFRelease(common_name); + CFRetain(identity); + *out_cert_and_key = identity; + status = noErr; + break; + } + CFRelease(common_name); + } + CFRelease(cert); + } + } + + if(keys_list) + CFRelease(keys_list); + CFRelease(query_dict); + CFRelease(label_cf); + } + else { +#if CURL_SUPPORT_MAC_10_6 + /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */ + status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key); +#endif /* CURL_SUPPORT_MAC_10_6 */ + } +#elif CURL_SUPPORT_MAC_10_6 + /* For developers building on older cats, we have no choice but to fall back + to SecKeychainSearch. */ + status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key); +#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ + return status; +} + +static OSStatus CopyIdentityFromPKCS12File(const char *cPath, const struct curl_blob *blob, - const char *cPassword, - SecIdentityRef *out_cert_and_key) -{ - OSStatus status = errSecItemNotFound; + const char *cPassword, + SecIdentityRef *out_cert_and_key) +{ + OSStatus status = errSecItemNotFound; CFURLRef pkcs_url = NULL; - CFStringRef password = cPassword ? CFStringCreateWithCString(NULL, - cPassword, kCFStringEncodingUTF8) : NULL; - CFDataRef pkcs_data = NULL; - - /* We can import P12 files on iOS or OS X 10.7 or later: */ - /* These constants are documented as having first appeared in 10.6 but they - raise linker errors when used on that cat for some reason. */ -#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS + CFStringRef password = cPassword ? CFStringCreateWithCString(NULL, + cPassword, kCFStringEncodingUTF8) : NULL; + CFDataRef pkcs_data = NULL; + + /* We can import P12 files on iOS or OS X 10.7 or later: */ + /* These constants are documented as having first appeared in 10.6 but they + raise linker errors when used on that cat for some reason. */ +#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS bool resource_imported; if(blob) { @@ -1160,2167 +1160,2167 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath, } if(resource_imported) { - CFArrayRef items = NULL; - - /* On iOS SecPKCS12Import will never add the client certificate to the - * Keychain. - * - * It gives us back a SecIdentityRef that we can use directly. */ -#if CURL_BUILD_IOS - const void *cKeys[] = {kSecImportExportPassphrase}; - const void *cValues[] = {password}; - CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues, - password ? 1L : 0L, NULL, NULL); - - if(options != NULL) { - status = SecPKCS12Import(pkcs_data, options, &items); - CFRelease(options); - } - - - /* On macOS SecPKCS12Import will always add the client certificate to - * the Keychain. - * - * As this doesn't match iOS, and apps may not want to see their client + CFArrayRef items = NULL; + + /* On iOS SecPKCS12Import will never add the client certificate to the + * Keychain. + * + * It gives us back a SecIdentityRef that we can use directly. */ +#if CURL_BUILD_IOS + const void *cKeys[] = {kSecImportExportPassphrase}; + const void *cValues[] = {password}; + CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues, + password ? 1L : 0L, NULL, NULL); + + if(options != NULL) { + status = SecPKCS12Import(pkcs_data, options, &items); + CFRelease(options); + } + + + /* On macOS SecPKCS12Import will always add the client certificate to + * the Keychain. + * + * As this doesn't match iOS, and apps may not want to see their client * certificate saved in the user's keychain, we use SecItemImport - * with a NULL keychain to avoid importing it. - * - * This returns a SecCertificateRef from which we can construct a - * SecIdentityRef. - */ -#elif CURL_BUILD_MAC_10_7 - SecItemImportExportKeyParameters keyParams; - SecExternalFormat inputFormat = kSecFormatPKCS12; - SecExternalItemType inputType = kSecItemTypeCertificate; - - memset(&keyParams, 0x00, sizeof(keyParams)); - keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - keyParams.passphrase = password; - - status = SecItemImport(pkcs_data, NULL, &inputFormat, &inputType, - 0, &keyParams, NULL, &items); -#endif - - - /* Extract the SecIdentityRef */ - if(status == errSecSuccess && items && CFArrayGetCount(items)) { - CFIndex i, count; - count = CFArrayGetCount(items); - - for(i = 0; i < count; i++) { - CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i); - CFTypeID itemID = CFGetTypeID(item); - - if(itemID == CFDictionaryGetTypeID()) { - CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue( - (CFDictionaryRef) item, - kSecImportItemIdentity); - CFRetain(identity); - *out_cert_and_key = (SecIdentityRef) identity; - break; - } -#if CURL_BUILD_MAC_10_7 - else if(itemID == SecCertificateGetTypeID()) { - status = SecIdentityCreateWithCertificate(NULL, - (SecCertificateRef) item, - out_cert_and_key); - break; - } -#endif - } - } - - if(items) - CFRelease(items); - CFRelease(pkcs_data); - } -#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ - if(password) - CFRelease(password); + * with a NULL keychain to avoid importing it. + * + * This returns a SecCertificateRef from which we can construct a + * SecIdentityRef. + */ +#elif CURL_BUILD_MAC_10_7 + SecItemImportExportKeyParameters keyParams; + SecExternalFormat inputFormat = kSecFormatPKCS12; + SecExternalItemType inputType = kSecItemTypeCertificate; + + memset(&keyParams, 0x00, sizeof(keyParams)); + keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; + keyParams.passphrase = password; + + status = SecItemImport(pkcs_data, NULL, &inputFormat, &inputType, + 0, &keyParams, NULL, &items); +#endif + + + /* Extract the SecIdentityRef */ + if(status == errSecSuccess && items && CFArrayGetCount(items)) { + CFIndex i, count; + count = CFArrayGetCount(items); + + for(i = 0; i < count; i++) { + CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i); + CFTypeID itemID = CFGetTypeID(item); + + if(itemID == CFDictionaryGetTypeID()) { + CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue( + (CFDictionaryRef) item, + kSecImportItemIdentity); + CFRetain(identity); + *out_cert_and_key = (SecIdentityRef) identity; + break; + } +#if CURL_BUILD_MAC_10_7 + else if(itemID == SecCertificateGetTypeID()) { + status = SecIdentityCreateWithCertificate(NULL, + (SecCertificateRef) item, + out_cert_and_key); + break; + } +#endif + } + } + + if(items) + CFRelease(items); + CFRelease(pkcs_data); + } +#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ + if(password) + CFRelease(password); if(pkcs_url) CFRelease(pkcs_url); - return status; -} - -/* This code was borrowed from nss.c, with some modifications: - * Determine whether the nickname passed in is a filename that needs to - * be loaded as a PEM or a regular NSS nickname. - * - * returns 1 for a file - * returns 0 for not a file - */ -CF_INLINE bool is_file(const char *filename) -{ - struct_stat st; - - if(filename == NULL) - return false; - - if(stat(filename, &st) == 0) - return S_ISREG(st.st_mode); - return false; -} - -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS -static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver, - long ssl_version) -{ - switch(ssl_version) { - case CURL_SSLVERSION_TLSv1_0: - *darwinver = kTLSProtocol1; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1: - *darwinver = kTLSProtocol11; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2: - *darwinver = kTLSProtocol12; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3: - /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */ -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - *darwinver = kTLSProtocol13; - return CURLE_OK; - } -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - HAVE_BUILTIN_AVAILABLE == 1 */ - break; - } - return CURLE_SSL_CONNECT_ERROR; -} -#endif - -static CURLcode -set_ssl_version_min_max(struct connectdata *conn, int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + return status; +} + +/* This code was borrowed from nss.c, with some modifications: + * Determine whether the nickname passed in is a filename that needs to + * be loaded as a PEM or a regular NSS nickname. + * + * returns 1 for a file + * returns 0 for not a file + */ +CF_INLINE bool is_file(const char *filename) +{ + struct_stat st; + + if(filename == NULL) + return false; + + if(stat(filename, &st) == 0) + return S_ISREG(st.st_mode); + return false; +} + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS +static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver, + long ssl_version) +{ + switch(ssl_version) { + case CURL_SSLVERSION_TLSv1_0: + *darwinver = kTLSProtocol1; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1: + *darwinver = kTLSProtocol11; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_2: + *darwinver = kTLSProtocol12; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3: + /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */ +#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(__builtin_available(macOS 10.13, iOS 11.0, *)) { + *darwinver = kTLSProtocol13; + return CURLE_OK; + } +#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && + HAVE_BUILTIN_AVAILABLE == 1 */ + break; + } + return CURLE_SSL_CONNECT_ERROR; +} +#endif + +static CURLcode +set_ssl_version_min_max(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - long ssl_version = SSL_CONN_CONFIG(version); - long ssl_version_max = SSL_CONN_CONFIG(version_max); - long max_supported_version_by_os; - - /* macOS 10.5-10.7 supported TLS 1.0 only. - macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2. - macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */ -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3; - } - else { - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; - } -#else - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - HAVE_BUILTIN_AVAILABLE == 1 */ - - switch(ssl_version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - ssl_version = CURL_SSLVERSION_TLSv1_0; - break; - } - - switch(ssl_version_max) { - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_DEFAULT: - ssl_version_max = max_supported_version_by_os; - break; - } - -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(SSLSetProtocolVersionMax != NULL) { - SSLProtocol darwin_ver_min = kTLSProtocol1; - SSLProtocol darwin_ver_max = kTLSProtocol1; - CURLcode result = sectransp_version_from_curl(&darwin_ver_min, - ssl_version); - if(result) { - failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); - return result; - } - result = sectransp_version_from_curl(&darwin_ver_max, - ssl_version_max >> 16); - if(result) { - failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); - return result; - } - + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + long max_supported_version_by_os; + + /* macOS 10.5-10.7 supported TLS 1.0 only. + macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2. + macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */ +#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(__builtin_available(macOS 10.13, iOS 11.0, *)) { + max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3; + } + else { + max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; + } +#else + max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; +#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && + HAVE_BUILTIN_AVAILABLE == 1 */ + + switch(ssl_version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + ssl_version = CURL_SSLVERSION_TLSv1_0; + break; + } + + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + ssl_version_max = max_supported_version_by_os; + break; + } + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLSetProtocolVersionMax != NULL) { + SSLProtocol darwin_ver_min = kTLSProtocol1; + SSLProtocol darwin_ver_max = kTLSProtocol1; + CURLcode result = sectransp_version_from_curl(&darwin_ver_min, + ssl_version); + if(result) { + failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); + return result; + } + result = sectransp_version_from_curl(&darwin_ver_max, + ssl_version_max >> 16); + if(result) { + failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); + return result; + } + (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min); (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max); - return result; - } - else { -#if CURL_SUPPORT_MAC_10_8 - long i = ssl_version; + return result; + } + else { +#if CURL_SUPPORT_MAC_10_8 + long i = ssl_version; (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocolAll, - false); - for(; i <= (ssl_version_max >> 16); i++) { - switch(i) { - case CURL_SSLVERSION_TLSv1_0: + kSSLProtocolAll, + false); + for(; i <= (ssl_version_max >> 16); i++) { + switch(i) { + case CURL_SSLVERSION_TLSv1_0: (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); - break; - case CURL_SSLVERSION_TLSv1_1: + kTLSProtocol1, + true); + break; + case CURL_SSLVERSION_TLSv1_1: (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol11, - true); - break; - case CURL_SSLVERSION_TLSv1_2: + kTLSProtocol11, + true); + break; + case CURL_SSLVERSION_TLSv1_2: (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol12, - true); - break; - case CURL_SSLVERSION_TLSv1_3: - failf(data, "Your version of the OS does not support TLSv1.3"); - return CURLE_SSL_CONNECT_ERROR; - } - } - return CURLE_OK; -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - failf(data, "Secure Transport: cannot set SSL protocol"); - return CURLE_SSL_CONNECT_ERROR; -} - - -static CURLcode sectransp_connect_step1(struct connectdata *conn, - int sockindex) -{ - struct Curl_easy *data = conn->data; - curl_socket_t sockfd = conn->sock[sockindex]; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + kTLSProtocol12, + true); + break; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "Your version of the OS does not support TLSv1.3"); + return CURLE_SSL_CONNECT_ERROR; + } + } + return CURLE_OK; +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + failf(data, "Secure Transport: cannot set SSL protocol"); + return CURLE_SSL_CONNECT_ERROR; +} + + +static CURLcode sectransp_connect_step1(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + curl_socket_t sockfd = conn->sock[sockindex]; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); const struct curl_blob *ssl_cablob = NULL; - const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); #ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; #else const char * const hostname = conn->host.name; const long int port = conn->remote_port; #endif -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif /* ENABLE_IPV6 */ - size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; - SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; - OSStatus err = noErr; -#if CURL_BUILD_MAC - int darwinver_maj = 0, darwinver_min = 0; - - GetDarwinVersionNumber(&darwinver_maj, &darwinver_min); -#endif /* CURL_BUILD_MAC */ - -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(SSLCreateContext != NULL) { /* use the newer API if available */ +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif /* ENABLE_IPV6 */ + size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; + SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; + OSStatus err = noErr; +#if CURL_BUILD_MAC + int darwinver_maj = 0, darwinver_min = 0; + + GetDarwinVersionNumber(&darwinver_maj, &darwinver_min); +#endif /* CURL_BUILD_MAC */ + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLCreateContext != NULL) { /* use the newer API if available */ if(backend->ssl_ctx) CFRelease(backend->ssl_ctx); backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); if(!backend->ssl_ctx) { - failf(data, "SSL: couldn't create a context!"); - return CURLE_OUT_OF_MEMORY; - } - } - else { - /* The old ST API does not exist under iOS, so don't compile it: */ -#if CURL_SUPPORT_MAC_10_8 + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + } + else { + /* The old ST API does not exist under iOS, so don't compile it: */ +#if CURL_SUPPORT_MAC_10_8 if(backend->ssl_ctx) (void)SSLDisposeContext(backend->ssl_ctx); err = SSLNewContext(false, &(backend->ssl_ctx)); - if(err != noErr) { - failf(data, "SSL: couldn't create a context: OSStatus %d", err); - return CURLE_OUT_OF_MEMORY; - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#else + if(err != noErr) { + failf(data, "SSL: couldn't create a context: OSStatus %d", err); + return CURLE_OUT_OF_MEMORY; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else if(backend->ssl_ctx) (void)SSLDisposeContext(backend->ssl_ctx); err = SSLNewContext(false, &(backend->ssl_ctx)); - if(err != noErr) { - failf(data, "SSL: couldn't create a context: OSStatus %d", err); - return CURLE_OUT_OF_MEMORY; - } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + if(err != noErr) { + failf(data, "SSL: couldn't create a context: OSStatus %d", err); + return CURLE_OUT_OF_MEMORY; + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */ - - /* check to see if we've been told to use an explicit SSL/TLS version */ -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(SSLSetProtocolVersionMax != NULL) { - switch(conn->ssl_config.version) { - case CURL_SSLVERSION_TLSv1: + + /* check to see if we've been told to use an explicit SSL/TLS version */ +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLSetProtocolVersionMax != NULL) { + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_TLSv1: (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1); -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { +#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(__builtin_available(macOS 10.13, iOS 11.0, *)) { (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13); - } - else { + } + else { (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); - } -#else + } +#else (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - HAVE_BUILTIN_AVAILABLE == 1 */ - break; - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - { - CURLcode result = set_ssl_version_min_max(conn, sockindex); - if(result != CURLE_OK) - return result; - break; - } - case CURL_SSLVERSION_SSLv3: +#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && + HAVE_BUILTIN_AVAILABLE == 1 */ + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(conn, sockindex); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv3: err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol3); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol3); - break; - case CURL_SSLVERSION_SSLv2: + break; + case CURL_SSLVERSION_SSLv2: err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol2); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol2); - break; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { -#if CURL_SUPPORT_MAC_10_8 + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#if CURL_SUPPORT_MAC_10_8 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocolAll, - false); - switch(conn->ssl_config.version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: + kSSLProtocolAll, + false); + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); + kTLSProtocol1, + true); (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol11, - true); + kTLSProtocol11, + true); (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol12, - true); - break; - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - { - CURLcode result = set_ssl_version_min_max(conn, sockindex); - if(result != CURLE_OK) - return result; - break; - } - case CURL_SSLVERSION_SSLv3: + kTLSProtocol12, + true); + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(conn, sockindex); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv3: err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol3, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - case CURL_SSLVERSION_SSLv2: + kSSLProtocol3, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + case CURL_SSLVERSION_SSLv2: err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol2, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#else - if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) { - failf(data, "Your version of the OS does not support to set maximum" - " SSL/TLS version"); - return CURLE_SSL_CONNECT_ERROR; - } + kSSLProtocol2, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else + if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) { + failf(data, "Your version of the OS does not support to set maximum" + " SSL/TLS version"); + return CURLE_SSL_CONNECT_ERROR; + } (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); - switch(conn->ssl_config.version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); - break; - case CURL_SSLVERSION_TLSv1_1: - failf(data, "Your version of the OS does not support TLSv1.1"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_2: - failf(data, "Your version of the OS does not support TLSv1.2"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_3: - failf(data, "Your version of the OS does not support TLSv1.3"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_SSLv2: + kTLSProtocol1, + true); + break; + case CURL_SSLVERSION_TLSv1_1: + failf(data, "Your version of the OS does not support TLSv1.1"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_2: + failf(data, "Your version of the OS does not support TLSv1.2"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "Your version of the OS does not support TLSv1.3"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv2: err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol2, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - case CURL_SSLVERSION_SSLv3: + kSSLProtocol2, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + case CURL_SSLVERSION_SSLv3: err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol3, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 - if(conn->bits.tls_enable_alpn) { - if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { - CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0, - &kCFTypeArrayCallBacks); - -#ifdef USE_NGHTTP2 + kSSLProtocol3, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + +#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(conn->bits.tls_enable_alpn) { + if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { + CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0, + &kCFTypeArrayCallBacks); + +#ifdef USE_NGHTTP2 if(data->set.httpversion >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1)); - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - - /* expects length prefixed preference ordered list of protocols in wire - * format - */ + CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1)); + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + /* expects length prefixed preference ordered list of protocols in wire + * format + */ err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr); - if(err != noErr) - infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n", - err); - CFRelease(alpnArr); - } - } -#endif - - if(SSL_SET_OPTION(key)) { - infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure " - "Transport. The private key must be in the Keychain.\n"); - } - + if(err != noErr) + infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n", + err); + CFRelease(alpnArr); + } + } +#endif + + if(SSL_SET_OPTION(key)) { + infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure " + "Transport. The private key must be in the Keychain.\n"); + } + if(ssl_cert || ssl_cert_blob) { bool is_cert_data = ssl_cert_blob != NULL; bool is_cert_file = (!is_cert_data) && is_file(ssl_cert); - SecIdentityRef cert_and_key = NULL; - - /* User wants to authenticate with a client cert. Look for it: - If we detect that this is a file on disk, then let's load it. - Otherwise, assume that the user wants to use an identity loaded - from the Keychain. */ + SecIdentityRef cert_and_key = NULL; + + /* User wants to authenticate with a client cert. Look for it: + If we detect that this is a file on disk, then let's load it. + Otherwise, assume that the user wants to use an identity loaded + from the Keychain. */ if(is_cert_file || is_cert_data) { - if(!SSL_SET_OPTION(cert_type)) - infof(data, "WARNING: SSL: Certificate type not set, assuming " - "PKCS#12 format.\n"); - else if(strncmp(SSL_SET_OPTION(cert_type), "P12", - strlen(SSL_SET_OPTION(cert_type))) != 0) - infof(data, "WARNING: SSL: The Security framework only supports " - "loading identities that are in PKCS#12 format.\n"); - + if(!SSL_SET_OPTION(cert_type)) + infof(data, "WARNING: SSL: Certificate type not set, assuming " + "PKCS#12 format.\n"); + else if(strncmp(SSL_SET_OPTION(cert_type), "P12", + strlen(SSL_SET_OPTION(cert_type))) != 0) + infof(data, "WARNING: SSL: The Security framework only supports " + "loading identities that are in PKCS#12 format.\n"); + err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob, - SSL_SET_OPTION(key_passwd), &cert_and_key); - } - else - err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); - - if(err == noErr && cert_and_key) { - SecCertificateRef cert = NULL; - CFTypeRef certs_c[1]; - CFArrayRef certs; - - /* If we found one, print it out: */ - err = SecIdentityCopyCertificate(cert_and_key, &cert); - if(err == noErr) { - char *certp; - CURLcode result = CopyCertSubject(data, cert, &certp); - if(!result) { - infof(data, "Client certificate: %s\n", certp); - free(certp); - } - - CFRelease(cert); - if(result == CURLE_PEER_FAILED_VERIFICATION) - return CURLE_SSL_CERTPROBLEM; - if(result) - return result; - } - certs_c[0] = cert_and_key; - certs = CFArrayCreate(NULL, (const void **)certs_c, 1L, - &kCFTypeArrayCallBacks); + SSL_SET_OPTION(key_passwd), &cert_and_key); + } + else + err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); + + if(err == noErr && cert_and_key) { + SecCertificateRef cert = NULL; + CFTypeRef certs_c[1]; + CFArrayRef certs; + + /* If we found one, print it out: */ + err = SecIdentityCopyCertificate(cert_and_key, &cert); + if(err == noErr) { + char *certp; + CURLcode result = CopyCertSubject(data, cert, &certp); + if(!result) { + infof(data, "Client certificate: %s\n", certp); + free(certp); + } + + CFRelease(cert); + if(result == CURLE_PEER_FAILED_VERIFICATION) + return CURLE_SSL_CERTPROBLEM; + if(result) + return result; + } + certs_c[0] = cert_and_key; + certs = CFArrayCreate(NULL, (const void **)certs_c, 1L, + &kCFTypeArrayCallBacks); err = SSLSetCertificate(backend->ssl_ctx, certs); - if(certs) - CFRelease(certs); - if(err != noErr) { - failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err); - return CURLE_SSL_CERTPROBLEM; - } - CFRelease(cert_and_key); - } - else { + if(certs) + CFRelease(certs); + if(err != noErr) { + failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err); + return CURLE_SSL_CERTPROBLEM; + } + CFRelease(cert_and_key); + } + else { const char *cert_showfilename_error = is_cert_data ? "(memory blob)" : ssl_cert; - switch(err) { - case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */ - failf(data, "SSL: Incorrect password for the certificate \"%s\" " + switch(err) { + case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */ + failf(data, "SSL: Incorrect password for the certificate \"%s\" " "and its private key.", cert_showfilename_error); - break; - case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */ - failf(data, "SSL: Couldn't make sense of the data in the " - "certificate \"%s\" and its private key.", + break; + case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */ + failf(data, "SSL: Couldn't make sense of the data in the " + "certificate \"%s\" and its private key.", cert_showfilename_error); - break; - case -25260: /* errSecPassphraseRequired */ - failf(data, "SSL The certificate \"%s\" requires a password.", + break; + case -25260: /* errSecPassphraseRequired */ + failf(data, "SSL The certificate \"%s\" requires a password.", cert_showfilename_error); - break; - case errSecItemNotFound: - failf(data, "SSL: Can't find the certificate \"%s\" and its private " + break; + case errSecItemNotFound: + failf(data, "SSL: Can't find the certificate \"%s\" and its private " "key in the Keychain.", cert_showfilename_error); - break; - default: - failf(data, "SSL: Can't load the certificate \"%s\" and its private " + break; + default: + failf(data, "SSL: Can't load the certificate \"%s\" and its private " "key: OSStatus %d", cert_showfilename_error, err); - break; - } - return CURLE_SSL_CERTPROBLEM; - } - } - - /* SSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ -#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS - /* Snow Leopard introduced the SSLSetSessionOption() function, but due to - a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag - works, it doesn't work as expected under Snow Leopard, Lion or - Mountain Lion. - So we need to call SSLSetEnableCertVerify() on those older cats in order - to disable certificate validation if the user turned that off. - (SecureTransport will always validate the certificate chain by - default.) - Note: - Darwin 11.x.x is Lion (10.7) - Darwin 12.x.x is Mountain Lion (10.8) - Darwin 13.x.x is Mavericks (10.9) - Darwin 14.x.x is Yosemite (10.10) - Darwin 15.x.x is El Capitan (10.11) - */ -#if CURL_BUILD_MAC - if(SSLSetSessionOption != NULL && darwinver_maj >= 13) { -#else - if(SSLSetSessionOption != NULL) { -#endif /* CURL_BUILD_MAC */ + break; + } + return CURLE_SSL_CERTPROBLEM; + } + } + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ +#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS + /* Snow Leopard introduced the SSLSetSessionOption() function, but due to + a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag + works, it doesn't work as expected under Snow Leopard, Lion or + Mountain Lion. + So we need to call SSLSetEnableCertVerify() on those older cats in order + to disable certificate validation if the user turned that off. + (SecureTransport will always validate the certificate chain by + default.) + Note: + Darwin 11.x.x is Lion (10.7) + Darwin 12.x.x is Mountain Lion (10.8) + Darwin 13.x.x is Mavericks (10.9) + Darwin 14.x.x is Yosemite (10.10) + Darwin 15.x.x is El Capitan (10.11) + */ +#if CURL_BUILD_MAC + if(SSLSetSessionOption != NULL && darwinver_maj >= 13) { +#else + if(SSLSetSessionOption != NULL) { +#endif /* CURL_BUILD_MAC */ bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile || ssl_cablob; err = SSLSetSessionOption(backend->ssl_ctx, - kSSLSessionOptionBreakOnServerAuth, - break_on_auth); - if(err != noErr) { - failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { -#if CURL_SUPPORT_MAC_10_8 + kSSLSessionOptionBreakOnServerAuth, + break_on_auth); + if(err != noErr) { + failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#if CURL_SUPPORT_MAC_10_8 err = SSLSetEnableCertVerify(backend->ssl_ctx, - conn->ssl_config.verifypeer?true:false); - if(err != noErr) { - failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#else + conn->ssl_config.verifypeer?true:false); + if(err != noErr) { + failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else err = SSLSetEnableCertVerify(backend->ssl_ctx, - conn->ssl_config.verifypeer?true:false); - if(err != noErr) { - failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ - + conn->ssl_config.verifypeer?true:false); + if(err != noErr) { + failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ + if((ssl_cafile || ssl_cablob) && verifypeer) { bool is_cert_data = ssl_cablob != NULL; bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile); - + if(!(is_cert_file || is_cert_data)) { - failf(data, "SSL: can't load CA certificate file %s", ssl_cafile); - return CURLE_SSL_CACERT_BADFILE; - } - } - - /* Configure hostname check. SNI is used if available. - * Both hostname check and SNI require SSLSetPeerDomainName(). - * Also: the verifyhost setting influences SNI usage */ - if(conn->ssl_config.verifyhost) { + failf(data, "SSL: can't load CA certificate file %s", ssl_cafile); + return CURLE_SSL_CACERT_BADFILE; + } + } + + /* Configure hostname check. SNI is used if available. + * Both hostname check and SNI require SSLSetPeerDomainName(). + * Also: the verifyhost setting influences SNI usage */ + if(conn->ssl_config.verifyhost) { err = SSLSetPeerDomainName(backend->ssl_ctx, hostname, - strlen(hostname)); - - if(err != noErr) { - infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n", - err); - } - - if((Curl_inet_pton(AF_INET, hostname, &addr)) - #ifdef ENABLE_IPV6 - || (Curl_inet_pton(AF_INET6, hostname, &addr)) - #endif - ) { - infof(data, "WARNING: using IP address, SNI is being disabled by " - "the OS.\n"); - } - } - else { - infof(data, "WARNING: disabling hostname validation also disables SNI.\n"); - } - - /* Disable cipher suites that ST supports but are not safe. These ciphers - are unlikely to be used in any case since ST gives other ciphers a much - higher priority, but it's probably better that we not connect at all than - to give the user a false sense of security if the server only supports - insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ + strlen(hostname)); + + if(err != noErr) { + infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n", + err); + } + + if((Curl_inet_pton(AF_INET, hostname, &addr)) + #ifdef ENABLE_IPV6 + || (Curl_inet_pton(AF_INET6, hostname, &addr)) + #endif + ) { + infof(data, "WARNING: using IP address, SNI is being disabled by " + "the OS.\n"); + } + } + else { + infof(data, "WARNING: disabling hostname validation also disables SNI.\n"); + } + + /* Disable cipher suites that ST supports but are not safe. These ciphers + are unlikely to be used in any case since ST gives other ciphers a much + higher priority, but it's probably better that we not connect at all than + to give the user a false sense of security if the server only supports + insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count); - if(err != noErr) { - failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", - err); - return CURLE_SSL_CIPHER; - } - all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - if(!all_ciphers) { - failf(data, "SSL: Failed to allocate memory for all ciphers"); - return CURLE_OUT_OF_MEMORY; - } - allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - if(!allowed_ciphers) { - Curl_safefree(all_ciphers); - failf(data, "SSL: Failed to allocate memory for allowed ciphers"); - return CURLE_OUT_OF_MEMORY; - } + if(err != noErr) { + failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", + err); + return CURLE_SSL_CIPHER; + } + all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!all_ciphers) { + failf(data, "SSL: Failed to allocate memory for all ciphers"); + return CURLE_OUT_OF_MEMORY; + } + allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!allowed_ciphers) { + Curl_safefree(all_ciphers); + failf(data, "SSL: Failed to allocate memory for allowed ciphers"); + return CURLE_OUT_OF_MEMORY; + } err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers, - &all_ciphers_count); - if(err != noErr) { - Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); - return CURLE_SSL_CIPHER; - } - for(i = 0UL ; i < all_ciphers_count ; i++) { -#if CURL_BUILD_MAC - /* There's a known bug in early versions of Mountain Lion where ST's ECC - ciphers (cipher suite 0xC001 through 0xC032) simply do not work. - Work around the problem here by disabling those ciphers if we are - running in an affected version of OS X. */ - if(darwinver_maj == 12 && darwinver_min <= 3 && - all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { - continue; - } -#endif /* CURL_BUILD_MAC */ - switch(all_ciphers[i]) { - /* Disable NULL ciphersuites: */ - case SSL_NULL_WITH_NULL_NULL: - case SSL_RSA_WITH_NULL_MD5: - case SSL_RSA_WITH_NULL_SHA: - case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ - case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ - case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ - case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ - case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ - case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ - case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ - case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ - case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ - case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ - case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ - case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ - case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ - /* Disable anonymous ciphersuites: */ - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - case SSL_DH_anon_WITH_RC4_128_MD5: - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_anon_WITH_DES_CBC_SHA: - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ - case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ - case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ - case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ - case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ - case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ - case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ - case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ - case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ - /* Disable weak key ciphersuites: */ - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_RSA_WITH_DES_CBC_SHA: - case SSL_DH_DSS_WITH_DES_CBC_SHA: - case SSL_DH_RSA_WITH_DES_CBC_SHA: - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - /* Disable IDEA: */ - case SSL_RSA_WITH_IDEA_CBC_SHA: - case SSL_RSA_WITH_IDEA_CBC_MD5: - /* Disable RC4: */ - case SSL_RSA_WITH_RC4_128_MD5: - case SSL_RSA_WITH_RC4_128_SHA: - case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ - case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/ - case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */ - case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ - case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */ - case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */ - case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */ - break; - default: /* enable everything else */ - allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; - break; - } - } + &all_ciphers_count); + if(err != noErr) { + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + return CURLE_SSL_CIPHER; + } + for(i = 0UL ; i < all_ciphers_count ; i++) { +#if CURL_BUILD_MAC + /* There's a known bug in early versions of Mountain Lion where ST's ECC + ciphers (cipher suite 0xC001 through 0xC032) simply do not work. + Work around the problem here by disabling those ciphers if we are + running in an affected version of OS X. */ + if(darwinver_maj == 12 && darwinver_min <= 3 && + all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { + continue; + } +#endif /* CURL_BUILD_MAC */ + switch(all_ciphers[i]) { + /* Disable NULL ciphersuites: */ + case SSL_NULL_WITH_NULL_NULL: + case SSL_RSA_WITH_NULL_MD5: + case SSL_RSA_WITH_NULL_SHA: + case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ + case SSL_FORTEZZA_DMS_WITH_NULL_SHA: + case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ + case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ + case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ + case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ + case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ + case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ + case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ + case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ + case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ + case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ + case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ + case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ + case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ + /* Disable anonymous ciphersuites: */ + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: + case SSL_DH_anon_WITH_RC4_128_MD5: + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_anon_WITH_DES_CBC_SHA: + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ + case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ + case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ + case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ + case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ + case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ + case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ + case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ + case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ + /* Disable weak key ciphersuites: */ + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_RSA_WITH_DES_CBC_SHA: + case SSL_DH_DSS_WITH_DES_CBC_SHA: + case SSL_DH_RSA_WITH_DES_CBC_SHA: + case SSL_DHE_DSS_WITH_DES_CBC_SHA: + case SSL_DHE_RSA_WITH_DES_CBC_SHA: + /* Disable IDEA: */ + case SSL_RSA_WITH_IDEA_CBC_SHA: + case SSL_RSA_WITH_IDEA_CBC_MD5: + /* Disable RC4: */ + case SSL_RSA_WITH_RC4_128_MD5: + case SSL_RSA_WITH_RC4_128_SHA: + case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ + case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/ + case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */ + case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ + case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */ + case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */ + case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */ + break; + default: /* enable everything else */ + allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; + break; + } + } err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers, - allowed_ciphers_count); - Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); - if(err != noErr) { - failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); - return CURLE_SSL_CIPHER; - } - -#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 - /* We want to enable 1/n-1 when using a CBC cipher unless the user - specifically doesn't want us doing that: */ - if(SSLSetSessionOption != NULL) { + allowed_ciphers_count); + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + if(err != noErr) { + failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + return CURLE_SSL_CIPHER; + } + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* We want to enable 1/n-1 when using a CBC cipher unless the user + specifically doesn't want us doing that: */ + if(SSLSetSessionOption != NULL) { SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord, - !data->set.ssl.enable_beast); + !data->set.ssl.enable_beast); SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart, - data->set.ssl.falsestart); /* false start support */ - } -#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ - - /* Check if there's a cached ID we can/should use here! */ - if(SSL_SET_OPTION(primary.sessionid)) { - char *ssl_sessionid; - size_t ssl_sessionid_len; - - Curl_ssl_sessionid_lock(conn); - if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid, - &ssl_sessionid_len, sockindex)) { - /* we got a session id, use it! */ + data->set.ssl.falsestart); /* false start support */ + } +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + char *ssl_sessionid; + size_t ssl_sessionid_len; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid, + &ssl_sessionid_len, sockindex)) { + /* we got a session id, use it! */ err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len); - Curl_ssl_sessionid_unlock(conn); - if(err != noErr) { - failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - infof(data, "SSL re-using session ID\n"); - } - /* If there isn't one, then let's make one up! This has to be done prior - to starting the handshake. */ - else { - CURLcode result; - ssl_sessionid = + Curl_ssl_sessionid_unlock(conn); + if(err != noErr) { + failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + /* If there isn't one, then let's make one up! This has to be done prior + to starting the handshake. */ + else { + CURLcode result; + ssl_sessionid = aprintf("%s:%d:%d:%s:%ld", ssl_cafile, - verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port); - ssl_sessionid_len = strlen(ssl_sessionid); - + verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port); + ssl_sessionid_len = strlen(ssl_sessionid); + err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len); - if(err != noErr) { - Curl_ssl_sessionid_unlock(conn); - failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - - result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len, - sockindex); - Curl_ssl_sessionid_unlock(conn); - if(result) { - failf(data, "failed to store ssl session"); - return result; - } - } - } - + if(err != noErr) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len, + sockindex); + Curl_ssl_sessionid_unlock(conn); + if(result) { + failf(data, "failed to store ssl session"); + return result; + } + } + } + err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite); - if(err != noErr) { - failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - - /* pass the raw socket into the SSL layers */ - /* We need to store the FD in a constant memory address, because - * SSLSetConnection() will not copy that address. I've found that - * conn->sock[sockindex] may change on its own. */ + if(err != noErr) { + failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + /* pass the raw socket into the SSL layers */ + /* We need to store the FD in a constant memory address, because + * SSLSetConnection() will not copy that address. I've found that + * conn->sock[sockindex] may change on its own. */ backend->ssl_sockfd = sockfd; err = SSLSetConnection(backend->ssl_ctx, connssl); - if(err != noErr) { - failf(data, "SSL: SSLSetConnection() failed: %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - - connssl->connecting_state = ssl_connect_2; - return CURLE_OK; -} - -static long pem_to_der(const char *in, unsigned char **out, size_t *outlen) -{ - char *sep_start, *sep_end, *cert_start, *cert_end; - size_t i, j, err; - size_t len; - unsigned char *b64; - - /* Jump through the separators at the beginning of the certificate. */ - sep_start = strstr(in, "-----"); - if(sep_start == NULL) - return 0; - cert_start = strstr(sep_start + 1, "-----"); - if(cert_start == NULL) - return -1; - - cert_start += 5; - - /* Find separator after the end of the certificate. */ - cert_end = strstr(cert_start, "-----"); - if(cert_end == NULL) - return -1; - - sep_end = strstr(cert_end + 1, "-----"); - if(sep_end == NULL) - return -1; - sep_end += 5; - - len = cert_end - cert_start; - b64 = malloc(len + 1); - if(!b64) - return -1; - - /* Create base64 string without linefeeds. */ - for(i = 0, j = 0; i < len; i++) { - if(cert_start[i] != '\r' && cert_start[i] != '\n') - b64[j++] = cert_start[i]; - } - b64[j] = '\0'; - - err = Curl_base64_decode((const char *)b64, out, outlen); - free(b64); - if(err) { - free(*out); - return -1; - } - - return sep_end - in; -} - -static int read_cert(const char *file, unsigned char **out, size_t *outlen) -{ - int fd; - ssize_t n, len = 0, cap = 512; - unsigned char buf[512], *data; - - fd = open(file, 0); - if(fd < 0) - return -1; - - data = malloc(cap); - if(!data) { - close(fd); - return -1; - } - - for(;;) { - n = read(fd, buf, sizeof(buf)); - if(n < 0) { - close(fd); - free(data); - return -1; - } - else if(n == 0) { - close(fd); - break; - } - - if(len + n >= cap) { - cap *= 2; - data = Curl_saferealloc(data, cap); - if(!data) { - close(fd); - return -1; - } - } - - memcpy(data + len, buf, n); - len += n; - } - data[len] = '\0'; - - *out = data; - *outlen = len; - - return 0; -} - -static int append_cert_to_array(struct Curl_easy *data, - unsigned char *buf, size_t buflen, - CFMutableArrayRef array) -{ - CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); - char *certp; - CURLcode result; - if(!certdata) { - failf(data, "SSL: failed to allocate array for CA certificate"); - return CURLE_OUT_OF_MEMORY; - } - - SecCertificateRef cacert = - SecCertificateCreateWithData(kCFAllocatorDefault, certdata); - CFRelease(certdata); - if(!cacert) { - failf(data, "SSL: failed to create SecCertificate from CA certificate"); - return CURLE_SSL_CACERT_BADFILE; - } - - /* Check if cacert is valid. */ - result = CopyCertSubject(data, cacert, &certp); - switch(result) { - case CURLE_OK: - break; - case CURLE_PEER_FAILED_VERIFICATION: - return CURLE_SSL_CACERT_BADFILE; - case CURLE_OUT_OF_MEMORY: - default: - return result; - } - free(certp); - - CFArrayAppendValue(array, cacert); - CFRelease(cacert); - - return CURLE_OK; -} - -static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, - SSLContextRef ctx) -{ - int n = 0, rc; - long res; - unsigned char *certbuf, *der; - size_t buflen, derlen, offset = 0; - - if(read_cert(cafile, &certbuf, &buflen) < 0) { - failf(data, "SSL: failed to read or invalid CA certificate"); - return CURLE_SSL_CACERT_BADFILE; - } - - /* - * Certbuf now contains the contents of the certificate file, which can be - * - a single DER certificate, - * - a single PEM certificate or - * - a bunch of PEM certificates (certificate bundle). - * - * Go through certbuf, and convert any PEM certificate in it into DER - * format. - */ - CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeArrayCallBacks); - if(array == NULL) { - free(certbuf); - failf(data, "SSL: out of memory creating CA certificate array"); - return CURLE_OUT_OF_MEMORY; - } - - while(offset < buflen) { - n++; - - /* - * Check if the certificate is in PEM format, and convert it to DER. If - * this fails, we assume the certificate is in DER format. - */ - res = pem_to_der((const char *)certbuf + offset, &der, &derlen); - if(res < 0) { - free(certbuf); - CFRelease(array); + if(err != noErr) { + failf(data, "SSL: SSLSetConnection() failed: %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + +static long pem_to_der(const char *in, unsigned char **out, size_t *outlen) +{ + char *sep_start, *sep_end, *cert_start, *cert_end; + size_t i, j, err; + size_t len; + unsigned char *b64; + + /* Jump through the separators at the beginning of the certificate. */ + sep_start = strstr(in, "-----"); + if(sep_start == NULL) + return 0; + cert_start = strstr(sep_start + 1, "-----"); + if(cert_start == NULL) + return -1; + + cert_start += 5; + + /* Find separator after the end of the certificate. */ + cert_end = strstr(cert_start, "-----"); + if(cert_end == NULL) + return -1; + + sep_end = strstr(cert_end + 1, "-----"); + if(sep_end == NULL) + return -1; + sep_end += 5; + + len = cert_end - cert_start; + b64 = malloc(len + 1); + if(!b64) + return -1; + + /* Create base64 string without linefeeds. */ + for(i = 0, j = 0; i < len; i++) { + if(cert_start[i] != '\r' && cert_start[i] != '\n') + b64[j++] = cert_start[i]; + } + b64[j] = '\0'; + + err = Curl_base64_decode((const char *)b64, out, outlen); + free(b64); + if(err) { + free(*out); + return -1; + } + + return sep_end - in; +} + +static int read_cert(const char *file, unsigned char **out, size_t *outlen) +{ + int fd; + ssize_t n, len = 0, cap = 512; + unsigned char buf[512], *data; + + fd = open(file, 0); + if(fd < 0) + return -1; + + data = malloc(cap); + if(!data) { + close(fd); + return -1; + } + + for(;;) { + n = read(fd, buf, sizeof(buf)); + if(n < 0) { + close(fd); + free(data); + return -1; + } + else if(n == 0) { + close(fd); + break; + } + + if(len + n >= cap) { + cap *= 2; + data = Curl_saferealloc(data, cap); + if(!data) { + close(fd); + return -1; + } + } + + memcpy(data + len, buf, n); + len += n; + } + data[len] = '\0'; + + *out = data; + *outlen = len; + + return 0; +} + +static int append_cert_to_array(struct Curl_easy *data, + unsigned char *buf, size_t buflen, + CFMutableArrayRef array) +{ + CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); + char *certp; + CURLcode result; + if(!certdata) { + failf(data, "SSL: failed to allocate array for CA certificate"); + return CURLE_OUT_OF_MEMORY; + } + + SecCertificateRef cacert = + SecCertificateCreateWithData(kCFAllocatorDefault, certdata); + CFRelease(certdata); + if(!cacert) { + failf(data, "SSL: failed to create SecCertificate from CA certificate"); + return CURLE_SSL_CACERT_BADFILE; + } + + /* Check if cacert is valid. */ + result = CopyCertSubject(data, cacert, &certp); + switch(result) { + case CURLE_OK: + break; + case CURLE_PEER_FAILED_VERIFICATION: + return CURLE_SSL_CACERT_BADFILE; + case CURLE_OUT_OF_MEMORY: + default: + return result; + } + free(certp); + + CFArrayAppendValue(array, cacert); + CFRelease(cacert); + + return CURLE_OK; +} + +static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, + SSLContextRef ctx) +{ + int n = 0, rc; + long res; + unsigned char *certbuf, *der; + size_t buflen, derlen, offset = 0; + + if(read_cert(cafile, &certbuf, &buflen) < 0) { + failf(data, "SSL: failed to read or invalid CA certificate"); + return CURLE_SSL_CACERT_BADFILE; + } + + /* + * Certbuf now contains the contents of the certificate file, which can be + * - a single DER certificate, + * - a single PEM certificate or + * - a bunch of PEM certificates (certificate bundle). + * + * Go through certbuf, and convert any PEM certificate in it into DER + * format. + */ + CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeArrayCallBacks); + if(array == NULL) { + free(certbuf); + failf(data, "SSL: out of memory creating CA certificate array"); + return CURLE_OUT_OF_MEMORY; + } + + while(offset < buflen) { + n++; + + /* + * Check if the certificate is in PEM format, and convert it to DER. If + * this fails, we assume the certificate is in DER format. + */ + res = pem_to_der((const char *)certbuf + offset, &der, &derlen); + if(res < 0) { + free(certbuf); + CFRelease(array); failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle", - n, offset); - return CURLE_SSL_CACERT_BADFILE; - } - offset += res; - - if(res == 0 && offset == 0) { - /* This is not a PEM file, probably a certificate in DER format. */ - rc = append_cert_to_array(data, certbuf, buflen, array); - free(certbuf); - if(rc != CURLE_OK) { - CFRelease(array); - return rc; - } - break; - } - else if(res == 0) { - /* No more certificates in the bundle. */ - free(certbuf); - break; - } - - rc = append_cert_to_array(data, der, derlen, array); - free(der); - if(rc != CURLE_OK) { - free(certbuf); - CFRelease(array); - return rc; - } - } - - SecTrustRef trust; - OSStatus ret = SSLCopyPeerTrust(ctx, &trust); - if(trust == NULL) { - failf(data, "SSL: error getting certificate chain"); - CFRelease(array); - return CURLE_PEER_FAILED_VERIFICATION; - } - else if(ret != noErr) { - CFRelease(array); - failf(data, "SSLCopyPeerTrust() returned error %d", ret); - return CURLE_PEER_FAILED_VERIFICATION; - } - - ret = SecTrustSetAnchorCertificates(trust, array); - if(ret != noErr) { - CFRelease(array); - CFRelease(trust); - failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret); - return CURLE_PEER_FAILED_VERIFICATION; - } - ret = SecTrustSetAnchorCertificatesOnly(trust, true); - if(ret != noErr) { - CFRelease(array); - CFRelease(trust); - failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret); - return CURLE_PEER_FAILED_VERIFICATION; - } - - SecTrustResultType trust_eval = 0; - ret = SecTrustEvaluate(trust, &trust_eval); - CFRelease(array); - CFRelease(trust); - if(ret != noErr) { - failf(data, "SecTrustEvaluate() returned error %d", ret); - return CURLE_PEER_FAILED_VERIFICATION; - } - - switch(trust_eval) { - case kSecTrustResultUnspecified: - case kSecTrustResultProceed: - return CURLE_OK; - - case kSecTrustResultRecoverableTrustFailure: - case kSecTrustResultDeny: - default: - failf(data, "SSL: certificate verification failed (result: %d)", - trust_eval); - return CURLE_PEER_FAILED_VERIFICATION; - } -} - -#ifdef SECTRANSP_PINNEDPUBKEY -static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, - SSLContextRef ctx, - const char *pinnedpubkey) -{ /* Scratch */ - size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24; - unsigned char *pubkey = NULL, *realpubkey = NULL; - const unsigned char *spkiHeader = NULL; - CFDataRef publicKeyBits = NULL; - - /* Result is returned to caller */ - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - /* if a path wasn't specified, don't pin */ - if(!pinnedpubkey) - return CURLE_OK; - - - if(!ctx) - return result; - - do { - SecTrustRef trust; - OSStatus ret = SSLCopyPeerTrust(ctx, &trust); - if(ret != noErr || trust == NULL) - break; - - SecKeyRef keyRef = SecTrustCopyPublicKey(trust); - CFRelease(trust); - if(keyRef == NULL) - break; - -#ifdef SECTRANSP_PINNEDPUBKEY_V1 - - publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL); - CFRelease(keyRef); - if(publicKeyBits == NULL) - break; - -#elif SECTRANSP_PINNEDPUBKEY_V2 - - OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, - &publicKeyBits); - CFRelease(keyRef); - if(success != errSecSuccess || publicKeyBits == NULL) - break; - -#endif /* SECTRANSP_PINNEDPUBKEY_V2 */ - - pubkeylen = CFDataGetLength(publicKeyBits); - pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits); - - switch(pubkeylen) { - case 526: - /* 4096 bit RSA pubkeylen == 526 */ - spkiHeader = rsa4096SpkiHeader; - break; - case 270: - /* 2048 bit RSA pubkeylen == 270 */ - spkiHeader = rsa2048SpkiHeader; - break; -#ifdef SECTRANSP_PINNEDPUBKEY_V1 - case 65: - /* ecDSA secp256r1 pubkeylen == 65 */ - spkiHeader = ecDsaSecp256r1SpkiHeader; - spkiHeaderLength = 26; - break; - case 97: - /* ecDSA secp384r1 pubkeylen == 97 */ - spkiHeader = ecDsaSecp384r1SpkiHeader; - spkiHeaderLength = 23; - break; - default: - infof(data, "SSL: unhandled public key length: %d\n", pubkeylen); -#elif SECTRANSP_PINNEDPUBKEY_V2 - default: - /* ecDSA secp256r1 pubkeylen == 91 header already included? - * ecDSA secp384r1 header already included too - * we assume rest of algorithms do same, so do nothing - */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey, - pubkeylen); -#endif /* SECTRANSP_PINNEDPUBKEY_V2 */ - continue; /* break from loop */ - } - - realpubkeylen = pubkeylen + spkiHeaderLength; - realpubkey = malloc(realpubkeylen); - if(!realpubkey) - break; - - memcpy(realpubkey, spkiHeader, spkiHeaderLength); - memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen); - - result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey, - realpubkeylen); - - } while(0); - - Curl_safefree(realpubkey); - if(publicKeyBits != NULL) - CFRelease(publicKeyBits); - - return result; -} -#endif /* SECTRANSP_PINNEDPUBKEY */ - -static CURLcode -sectransp_connect_step2(struct connectdata *conn, int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + n, offset); + return CURLE_SSL_CACERT_BADFILE; + } + offset += res; + + if(res == 0 && offset == 0) { + /* This is not a PEM file, probably a certificate in DER format. */ + rc = append_cert_to_array(data, certbuf, buflen, array); + free(certbuf); + if(rc != CURLE_OK) { + CFRelease(array); + return rc; + } + break; + } + else if(res == 0) { + /* No more certificates in the bundle. */ + free(certbuf); + break; + } + + rc = append_cert_to_array(data, der, derlen, array); + free(der); + if(rc != CURLE_OK) { + free(certbuf); + CFRelease(array); + return rc; + } + } + + SecTrustRef trust; + OSStatus ret = SSLCopyPeerTrust(ctx, &trust); + if(trust == NULL) { + failf(data, "SSL: error getting certificate chain"); + CFRelease(array); + return CURLE_PEER_FAILED_VERIFICATION; + } + else if(ret != noErr) { + CFRelease(array); + failf(data, "SSLCopyPeerTrust() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; + } + + ret = SecTrustSetAnchorCertificates(trust, array); + if(ret != noErr) { + CFRelease(array); + CFRelease(trust); + failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; + } + ret = SecTrustSetAnchorCertificatesOnly(trust, true); + if(ret != noErr) { + CFRelease(array); + CFRelease(trust); + failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; + } + + SecTrustResultType trust_eval = 0; + ret = SecTrustEvaluate(trust, &trust_eval); + CFRelease(array); + CFRelease(trust); + if(ret != noErr) { + failf(data, "SecTrustEvaluate() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; + } + + switch(trust_eval) { + case kSecTrustResultUnspecified: + case kSecTrustResultProceed: + return CURLE_OK; + + case kSecTrustResultRecoverableTrustFailure: + case kSecTrustResultDeny: + default: + failf(data, "SSL: certificate verification failed (result: %d)", + trust_eval); + return CURLE_PEER_FAILED_VERIFICATION; + } +} + +#ifdef SECTRANSP_PINNEDPUBKEY +static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, + SSLContextRef ctx, + const char *pinnedpubkey) +{ /* Scratch */ + size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24; + unsigned char *pubkey = NULL, *realpubkey = NULL; + const unsigned char *spkiHeader = NULL; + CFDataRef publicKeyBits = NULL; + + /* Result is returned to caller */ + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + /* if a path wasn't specified, don't pin */ + if(!pinnedpubkey) + return CURLE_OK; + + + if(!ctx) + return result; + + do { + SecTrustRef trust; + OSStatus ret = SSLCopyPeerTrust(ctx, &trust); + if(ret != noErr || trust == NULL) + break; + + SecKeyRef keyRef = SecTrustCopyPublicKey(trust); + CFRelease(trust); + if(keyRef == NULL) + break; + +#ifdef SECTRANSP_PINNEDPUBKEY_V1 + + publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL); + CFRelease(keyRef); + if(publicKeyBits == NULL) + break; + +#elif SECTRANSP_PINNEDPUBKEY_V2 + + OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, + &publicKeyBits); + CFRelease(keyRef); + if(success != errSecSuccess || publicKeyBits == NULL) + break; + +#endif /* SECTRANSP_PINNEDPUBKEY_V2 */ + + pubkeylen = CFDataGetLength(publicKeyBits); + pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits); + + switch(pubkeylen) { + case 526: + /* 4096 bit RSA pubkeylen == 526 */ + spkiHeader = rsa4096SpkiHeader; + break; + case 270: + /* 2048 bit RSA pubkeylen == 270 */ + spkiHeader = rsa2048SpkiHeader; + break; +#ifdef SECTRANSP_PINNEDPUBKEY_V1 + case 65: + /* ecDSA secp256r1 pubkeylen == 65 */ + spkiHeader = ecDsaSecp256r1SpkiHeader; + spkiHeaderLength = 26; + break; + case 97: + /* ecDSA secp384r1 pubkeylen == 97 */ + spkiHeader = ecDsaSecp384r1SpkiHeader; + spkiHeaderLength = 23; + break; + default: + infof(data, "SSL: unhandled public key length: %d\n", pubkeylen); +#elif SECTRANSP_PINNEDPUBKEY_V2 + default: + /* ecDSA secp256r1 pubkeylen == 91 header already included? + * ecDSA secp384r1 header already included too + * we assume rest of algorithms do same, so do nothing + */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey, + pubkeylen); +#endif /* SECTRANSP_PINNEDPUBKEY_V2 */ + continue; /* break from loop */ + } + + realpubkeylen = pubkeylen + spkiHeaderLength; + realpubkey = malloc(realpubkeylen); + if(!realpubkey) + break; + + memcpy(realpubkey, spkiHeader, spkiHeaderLength); + memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen); + + result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey, + realpubkeylen); + + } while(0); + + Curl_safefree(realpubkey); + if(publicKeyBits != NULL) + CFRelease(publicKeyBits); + + return result; +} +#endif /* SECTRANSP_PINNEDPUBKEY */ + +static CURLcode +sectransp_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - OSStatus err; - SSLCipherSuite cipher; - SSLProtocol protocol = 0; + OSStatus err; + SSLCipherSuite cipher; + SSLProtocol protocol = 0; #ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; #else const char * const hostname = conn->host.name; #endif - - DEBUGASSERT(ssl_connect_2 == connssl->connecting_state - || ssl_connect_2_reading == connssl->connecting_state - || ssl_connect_2_writing == connssl->connecting_state); - - /* Here goes nothing: */ + + DEBUGASSERT(ssl_connect_2 == connssl->connecting_state + || ssl_connect_2_reading == connssl->connecting_state + || ssl_connect_2_writing == connssl->connecting_state); + + /* Here goes nothing: */ err = SSLHandshake(backend->ssl_ctx); - - if(err != noErr) { - switch(err) { - case errSSLWouldBlock: /* they're not done with us yet */ + + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: /* they're not done with us yet */ connssl->connecting_state = backend->ssl_direction ? - ssl_connect_2_writing : ssl_connect_2_reading; - return CURLE_OK; - - /* The below is errSSLServerAuthCompleted; it's not defined in - Leopard's headers */ - case -9841: - if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { - CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, + ssl_connect_2_writing : ssl_connect_2_reading; + return CURLE_OK; + + /* The below is errSSLServerAuthCompleted; it's not defined in + Leopard's headers */ + case -9841: + if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { + CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, backend->ssl_ctx); - if(result) - return result; - } - /* the documentation says we need to call SSLHandshake() again */ - return sectransp_connect_step2(conn, sockindex); - - /* Problem with encrypt / decrypt */ - case errSSLPeerDecodeError: - failf(data, "Decode failed"); - break; - case errSSLDecryptionFail: - case errSSLPeerDecryptionFail: - failf(data, "Decryption failed"); - break; - case errSSLPeerDecryptError: - failf(data, "A decryption error occurred"); - break; - case errSSLBadCipherSuite: - failf(data, "A bad SSL cipher suite was encountered"); - break; - case errSSLCrypto: - failf(data, "An underlying cryptographic error was encountered"); - break; -#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9 - case errSSLWeakPeerEphemeralDHKey: - failf(data, "Indicates a weak ephemeral Diffie-Hellman key"); - break; -#endif - - /* Problem with the message record validation */ - case errSSLBadRecordMac: - case errSSLPeerBadRecordMac: - failf(data, "A record with a bad message authentication code (MAC) " - "was encountered"); - break; - case errSSLRecordOverflow: - case errSSLPeerRecordOverflow: - failf(data, "A record overflow occurred"); - break; - - /* Problem with zlib decompression */ - case errSSLPeerDecompressFail: - failf(data, "Decompression failed"); - break; - - /* Problem with access */ - case errSSLPeerAccessDenied: - failf(data, "Access was denied"); - break; - case errSSLPeerInsufficientSecurity: - failf(data, "There is insufficient security for this operation"); - break; - - /* These are all certificate problems with the server: */ - case errSSLXCertChainInvalid: - failf(data, "SSL certificate problem: Invalid certificate chain"); - return CURLE_PEER_FAILED_VERIFICATION; - case errSSLUnknownRootCert: - failf(data, "SSL certificate problem: Untrusted root certificate"); - return CURLE_PEER_FAILED_VERIFICATION; - case errSSLNoRootCert: - failf(data, "SSL certificate problem: No root certificate"); - return CURLE_PEER_FAILED_VERIFICATION; - case errSSLCertNotYetValid: - failf(data, "SSL certificate problem: The certificate chain had a " - "certificate that is not yet valid"); - return CURLE_PEER_FAILED_VERIFICATION; - case errSSLCertExpired: - case errSSLPeerCertExpired: - failf(data, "SSL certificate problem: Certificate chain had an " - "expired certificate"); - return CURLE_PEER_FAILED_VERIFICATION; - case errSSLBadCert: - case errSSLPeerBadCert: - failf(data, "SSL certificate problem: Couldn't understand the server " - "certificate format"); - return CURLE_PEER_FAILED_VERIFICATION; - case errSSLPeerUnsupportedCert: - failf(data, "SSL certificate problem: An unsupported certificate " - "format was encountered"); - return CURLE_PEER_FAILED_VERIFICATION; - case errSSLPeerCertRevoked: - failf(data, "SSL certificate problem: The certificate was revoked"); - return CURLE_PEER_FAILED_VERIFICATION; - case errSSLPeerCertUnknown: - failf(data, "SSL certificate problem: The certificate is unknown"); - return CURLE_PEER_FAILED_VERIFICATION; - - /* These are all certificate problems with the client: */ - case errSecAuthFailed: - failf(data, "SSL authentication failed"); - break; - case errSSLPeerHandshakeFail: - failf(data, "SSL peer handshake failed, the server most likely " - "requires a client certificate to connect"); - break; - case errSSLPeerUnknownCA: - failf(data, "SSL server rejected the client certificate due to " - "the certificate being signed by an unknown certificate " - "authority"); - break; - - /* This error is raised if the server's cert didn't match the server's - host name: */ - case errSSLHostNameMismatch: - failf(data, "SSL certificate peer verification failed, the " - "certificate did not match \"%s\"\n", conn->host.dispname); - return CURLE_PEER_FAILED_VERIFICATION; - - /* Problem with SSL / TLS negotiation */ - case errSSLNegotiation: - failf(data, "Could not negotiate an SSL cipher suite with the server"); - break; - case errSSLBadConfiguration: - failf(data, "A configuration error occurred"); - break; - case errSSLProtocol: - failf(data, "SSL protocol error"); - break; - case errSSLPeerProtocolVersion: - failf(data, "A bad protocol version was encountered"); - break; - case errSSLPeerNoRenegotiation: - failf(data, "No renegotiation is allowed"); - break; - - /* Generic handshake errors: */ - case errSSLConnectionRefused: - failf(data, "Server dropped the connection during the SSL handshake"); - break; - case errSSLClosedAbort: - failf(data, "Server aborted the SSL handshake"); - break; - case errSSLClosedGraceful: - failf(data, "The connection closed gracefully"); - break; - case errSSLClosedNoNotify: - failf(data, "The server closed the session with no notification"); - break; - /* Sometimes paramErr happens with buggy ciphers: */ - case paramErr: - case errSSLInternal: - case errSSLPeerInternalError: - failf(data, "Internal SSL engine error encountered during the " - "SSL handshake"); - break; - case errSSLFatalAlert: - failf(data, "Fatal SSL engine error encountered during the SSL " - "handshake"); - break; - /* Unclassified error */ - case errSSLBufferOverflow: - failf(data, "An insufficient buffer was provided"); - break; - case errSSLIllegalParam: - failf(data, "An illegal parameter was encountered"); - break; - case errSSLModuleAttach: - failf(data, "Module attach failure"); - break; - case errSSLSessionNotFound: - failf(data, "An attempt to restore an unknown session failed"); - break; - case errSSLPeerExportRestriction: - failf(data, "An export restriction occurred"); - break; - case errSSLPeerUserCancelled: - failf(data, "The user canceled the operation"); - break; - case errSSLPeerUnexpectedMsg: - failf(data, "Peer rejected unexpected message"); - break; -#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9 - /* Treaing non-fatal error as fatal like before */ - case errSSLClientHelloReceived: - failf(data, "A non-fatal result for providing a server name " - "indication"); - break; -#endif - - /* Error codes defined in the enum but should never be returned. - We list them here just in case. */ -#if CURL_BUILD_MAC_10_6 - /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */ - case errSSLClientCertRequested: - failf(data, "The server has requested a client certificate"); - break; -#endif -#if CURL_BUILD_MAC_10_9 - /* Alias for errSSLLast, end of error range */ - case errSSLUnexpectedRecord: - failf(data, "Unexpected (skipped) record in DTLS"); - break; -#endif - default: - /* May also return codes listed in Security Framework Result Codes */ - failf(data, "Unknown SSL protocol error in connection to %s:%d", - hostname, err); - break; - } - return CURLE_SSL_CONNECT_ERROR; - } - else { - /* we have been connected fine, we're not waiting for anything else. */ - connssl->connecting_state = ssl_connect_3; - -#ifdef SECTRANSP_PINNEDPUBKEY - if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { + if(result) + return result; + } + /* the documentation says we need to call SSLHandshake() again */ + return sectransp_connect_step2(conn, sockindex); + + /* Problem with encrypt / decrypt */ + case errSSLPeerDecodeError: + failf(data, "Decode failed"); + break; + case errSSLDecryptionFail: + case errSSLPeerDecryptionFail: + failf(data, "Decryption failed"); + break; + case errSSLPeerDecryptError: + failf(data, "A decryption error occurred"); + break; + case errSSLBadCipherSuite: + failf(data, "A bad SSL cipher suite was encountered"); + break; + case errSSLCrypto: + failf(data, "An underlying cryptographic error was encountered"); + break; +#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9 + case errSSLWeakPeerEphemeralDHKey: + failf(data, "Indicates a weak ephemeral Diffie-Hellman key"); + break; +#endif + + /* Problem with the message record validation */ + case errSSLBadRecordMac: + case errSSLPeerBadRecordMac: + failf(data, "A record with a bad message authentication code (MAC) " + "was encountered"); + break; + case errSSLRecordOverflow: + case errSSLPeerRecordOverflow: + failf(data, "A record overflow occurred"); + break; + + /* Problem with zlib decompression */ + case errSSLPeerDecompressFail: + failf(data, "Decompression failed"); + break; + + /* Problem with access */ + case errSSLPeerAccessDenied: + failf(data, "Access was denied"); + break; + case errSSLPeerInsufficientSecurity: + failf(data, "There is insufficient security for this operation"); + break; + + /* These are all certificate problems with the server: */ + case errSSLXCertChainInvalid: + failf(data, "SSL certificate problem: Invalid certificate chain"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLUnknownRootCert: + failf(data, "SSL certificate problem: Untrusted root certificate"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLNoRootCert: + failf(data, "SSL certificate problem: No root certificate"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLCertNotYetValid: + failf(data, "SSL certificate problem: The certificate chain had a " + "certificate that is not yet valid"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLCertExpired: + case errSSLPeerCertExpired: + failf(data, "SSL certificate problem: Certificate chain had an " + "expired certificate"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLBadCert: + case errSSLPeerBadCert: + failf(data, "SSL certificate problem: Couldn't understand the server " + "certificate format"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLPeerUnsupportedCert: + failf(data, "SSL certificate problem: An unsupported certificate " + "format was encountered"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLPeerCertRevoked: + failf(data, "SSL certificate problem: The certificate was revoked"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLPeerCertUnknown: + failf(data, "SSL certificate problem: The certificate is unknown"); + return CURLE_PEER_FAILED_VERIFICATION; + + /* These are all certificate problems with the client: */ + case errSecAuthFailed: + failf(data, "SSL authentication failed"); + break; + case errSSLPeerHandshakeFail: + failf(data, "SSL peer handshake failed, the server most likely " + "requires a client certificate to connect"); + break; + case errSSLPeerUnknownCA: + failf(data, "SSL server rejected the client certificate due to " + "the certificate being signed by an unknown certificate " + "authority"); + break; + + /* This error is raised if the server's cert didn't match the server's + host name: */ + case errSSLHostNameMismatch: + failf(data, "SSL certificate peer verification failed, the " + "certificate did not match \"%s\"\n", conn->host.dispname); + return CURLE_PEER_FAILED_VERIFICATION; + + /* Problem with SSL / TLS negotiation */ + case errSSLNegotiation: + failf(data, "Could not negotiate an SSL cipher suite with the server"); + break; + case errSSLBadConfiguration: + failf(data, "A configuration error occurred"); + break; + case errSSLProtocol: + failf(data, "SSL protocol error"); + break; + case errSSLPeerProtocolVersion: + failf(data, "A bad protocol version was encountered"); + break; + case errSSLPeerNoRenegotiation: + failf(data, "No renegotiation is allowed"); + break; + + /* Generic handshake errors: */ + case errSSLConnectionRefused: + failf(data, "Server dropped the connection during the SSL handshake"); + break; + case errSSLClosedAbort: + failf(data, "Server aborted the SSL handshake"); + break; + case errSSLClosedGraceful: + failf(data, "The connection closed gracefully"); + break; + case errSSLClosedNoNotify: + failf(data, "The server closed the session with no notification"); + break; + /* Sometimes paramErr happens with buggy ciphers: */ + case paramErr: + case errSSLInternal: + case errSSLPeerInternalError: + failf(data, "Internal SSL engine error encountered during the " + "SSL handshake"); + break; + case errSSLFatalAlert: + failf(data, "Fatal SSL engine error encountered during the SSL " + "handshake"); + break; + /* Unclassified error */ + case errSSLBufferOverflow: + failf(data, "An insufficient buffer was provided"); + break; + case errSSLIllegalParam: + failf(data, "An illegal parameter was encountered"); + break; + case errSSLModuleAttach: + failf(data, "Module attach failure"); + break; + case errSSLSessionNotFound: + failf(data, "An attempt to restore an unknown session failed"); + break; + case errSSLPeerExportRestriction: + failf(data, "An export restriction occurred"); + break; + case errSSLPeerUserCancelled: + failf(data, "The user canceled the operation"); + break; + case errSSLPeerUnexpectedMsg: + failf(data, "Peer rejected unexpected message"); + break; +#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9 + /* Treaing non-fatal error as fatal like before */ + case errSSLClientHelloReceived: + failf(data, "A non-fatal result for providing a server name " + "indication"); + break; +#endif + + /* Error codes defined in the enum but should never be returned. + We list them here just in case. */ +#if CURL_BUILD_MAC_10_6 + /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */ + case errSSLClientCertRequested: + failf(data, "The server has requested a client certificate"); + break; +#endif +#if CURL_BUILD_MAC_10_9 + /* Alias for errSSLLast, end of error range */ + case errSSLUnexpectedRecord: + failf(data, "Unexpected (skipped) record in DTLS"); + break; +#endif + default: + /* May also return codes listed in Security Framework Result Codes */ + failf(data, "Unknown SSL protocol error in connection to %s:%d", + hostname, err); + break; + } + return CURLE_SSL_CONNECT_ERROR; + } + else { + /* we have been connected fine, we're not waiting for anything else. */ + connssl->connecting_state = ssl_connect_3; + +#ifdef SECTRANSP_PINNEDPUBKEY + if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { CURLcode result = pkp_pin_peer_pubkey(data, backend->ssl_ctx, - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); - if(result) { - failf(data, "SSL: public key does not match pinned public key!"); - return result; - } - } -#endif /* SECTRANSP_PINNEDPUBKEY */ - - /* Informational message */ + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } + } +#endif /* SECTRANSP_PINNEDPUBKEY */ + + /* Informational message */ (void)SSLGetNegotiatedCipher(backend->ssl_ctx, &cipher); (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol); - switch(protocol) { - case kSSLProtocol2: - infof(data, "SSL 2.0 connection using %s\n", - SSLCipherNameForNumber(cipher)); - break; - case kSSLProtocol3: - infof(data, "SSL 3.0 connection using %s\n", - SSLCipherNameForNumber(cipher)); - break; - case kTLSProtocol1: - infof(data, "TLS 1.0 connection using %s\n", - TLSCipherNameForNumber(cipher)); - break; -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - case kTLSProtocol11: - infof(data, "TLS 1.1 connection using %s\n", - TLSCipherNameForNumber(cipher)); - break; - case kTLSProtocol12: - infof(data, "TLS 1.2 connection using %s\n", - TLSCipherNameForNumber(cipher)); - break; -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 - case kTLSProtocol13: - infof(data, "TLS 1.3 connection using %s\n", - TLSCipherNameForNumber(cipher)); - break; -#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ - default: - infof(data, "Unknown protocol connection\n"); - break; - } - -#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 - if(conn->bits.tls_enable_alpn) { - if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { - CFArrayRef alpnArr = NULL; - CFStringRef chosenProtocol = NULL; + switch(protocol) { + case kSSLProtocol2: + infof(data, "SSL 2.0 connection using %s\n", + SSLCipherNameForNumber(cipher)); + break; + case kSSLProtocol3: + infof(data, "SSL 3.0 connection using %s\n", + SSLCipherNameForNumber(cipher)); + break; + case kTLSProtocol1: + infof(data, "TLS 1.0 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + case kTLSProtocol11: + infof(data, "TLS 1.1 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; + case kTLSProtocol12: + infof(data, "TLS 1.2 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ +#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 + case kTLSProtocol13: + infof(data, "TLS 1.3 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + default: + infof(data, "Unknown protocol connection\n"); + break; + } + +#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(conn->bits.tls_enable_alpn) { + if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { + CFArrayRef alpnArr = NULL; + CFStringRef chosenProtocol = NULL; err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr); - - if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1) - chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0); - -#ifdef USE_NGHTTP2 - if(chosenProtocol && - !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID), - 0)) { - conn->negnpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(chosenProtocol && - !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } - else - infof(data, "ALPN, server did not agree to a protocol\n"); - - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); - - /* chosenProtocol is a reference to the string within alpnArr - and doesn't need to be freed separately */ - if(alpnArr) - CFRelease(alpnArr); - } - } -#endif - - return CURLE_OK; - } -} - -#ifndef CURL_DISABLE_VERBOSE_STRINGS -/* This should be called during step3 of the connection at the earliest */ -static void -show_verbose_server_cert(struct connectdata *conn, - int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1) + chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0); + +#ifdef USE_NGHTTP2 + if(chosenProtocol && + !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID), + 0)) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(chosenProtocol && + !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + + /* chosenProtocol is a reference to the string within alpnArr + and doesn't need to be freed separately */ + if(alpnArr) + CFRelease(alpnArr); + } + } +#endif + + return CURLE_OK; + } +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +/* This should be called during step3 of the connection at the earliest */ +static void +show_verbose_server_cert(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - CFArrayRef server_certs = NULL; - SecCertificateRef server_cert; - OSStatus err; - CFIndex i, count; - SecTrustRef trust = NULL; - + CFArrayRef server_certs = NULL; + SecCertificateRef server_cert; + OSStatus err; + CFIndex i, count; + SecTrustRef trust = NULL; + if(!backend->ssl_ctx) - return; - -#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS -#if CURL_BUILD_IOS -#pragma unused(server_certs) + return; + +#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS +#if CURL_BUILD_IOS +#pragma unused(server_certs) err = SSLCopyPeerTrust(backend->ssl_ctx, &trust); - /* For some reason, SSLCopyPeerTrust() can return noErr and yet return - a null trust, so be on guard for that: */ - if(err == noErr && trust) { - count = SecTrustGetCertificateCount(trust); - for(i = 0L ; i < count ; i++) { - CURLcode result; - char *certp; - server_cert = SecTrustGetCertificateAtIndex(trust, i); - result = CopyCertSubject(data, server_cert, &certp); - if(!result) { - infof(data, "Server certificate: %s\n", certp); - free(certp); - } - } - CFRelease(trust); - } -#else - /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion. - The function SecTrustGetCertificateAtIndex() is officially present - in Lion, but it is unfortunately also present in Snow Leopard as - private API and doesn't work as expected. So we have to look for - a different symbol to make sure this code is only executed under - Lion or later. */ - if(SecTrustEvaluateAsync != NULL) { -#pragma unused(server_certs) + /* For some reason, SSLCopyPeerTrust() can return noErr and yet return + a null trust, so be on guard for that: */ + if(err == noErr && trust) { + count = SecTrustGetCertificateCount(trust); + for(i = 0L ; i < count ; i++) { + CURLcode result; + char *certp; + server_cert = SecTrustGetCertificateAtIndex(trust, i); + result = CopyCertSubject(data, server_cert, &certp); + if(!result) { + infof(data, "Server certificate: %s\n", certp); + free(certp); + } + } + CFRelease(trust); + } +#else + /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion. + The function SecTrustGetCertificateAtIndex() is officially present + in Lion, but it is unfortunately also present in Snow Leopard as + private API and doesn't work as expected. So we have to look for + a different symbol to make sure this code is only executed under + Lion or later. */ + if(SecTrustEvaluateAsync != NULL) { +#pragma unused(server_certs) err = SSLCopyPeerTrust(backend->ssl_ctx, &trust); - /* For some reason, SSLCopyPeerTrust() can return noErr and yet return - a null trust, so be on guard for that: */ - if(err == noErr && trust) { - count = SecTrustGetCertificateCount(trust); - for(i = 0L ; i < count ; i++) { - char *certp; - CURLcode result; - server_cert = SecTrustGetCertificateAtIndex(trust, i); - result = CopyCertSubject(data, server_cert, &certp); - if(!result) { - infof(data, "Server certificate: %s\n", certp); - free(certp); - } - } - CFRelease(trust); - } - } - else { -#if CURL_SUPPORT_MAC_10_8 + /* For some reason, SSLCopyPeerTrust() can return noErr and yet return + a null trust, so be on guard for that: */ + if(err == noErr && trust) { + count = SecTrustGetCertificateCount(trust); + for(i = 0L ; i < count ; i++) { + char *certp; + CURLcode result; + server_cert = SecTrustGetCertificateAtIndex(trust, i); + result = CopyCertSubject(data, server_cert, &certp); + if(!result) { + infof(data, "Server certificate: %s\n", certp); + free(certp); + } + } + CFRelease(trust); + } + } + else { +#if CURL_SUPPORT_MAC_10_8 err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs); - /* Just in case SSLCopyPeerCertificates() returns null too... */ - if(err == noErr && server_certs) { - count = CFArrayGetCount(server_certs); - for(i = 0L ; i < count ; i++) { - char *certp; - CURLcode result; - server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, - i); - result = CopyCertSubject(data, server_cert, &certp); - if(!result) { - infof(data, "Server certificate: %s\n", certp); - free(certp); - } - } - CFRelease(server_certs); - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#endif /* CURL_BUILD_IOS */ -#else -#pragma unused(trust) + /* Just in case SSLCopyPeerCertificates() returns null too... */ + if(err == noErr && server_certs) { + count = CFArrayGetCount(server_certs); + for(i = 0L ; i < count ; i++) { + char *certp; + CURLcode result; + server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, + i); + result = CopyCertSubject(data, server_cert, &certp); + if(!result) { + infof(data, "Server certificate: %s\n", certp); + free(certp); + } + } + CFRelease(server_certs); + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#endif /* CURL_BUILD_IOS */ +#else +#pragma unused(trust) err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs); - if(err == noErr) { - count = CFArrayGetCount(server_certs); - for(i = 0L ; i < count ; i++) { - CURLcode result; - char *certp; - server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i); - result = CopyCertSubject(data, server_cert, &certp); - if(!result) { - infof(data, "Server certificate: %s\n", certp); - free(certp); - } - } - CFRelease(server_certs); - } -#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ -} -#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ - -static CURLcode -sectransp_connect_step3(struct connectdata *conn, - int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - /* There is no step 3! - * Well, okay, if verbose mode is on, let's print the details of the - * server certificates. */ -#ifndef CURL_DISABLE_VERBOSE_STRINGS - if(data->set.verbose) - show_verbose_server_cert(conn, sockindex); -#endif - - connssl->connecting_state = ssl_connect_done; - return CURLE_OK; -} - -static Curl_recv sectransp_recv; -static Curl_send sectransp_send; - -static CURLcode -sectransp_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode result; - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1 == connssl->connecting_state) { - /* Find out how much more time we're allowed */ + if(err == noErr) { + count = CFArrayGetCount(server_certs); + for(i = 0L ; i < count ; i++) { + CURLcode result; + char *certp; + server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i); + result = CopyCertSubject(data, server_cert, &certp); + if(!result) { + infof(data, "Server certificate: %s\n", certp); + free(certp); + } + } + CFRelease(server_certs); + } +#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ +} +#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ + +static CURLcode +sectransp_connect_step3(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + /* There is no step 3! + * Well, okay, if verbose mode is on, let's print the details of the + * server certificates. */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(data->set.verbose) + show_verbose_server_cert(conn, sockindex); +#endif + + connssl->connecting_state = ssl_connect_done; + return CURLE_OK; +} + +static Curl_recv sectransp_recv; +static Curl_send sectransp_send; + +static CURLcode +sectransp_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - result = sectransp_connect_step1(conn, sockindex); - if(result) - return result; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - /* check allowed time left */ + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = sectransp_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading || - connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing == - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading == - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading || + connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, nonblocking ? 0 : timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if this - * connection is done nonblocking and this loop would execute again. This - * permits the owner of a multi handle to abort a connection attempt - * before step2 has completed while ensuring that a client using select() - * or epoll() will always have a valid fdset to wait on. - */ - result = sectransp_connect_step2(conn, sockindex); - if(result || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return result; - - } /* repeat step2 until all transactions are done. */ - - - if(ssl_connect_3 == connssl->connecting_state) { - result = sectransp_connect_step3(conn, sockindex); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = sectransp_recv; - conn->send[sockindex] = sectransp_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -static CURLcode Curl_sectransp_connect_nonblocking(struct connectdata *conn, - int sockindex, bool *done) -{ - return sectransp_connect_common(conn, sockindex, TRUE, done); -} - -static CURLcode Curl_sectransp_connect(struct connectdata *conn, int sockindex) -{ - CURLcode result; - bool done = FALSE; - - result = sectransp_connect_common(conn, sockindex, FALSE, &done); - - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -static void Curl_sectransp_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + result = sectransp_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + + } /* repeat step2 until all transactions are done. */ + + + if(ssl_connect_3 == connssl->connecting_state) { + result = sectransp_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = sectransp_recv; + conn->send[sockindex] = sectransp_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static CURLcode Curl_sectransp_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return sectransp_connect_common(conn, sockindex, TRUE, done); +} + +static CURLcode Curl_sectransp_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = sectransp_connect_common(conn, sockindex, FALSE, &done); + + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static void Curl_sectransp_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - + if(backend->ssl_ctx) { (void)SSLClose(backend->ssl_ctx); -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(SSLCreateContext != NULL) +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLCreateContext != NULL) CFRelease(backend->ssl_ctx); -#if CURL_SUPPORT_MAC_10_8 - else +#if CURL_SUPPORT_MAC_10_8 + else (void)SSLDisposeContext(backend->ssl_ctx); -#endif /* CURL_SUPPORT_MAC_10_8 */ -#else +#endif /* CURL_SUPPORT_MAC_10_8 */ +#else (void)SSLDisposeContext(backend->ssl_ctx); -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ backend->ssl_ctx = NULL; - } + } backend->ssl_sockfd = 0; -} - -static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; +} + +static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - struct Curl_easy *data = conn->data; - ssize_t nread; - int what; - int rc; - char buf[120]; - + struct Curl_easy *data = conn->data; + ssize_t nread; + int what; + int rc; + char buf[120]; + if(!backend->ssl_ctx) - return 0; - -#ifndef CURL_DISABLE_FTP - if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) - return 0; -#endif - - Curl_sectransp_close(conn, sockindex); - - rc = 0; - - what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); - - for(;;) { - if(what < 0) { - /* anything that gets here is fatally bad */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - rc = -1; - break; - } - - if(!what) { /* timeout */ - failf(data, "SSL shutdown timeout"); - break; - } - - /* Something to read, let's do it and hope that it is the close - notify alert from the server. No way to SSL_Read now, so use read(). */ - - nread = read(conn->sock[sockindex], buf, sizeof(buf)); - - if(nread < 0) { - failf(data, "read: %s", strerror(errno)); - rc = -1; - } - - if(nread <= 0) - break; - - what = SOCKET_READABLE(conn->sock[sockindex], 0); - } - - return rc; -} - -static void Curl_sectransp_session_free(void *ptr) -{ - /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a - cached session ID inside the Security framework. There is a private - function that does this, but I don't want to have to explain to you why I - got your application rejected from the App Store due to the use of a - private API, so the best we can do is free up our own char array that we - created way back in sectransp_connect_step1... */ - Curl_safefree(ptr); -} - -static size_t Curl_sectransp_version(char *buffer, size_t size) -{ - return msnprintf(buffer, size, "SecureTransport"); -} - -/* - * This function uses SSLGetSessionState to determine connection status. - * - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ -static int Curl_sectransp_check_cxn(struct connectdata *conn) -{ - struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; + return 0; + +#ifndef CURL_DISABLE_FTP + if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) + return 0; +#endif + + Curl_sectransp_close(conn, sockindex); + + rc = 0; + + what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); + + for(;;) { + if(what < 0) { + /* anything that gets here is fatally bad */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + rc = -1; + break; + } + + if(!what) { /* timeout */ + failf(data, "SSL shutdown timeout"); + break; + } + + /* Something to read, let's do it and hope that it is the close + notify alert from the server. No way to SSL_Read now, so use read(). */ + + nread = read(conn->sock[sockindex], buf, sizeof(buf)); + + if(nread < 0) { + failf(data, "read: %s", strerror(errno)); + rc = -1; + } + + if(nread <= 0) + break; + + what = SOCKET_READABLE(conn->sock[sockindex], 0); + } + + return rc; +} + +static void Curl_sectransp_session_free(void *ptr) +{ + /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a + cached session ID inside the Security framework. There is a private + function that does this, but I don't want to have to explain to you why I + got your application rejected from the App Store due to the use of a + private API, so the best we can do is free up our own char array that we + created way back in sectransp_connect_step1... */ + Curl_safefree(ptr); +} + +static size_t Curl_sectransp_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "SecureTransport"); +} + +/* + * This function uses SSLGetSessionState to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +static int Curl_sectransp_check_cxn(struct connectdata *conn) +{ + struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; struct ssl_backend_data *backend = connssl->backend; - OSStatus err; - SSLSessionState state; - + OSStatus err; + SSLSessionState state; + if(backend->ssl_ctx) { err = SSLGetSessionState(backend->ssl_ctx, &state); - if(err == noErr) - return state == kSSLConnected || state == kSSLHandshake; - return -1; - } - return 0; -} - -static bool Curl_sectransp_data_pending(const struct connectdata *conn, - int connindex) -{ - const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + if(err == noErr) + return state == kSSLConnected || state == kSSLHandshake; + return -1; + } + return 0; +} + +static bool Curl_sectransp_data_pending(const struct connectdata *conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; struct ssl_backend_data *backend = connssl->backend; - OSStatus err; - size_t buffer; - + OSStatus err; + size_t buffer; + if(backend->ssl_ctx) { /* SSL is in use */ err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer); - if(err == noErr) - return buffer > 0UL; - return false; - } - else - return false; -} - -static CURLcode Curl_sectransp_random(struct Curl_easy *data UNUSED_PARAM, - unsigned char *entropy, size_t length) -{ - /* arc4random_buf() isn't available on cats older than Lion, so let's - do this manually for the benefit of the older cats. */ - size_t i; - u_int32_t random_number = 0; - - (void)data; - - for(i = 0 ; i < length ; i++) { - if(i % sizeof(u_int32_t) == 0) - random_number = arc4random(); - entropy[i] = random_number & 0xFF; - random_number >>= 8; - } - i = random_number = 0; - return CURLE_OK; -} - -static CURLcode Curl_sectransp_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len) -{ - (void)md5len; - (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum); - return CURLE_OK; -} - -static CURLcode Curl_sectransp_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum, /* output */ - size_t sha256len) -{ - assert(sha256len >= CURL_SHA256_DIGEST_LENGTH); - (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum); - return CURLE_OK; -} - -static bool Curl_sectransp_false_start(void) -{ -#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 - if(SSLSetSessionOption != NULL) - return TRUE; -#endif - return FALSE; -} - -static ssize_t sectransp_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - /*struct Curl_easy *data = conn->data;*/ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + if(err == noErr) + return buffer > 0UL; + return false; + } + else + return false; +} + +static CURLcode Curl_sectransp_random(struct Curl_easy *data UNUSED_PARAM, + unsigned char *entropy, size_t length) +{ + /* arc4random_buf() isn't available on cats older than Lion, so let's + do this manually for the benefit of the older cats. */ + size_t i; + u_int32_t random_number = 0; + + (void)data; + + for(i = 0 ; i < length ; i++) { + if(i % sizeof(u_int32_t) == 0) + random_number = arc4random(); + entropy[i] = random_number & 0xFF; + random_number >>= 8; + } + i = random_number = 0; + return CURLE_OK; +} + +static CURLcode Curl_sectransp_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum, /* output */ + size_t md5len) +{ + (void)md5len; + (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum); + return CURLE_OK; +} + +static CURLcode Curl_sectransp_sha256sum(const unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum, /* output */ + size_t sha256len) +{ + assert(sha256len >= CURL_SHA256_DIGEST_LENGTH); + (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum); + return CURLE_OK; +} + +static bool Curl_sectransp_false_start(void) +{ +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + if(SSLSetSessionOption != NULL) + return TRUE; +#endif + return FALSE; +} + +static ssize_t sectransp_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + /*struct Curl_easy *data = conn->data;*/ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - size_t processed = 0UL; - OSStatus err; - - /* The SSLWrite() function works a little differently than expected. The - fourth argument (processed) is currently documented in Apple's - documentation as: "On return, the length, in bytes, of the data actually - written." - - Now, one could interpret that as "written to the socket," but actually, - it returns the amount of data that was written to a buffer internal to - the SSLContextRef instead. So it's possible for SSLWrite() to return - errSSLWouldBlock and a number of bytes "written" because those bytes were - encrypted and written to a buffer, not to the socket. - - So if this happens, then we need to keep calling SSLWrite() over and - over again with no new data until it quits returning errSSLWouldBlock. */ - - /* Do we have buffered data to write from the last time we were called? */ + size_t processed = 0UL; + OSStatus err; + + /* The SSLWrite() function works a little differently than expected. The + fourth argument (processed) is currently documented in Apple's + documentation as: "On return, the length, in bytes, of the data actually + written." + + Now, one could interpret that as "written to the socket," but actually, + it returns the amount of data that was written to a buffer internal to + the SSLContextRef instead. So it's possible for SSLWrite() to return + errSSLWouldBlock and a number of bytes "written" because those bytes were + encrypted and written to a buffer, not to the socket. + + So if this happens, then we need to keep calling SSLWrite() over and + over again with no new data until it quits returning errSSLWouldBlock. */ + + /* Do we have buffered data to write from the last time we were called? */ if(backend->ssl_write_buffered_length) { - /* Write the buffered data: */ + /* Write the buffered data: */ err = SSLWrite(backend->ssl_ctx, NULL, 0UL, &processed); - switch(err) { - case noErr: - /* processed is always going to be 0 because we didn't write to - the buffer, so return how much was written to the socket */ + switch(err) { + case noErr: + /* processed is always going to be 0 because we didn't write to + the buffer, so return how much was written to the socket */ processed = backend->ssl_write_buffered_length; backend->ssl_write_buffered_length = 0UL; - break; - case errSSLWouldBlock: /* argh, try again */ - *curlcode = CURLE_AGAIN; - return -1L; - default: - failf(conn->data, "SSLWrite() returned error %d", err); - *curlcode = CURLE_SEND_ERROR; - return -1L; - } - } - else { - /* We've got new data to write: */ + break; + case errSSLWouldBlock: /* argh, try again */ + *curlcode = CURLE_AGAIN; + return -1L; + default: + failf(conn->data, "SSLWrite() returned error %d", err); + *curlcode = CURLE_SEND_ERROR; + return -1L; + } + } + else { + /* We've got new data to write: */ err = SSLWrite(backend->ssl_ctx, mem, len, &processed); - if(err != noErr) { - switch(err) { - case errSSLWouldBlock: - /* Data was buffered but not sent, we have to tell the caller - to try sending again, and remember how much was buffered */ + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: + /* Data was buffered but not sent, we have to tell the caller + to try sending again, and remember how much was buffered */ backend->ssl_write_buffered_length = len; - *curlcode = CURLE_AGAIN; - return -1L; - default: - failf(conn->data, "SSLWrite() returned error %d", err); - *curlcode = CURLE_SEND_ERROR; - return -1L; - } - } - } - return (ssize_t)processed; -} - -static ssize_t sectransp_recv(struct connectdata *conn, - int num, - char *buf, - size_t buffersize, - CURLcode *curlcode) -{ - /*struct Curl_easy *data = conn->data;*/ - struct ssl_connect_data *connssl = &conn->ssl[num]; + *curlcode = CURLE_AGAIN; + return -1L; + default: + failf(conn->data, "SSLWrite() returned error %d", err); + *curlcode = CURLE_SEND_ERROR; + return -1L; + } + } + } + return (ssize_t)processed; +} + +static ssize_t sectransp_recv(struct connectdata *conn, + int num, + char *buf, + size_t buffersize, + CURLcode *curlcode) +{ + /*struct Curl_easy *data = conn->data;*/ + struct ssl_connect_data *connssl = &conn->ssl[num]; struct ssl_backend_data *backend = connssl->backend; - size_t processed = 0UL; - OSStatus err; - - again: + size_t processed = 0UL; + OSStatus err; + + again: err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed); - - if(err != noErr) { - switch(err) { - case errSSLWouldBlock: /* return how much we read (if anything) */ - if(processed) - return (ssize_t)processed; - *curlcode = CURLE_AGAIN; - return -1L; - break; - - /* errSSLClosedGraceful - server gracefully shut down the SSL session - errSSLClosedNoNotify - server hung up on us instead of sending a - closure alert notice, read() is returning 0 - Either way, inform the caller that the server disconnected. */ - case errSSLClosedGraceful: - case errSSLClosedNoNotify: - *curlcode = CURLE_OK; - return -1L; - break; - - /* The below is errSSLPeerAuthCompleted; it's not defined in - Leopard's headers */ - case -9841: - if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { - CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), conn->data, + + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: /* return how much we read (if anything) */ + if(processed) + return (ssize_t)processed; + *curlcode = CURLE_AGAIN; + return -1L; + break; + + /* errSSLClosedGraceful - server gracefully shut down the SSL session + errSSLClosedNoNotify - server hung up on us instead of sending a + closure alert notice, read() is returning 0 + Either way, inform the caller that the server disconnected. */ + case errSSLClosedGraceful: + case errSSLClosedNoNotify: + *curlcode = CURLE_OK; + return -1L; + break; + + /* The below is errSSLPeerAuthCompleted; it's not defined in + Leopard's headers */ + case -9841: + if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { + CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), conn->data, backend->ssl_ctx); - if(result) - return result; - } - goto again; - default: - failf(conn->data, "SSLRead() return error %d", err); - *curlcode = CURLE_RECV_ERROR; - return -1L; - break; - } - } - return (ssize_t)processed; -} - -static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl, - CURLINFO info UNUSED_PARAM) -{ + if(result) + return result; + } + goto again; + default: + failf(conn->data, "SSLRead() return error %d", err); + *curlcode = CURLE_RECV_ERROR; + return -1L; + break; + } + } + return (ssize_t)processed; +} + +static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ struct ssl_backend_data *backend = connssl->backend; - (void)info; + (void)info; return backend->ssl_ctx; -} - -const struct Curl_ssl Curl_ssl_sectransp = { - { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */ - -#ifdef SECTRANSP_PINNEDPUBKEY - SSLSUPP_PINNEDPUBKEY, -#else - 0, -#endif /* SECTRANSP_PINNEDPUBKEY */ - - sizeof(struct ssl_backend_data), - - Curl_none_init, /* init */ - Curl_none_cleanup, /* cleanup */ - Curl_sectransp_version, /* version */ - Curl_sectransp_check_cxn, /* check_cxn */ - Curl_sectransp_shutdown, /* shutdown */ - Curl_sectransp_data_pending, /* data_pending */ - Curl_sectransp_random, /* random */ - Curl_none_cert_status_request, /* cert_status_request */ - Curl_sectransp_connect, /* connect */ - Curl_sectransp_connect_nonblocking, /* connect_nonblocking */ - Curl_sectransp_get_internals, /* get_internals */ - Curl_sectransp_close, /* close_one */ - Curl_none_close_all, /* close_all */ - Curl_sectransp_session_free, /* session_free */ - Curl_none_set_engine, /* set_engine */ - Curl_none_set_engine_default, /* set_engine_default */ - Curl_none_engines_list, /* engines_list */ - Curl_sectransp_false_start, /* false_start */ - Curl_sectransp_md5sum, /* md5sum */ - Curl_sectransp_sha256sum /* sha256sum */ -}; - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#endif /* USE_SECTRANSP */ +} + +const struct Curl_ssl Curl_ssl_sectransp = { + { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */ + +#ifdef SECTRANSP_PINNEDPUBKEY + SSLSUPP_PINNEDPUBKEY, +#else + 0, +#endif /* SECTRANSP_PINNEDPUBKEY */ + + sizeof(struct ssl_backend_data), + + Curl_none_init, /* init */ + Curl_none_cleanup, /* cleanup */ + Curl_sectransp_version, /* version */ + Curl_sectransp_check_cxn, /* check_cxn */ + Curl_sectransp_shutdown, /* shutdown */ + Curl_sectransp_data_pending, /* data_pending */ + Curl_sectransp_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_sectransp_connect, /* connect */ + Curl_sectransp_connect_nonblocking, /* connect_nonblocking */ + Curl_sectransp_get_internals, /* get_internals */ + Curl_sectransp_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_sectransp_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_sectransp_false_start, /* false_start */ + Curl_sectransp_md5sum, /* md5sum */ + Curl_sectransp_sha256sum /* sha256sum */ +}; + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif /* USE_SECTRANSP */ diff --git a/contrib/libs/curl/lib/vtls/sectransp.h b/contrib/libs/curl/lib/vtls/sectransp.h index 1f0791b6cb..0febd6613a 100644 --- a/contrib/libs/curl/lib/vtls/sectransp.h +++ b/contrib/libs/curl/lib/vtls/sectransp.h @@ -1,32 +1,32 @@ -#ifndef HEADER_CURL_SECTRANSP_H -#define HEADER_CURL_SECTRANSP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>. +#ifndef HEADER_CURL_SECTRANSP_H +#define HEADER_CURL_SECTRANSP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>. * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_SECTRANSP - -extern const struct Curl_ssl Curl_ssl_sectransp; - -#endif /* USE_SECTRANSP */ -#endif /* HEADER_CURL_SECTRANSP_H */ + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_SECTRANSP + +extern const struct Curl_ssl Curl_ssl_sectransp; + +#endif /* USE_SECTRANSP */ +#endif /* HEADER_CURL_SECTRANSP_H */ diff --git a/contrib/libs/curl/lib/vtls/vtls.c b/contrib/libs/curl/lib/vtls/vtls.c index 2da7d13736..3bd51fdaf2 100644 --- a/contrib/libs/curl/lib/vtls/vtls.c +++ b/contrib/libs/curl/lib/vtls/vtls.c @@ -306,7 +306,7 @@ Curl_ssl_connect(struct connectdata *conn, int sockindex) conn->ssl[sockindex].use = TRUE; conn->ssl[sockindex].state = ssl_connection_negotiating; - result = Curl_ssl->connect_blocking(conn, sockindex); + result = Curl_ssl->connect_blocking(conn, sockindex); if(!result) Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */ @@ -577,7 +577,7 @@ void Curl_ssl_close_all(struct Curl_easy *data) { /* kill the session ID cache if not shared */ if(data->state.session && !SSLSESSION_SHARED(data)) { - size_t i; + size_t i; for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) /* the single-killer function handles empty table slots */ Curl_ssl_kill_session(&data->state.session[i]); @@ -592,7 +592,7 @@ void Curl_ssl_close_all(struct Curl_easy *data) #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ defined(USE_SECTRANSP) || defined(USE_NSS) || \ defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL) -int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks) +int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks) { struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; @@ -611,13 +611,13 @@ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks) } #else int Curl_ssl_getsock(struct connectdata *conn, - curl_socket_t *socks) + curl_socket_t *socks) { (void)conn; (void)socks; return GETSOCK_BLANK; } -/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */ +/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */ #endif void Curl_ssl_close(struct connectdata *conn, int sockindex) @@ -629,7 +629,7 @@ void Curl_ssl_close(struct connectdata *conn, int sockindex) CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex) { - if(Curl_ssl->shut_down(conn, sockindex)) + if(Curl_ssl->shut_down(conn, sockindex)) return CURLE_SSL_SHUTDOWN_FAILED; conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */ @@ -720,7 +720,7 @@ void Curl_ssl_free_certinfo(struct Curl_easy *data) if(ci->num_of_certs) { /* free all individual lists used */ - int i; + int i; for(i = 0; i<ci->num_of_certs; i++) { curl_slist_free_all(ci->certinfo[i]); ci->certinfo[i] = NULL; @@ -890,11 +890,11 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, /* only do this if pinnedpubkey starts with "sha256//", length 8 */ if(strncmp(pinnedpubkey, "sha256//", 8) == 0) { - CURLcode encode; - size_t encodedlen, pinkeylen; - char *encoded, *pinkeycopy, *begin_pos, *end_pos; - unsigned char *sha256sumdigest; - + CURLcode encode; + size_t encodedlen, pinkeylen; + char *encoded, *pinkeycopy, *begin_pos, *end_pos; + unsigned char *sha256sumdigest; + if(!Curl_ssl->sha256sum) { /* without sha256 support, this cannot match */ return result; @@ -965,10 +965,10 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, return result; do { - long filesize; - size_t size, pem_len; - CURLcode pem_read; - + long filesize; + size_t size, pem_len; + CURLcode pem_read; + /* Determine the file's size */ if(fseek(fp, 0, SEEK_END)) break; @@ -1188,7 +1188,7 @@ static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex) { if(multissl_init(NULL)) return CURLE_FAILED_INIT; - return Curl_ssl->connect_blocking(conn, sockindex); + return Curl_ssl->connect_blocking(conn, sockindex); } static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn, @@ -1244,10 +1244,10 @@ static const struct Curl_ssl Curl_ssl_multi = { const struct Curl_ssl *Curl_ssl = #if defined(CURL_WITH_MULTI_SSL) &Curl_ssl_multi; -#elif defined(USE_WOLFSSL) - &Curl_ssl_wolfssl; -#elif defined(USE_SECTRANSP) - &Curl_ssl_sectransp; +#elif defined(USE_WOLFSSL) + &Curl_ssl_wolfssl; +#elif defined(USE_SECTRANSP) + &Curl_ssl_sectransp; #elif defined(USE_GNUTLS) &Curl_ssl_gnutls; #elif defined(USE_GSKIT) @@ -1269,11 +1269,11 @@ const struct Curl_ssl *Curl_ssl = #endif static const struct Curl_ssl *available_backends[] = { -#if defined(USE_WOLFSSL) - &Curl_ssl_wolfssl, +#if defined(USE_WOLFSSL) + &Curl_ssl_wolfssl, #endif -#if defined(USE_SECTRANSP) - &Curl_ssl_sectransp, +#if defined(USE_SECTRANSP) + &Curl_ssl_sectransp, #endif #if defined(USE_GNUTLS) &Curl_ssl_gnutls, @@ -1313,7 +1313,7 @@ static size_t Curl_multissl_version(char *buffer, size_t size) if(current != selected) { char *p = backends; - char *end = backends + sizeof(backends); + char *end = backends + sizeof(backends); int i; selected = current; @@ -1368,7 +1368,7 @@ static int multissl_init(const struct Curl_ssl *backend) env = CURL_DEFAULT_SSL_BACKEND; #endif if(env) { - int i; + int i; for(i = 0; available_backends[i]; i++) { if(strcasecompare(env, available_backends[i]->info.name)) { Curl_ssl = available_backends[i]; diff --git a/contrib/libs/curl/lib/vtls/vtls.h b/contrib/libs/curl/lib/vtls/vtls.h index be8ded618c..f4cab9988f 100644 --- a/contrib/libs/curl/lib/vtls/vtls.h +++ b/contrib/libs/curl/lib/vtls/vtls.h @@ -47,7 +47,7 @@ struct Curl_ssl { size_t (*version)(char *buffer, size_t size); int (*check_cxn)(struct connectdata *cxn); - int (*shut_down)(struct connectdata *conn, int sockindex); + int (*shut_down)(struct connectdata *conn, int sockindex); bool (*data_pending)(const struct connectdata *conn, int connindex); @@ -56,7 +56,7 @@ struct Curl_ssl { size_t length); bool (*cert_status_request)(void); - CURLcode (*connect_blocking)(struct connectdata *conn, int sockindex); + CURLcode (*connect_blocking)(struct connectdata *conn, int sockindex); CURLcode (*connect_nonblocking)(struct connectdata *conn, int sockindex, bool *done); void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info); @@ -102,9 +102,9 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, #include "gtls.h" /* GnuTLS versions */ #include "nssg.h" /* NSS versions */ #include "gskit.h" /* Global Secure ToolKit versions */ -#include "wolfssl.h" /* wolfSSL versions */ +#include "wolfssl.h" /* wolfSSL versions */ #include "schannel.h" /* Schannel SSPI version */ -#include "sectransp.h" /* SecureTransport (Darwin) version */ +#include "sectransp.h" /* SecureTransport (Darwin) version */ #include "mbedtls.h" /* mbedTLS versions */ #include "mesalink.h" /* MesaLink versions */ #include "bearssl.h" /* BearSSL versions */ @@ -158,7 +158,7 @@ bool Curl_ssl_config_matches(struct ssl_primary_config *data, bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source, struct ssl_primary_config *dest); void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc); -int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks); +int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks); int Curl_ssl_backend(void); diff --git a/contrib/libs/curl/lib/vtls/wolfssl.c b/contrib/libs/curl/lib/vtls/wolfssl.c index 3627be345c..ac9818824d 100644 --- a/contrib/libs/curl/lib/vtls/wolfssl.c +++ b/contrib/libs/curl/lib/vtls/wolfssl.c @@ -1,105 +1,105 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all wolfSSL specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - */ - -#include "curl_setup.h" - -#ifdef USE_WOLFSSL - -#define WOLFSSL_OPTIONS_IGNORE_SYS -#error #include <wolfssl/version.h> -#error #include <wolfssl/options.h> - -/* To determine what functions are available we rely on one or both of: - - the user's options.h generated by wolfSSL - - the symbols detected by curl's configure - Since they are markedly different from one another, and one or the other may - not be available, we do some checking below to bring things in sync. */ - -/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */ -#ifndef HAVE_ALPN -#ifdef HAVE_WOLFSSL_USEALPN -#define HAVE_ALPN -#endif -#endif - -/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in - options.h, but is only seen in >= 3.6.6 since that's when they started - disabling SSLv3 by default. */ -#ifndef WOLFSSL_ALLOW_SSLV3 -#if (LIBWOLFSSL_VERSION_HEX < 0x03006006) || \ - defined(HAVE_WOLFSSLV3_CLIENT_METHOD) -#define WOLFSSL_ALLOW_SSLV3 -#endif -#endif - -#include <limits.h> - -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "vtls.h" + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all wolfSSL specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + * + */ + +#include "curl_setup.h" + +#ifdef USE_WOLFSSL + +#define WOLFSSL_OPTIONS_IGNORE_SYS +#error #include <wolfssl/version.h> +#error #include <wolfssl/options.h> + +/* To determine what functions are available we rely on one or both of: + - the user's options.h generated by wolfSSL + - the symbols detected by curl's configure + Since they are markedly different from one another, and one or the other may + not be available, we do some checking below to bring things in sync. */ + +/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */ +#ifndef HAVE_ALPN +#ifdef HAVE_WOLFSSL_USEALPN +#define HAVE_ALPN +#endif +#endif + +/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in + options.h, but is only seen in >= 3.6.6 since that's when they started + disabling SSLv3 by default. */ +#ifndef WOLFSSL_ALLOW_SSLV3 +#if (LIBWOLFSSL_VERSION_HEX < 0x03006006) || \ + defined(HAVE_WOLFSSLV3_CLIENT_METHOD) +#define WOLFSSL_ALLOW_SSLV3 +#endif +#endif + +#include <limits.h> + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" #include "keylog.h" -#include "parsedate.h" -#include "connect.h" /* for the connect timeout */ -#include "select.h" -#include "strcase.h" -#include "x509asn1.h" -#include "curl_printf.h" -#include "multiif.h" - -#error #include <wolfssl/openssl/ssl.h> -#error #include <wolfssl/ssl.h> -#error #include <wolfssl/error-ssl.h> -#include "wolfssl.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* KEEP_PEER_CERT is a product of the presence of build time symbol - OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is - in wolfSSL's settings.h, and the latter two are build time symbols in - options.h. */ -#ifndef KEEP_PEER_CERT -#if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \ - (defined(OPENSSL_EXTRA) && !defined(NO_CERTS)) -#define KEEP_PEER_CERT -#endif -#endif - -struct ssl_backend_data { - SSL_CTX* ctx; - SSL* handle; -}; - -static Curl_recv wolfssl_recv; -static Curl_send wolfssl_send; - +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "strcase.h" +#include "x509asn1.h" +#include "curl_printf.h" +#include "multiif.h" + +#error #include <wolfssl/openssl/ssl.h> +#error #include <wolfssl/ssl.h> +#error #include <wolfssl/error-ssl.h> +#include "wolfssl.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* KEEP_PEER_CERT is a product of the presence of build time symbol + OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is + in wolfSSL's settings.h, and the latter two are build time symbols in + options.h. */ +#ifndef KEEP_PEER_CERT +#if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \ + (defined(OPENSSL_EXTRA) && !defined(NO_CERTS)) +#define KEEP_PEER_CERT +#endif +#endif + +struct ssl_backend_data { + SSL_CTX* ctx; + SSL* handle; +}; + +static Curl_recv wolfssl_recv; +static Curl_send wolfssl_send; + #ifdef OPENSSL_EXTRA /* * Availability note: @@ -118,7 +118,7 @@ wolfssl_tls13_secret_callback(SSL *ssl, int id, const unsigned char *secret, const char *label; unsigned char client_random[SSL3_RANDOM_SIZE]; (void)ctx; - + if(!ssl || !Curl_tls_keylog_enabled()) { return 0; } @@ -201,294 +201,294 @@ wolfssl_log_tls12_secret(SSL *ssl) } #endif /* OPENSSL_EXTRA */ -static int do_file_type(const char *type) -{ - if(!type || !type[0]) - return SSL_FILETYPE_PEM; - if(strcasecompare(type, "PEM")) - return SSL_FILETYPE_PEM; - if(strcasecompare(type, "DER")) - return SSL_FILETYPE_ASN1; - return -1; -} - -/* - * This function loads all the client/CA certificates and CRLs. Setup the TLS - * layer and do all necessary magic. - */ -static CURLcode -wolfssl_connect_step1(struct connectdata *conn, - int sockindex) -{ - char *ciphers; - struct Curl_easy *data = conn->data; +static int do_file_type(const char *type) +{ + if(!type || !type[0]) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "PEM")) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "DER")) + return SSL_FILETYPE_ASN1; + return -1; +} + +/* + * This function loads all the client/CA certificates and CRLs. Setup the TLS + * layer and do all necessary magic. + */ +static CURLcode +wolfssl_connect_step1(struct connectdata *conn, + int sockindex) +{ + char *ciphers; + struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - SSL_METHOD* req_method = NULL; - curl_socket_t sockfd = conn->sock[sockindex]; -#ifdef HAVE_SNI - bool sni = FALSE; -#define use_sni(x) sni = (x) -#else -#define use_sni(x) Curl_nop_stmt -#endif - - if(connssl->state == ssl_connection_complete) - return CURLE_OK; - - if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) { - failf(data, "wolfSSL does not support to set maximum SSL/TLS version"); - return CURLE_SSL_CONNECT_ERROR; - } - - /* check to see if we've been told to use an explicit SSL/TLS version */ - switch(SSL_CONN_CONFIG(version)) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: -#if LIBWOLFSSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */ - /* minimum protocol version is set later after the CTX object is created */ - req_method = SSLv23_client_method(); -#else - infof(data, "wolfSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, " - "TLS 1.0 is used exclusively\n"); - req_method = TLSv1_client_method(); -#endif - use_sni(TRUE); - break; - case CURL_SSLVERSION_TLSv1_0: -#ifdef WOLFSSL_ALLOW_TLSV10 - req_method = TLSv1_client_method(); - use_sni(TRUE); -#else - failf(data, "wolfSSL does not support TLS 1.0"); - return CURLE_NOT_BUILT_IN; -#endif - break; - case CURL_SSLVERSION_TLSv1_1: - req_method = TLSv1_1_client_method(); - use_sni(TRUE); - break; - case CURL_SSLVERSION_TLSv1_2: - req_method = TLSv1_2_client_method(); - use_sni(TRUE); - break; - case CURL_SSLVERSION_TLSv1_3: -#ifdef WOLFSSL_TLS13 - req_method = wolfTLSv1_3_client_method(); - use_sni(TRUE); - break; -#else - failf(data, "wolfSSL: TLS 1.3 is not yet supported"); - return CURLE_SSL_CONNECT_ERROR; -#endif - case CURL_SSLVERSION_SSLv3: -#ifdef WOLFSSL_ALLOW_SSLV3 - req_method = SSLv3_client_method(); - use_sni(FALSE); -#else - failf(data, "wolfSSL does not support SSLv3"); - return CURLE_NOT_BUILT_IN; -#endif - break; - case CURL_SSLVERSION_SSLv2: - failf(data, "wolfSSL does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(!req_method) { - failf(data, "SSL: couldn't create a method!"); - return CURLE_OUT_OF_MEMORY; - } - + SSL_METHOD* req_method = NULL; + curl_socket_t sockfd = conn->sock[sockindex]; +#ifdef HAVE_SNI + bool sni = FALSE; +#define use_sni(x) sni = (x) +#else +#define use_sni(x) Curl_nop_stmt +#endif + + if(connssl->state == ssl_connection_complete) + return CURLE_OK; + + if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) { + failf(data, "wolfSSL does not support to set maximum SSL/TLS version"); + return CURLE_SSL_CONNECT_ERROR; + } + + /* check to see if we've been told to use an explicit SSL/TLS version */ + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: +#if LIBWOLFSSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */ + /* minimum protocol version is set later after the CTX object is created */ + req_method = SSLv23_client_method(); +#else + infof(data, "wolfSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, " + "TLS 1.0 is used exclusively\n"); + req_method = TLSv1_client_method(); +#endif + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_0: +#ifdef WOLFSSL_ALLOW_TLSV10 + req_method = TLSv1_client_method(); + use_sni(TRUE); +#else + failf(data, "wolfSSL does not support TLS 1.0"); + return CURLE_NOT_BUILT_IN; +#endif + break; + case CURL_SSLVERSION_TLSv1_1: + req_method = TLSv1_1_client_method(); + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_2: + req_method = TLSv1_2_client_method(); + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_3: +#ifdef WOLFSSL_TLS13 + req_method = wolfTLSv1_3_client_method(); + use_sni(TRUE); + break; +#else + failf(data, "wolfSSL: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; +#endif + case CURL_SSLVERSION_SSLv3: +#ifdef WOLFSSL_ALLOW_SSLV3 + req_method = SSLv3_client_method(); + use_sni(FALSE); +#else + failf(data, "wolfSSL does not support SSLv3"); + return CURLE_NOT_BUILT_IN; +#endif + break; + case CURL_SSLVERSION_SSLv2: + failf(data, "wolfSSL does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(!req_method) { + failf(data, "SSL: couldn't create a method!"); + return CURLE_OUT_OF_MEMORY; + } + if(backend->ctx) SSL_CTX_free(backend->ctx); backend->ctx = SSL_CTX_new(req_method); - + if(!backend->ctx) { - failf(data, "SSL: couldn't create a context!"); - return CURLE_OUT_OF_MEMORY; - } - - switch(SSL_CONN_CONFIG(version)) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: -#if LIBWOLFSSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */ - /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is - * whatever minimum version of TLS was built in and at least TLS 1.0. For - * later library versions that could change (eg TLS 1.0 built in but - * defaults to TLS 1.1) so we have this short circuit evaluation to find - * the minimum supported TLS version. - */ + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: +#if LIBWOLFSSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */ + /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is + * whatever minimum version of TLS was built in and at least TLS 1.0. For + * later library versions that could change (eg TLS 1.0 built in but + * defaults to TLS 1.1) so we have this short circuit evaluation to find + * the minimum supported TLS version. + */ if((wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1) != 1) && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_1) != 1) && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_2) != 1) -#ifdef WOLFSSL_TLS13 +#ifdef WOLFSSL_TLS13 && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_3) != 1) -#endif - ) { - failf(data, "SSL: couldn't set the minimum protocol version"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif - break; - } - - ciphers = SSL_CONN_CONFIG(cipher_list); - if(ciphers) { +#endif + ) { + failf(data, "SSL: couldn't set the minimum protocol version"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif + break; + } + + ciphers = SSL_CONN_CONFIG(cipher_list); + if(ciphers) { if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) { - failf(data, "failed setting cipher list: %s", ciphers); - return CURLE_SSL_CIPHER; - } - infof(data, "Cipher selection: %s\n", ciphers); - } - -#ifndef NO_FILESYSTEM - /* load trusted cacert */ - if(SSL_CONN_CONFIG(CAfile)) { + failf(data, "failed setting cipher list: %s", ciphers); + return CURLE_SSL_CIPHER; + } + infof(data, "Cipher selection: %s\n", ciphers); + } + +#ifndef NO_FILESYSTEM + /* load trusted cacert */ + if(SSL_CONN_CONFIG(CAfile)) { if(1 != SSL_CTX_load_verify_locations(backend->ctx, - SSL_CONN_CONFIG(CAfile), - SSL_CONN_CONFIG(CApath))) { - if(SSL_CONN_CONFIG(verifypeer)) { - /* Fail if we insist on successfully verifying the server. */ + SSL_CONN_CONFIG(CAfile), + SSL_CONN_CONFIG(CApath))) { + if(SSL_CONN_CONFIG(verifypeer)) { + /* Fail if we insist on successfully verifying the server. */ failf(data, "error setting certificate verify locations:" " CAfile: %s CApath: %s", - SSL_CONN_CONFIG(CAfile)? - SSL_CONN_CONFIG(CAfile): "none", - SSL_CONN_CONFIG(CApath)? - SSL_CONN_CONFIG(CApath) : "none"); - return CURLE_SSL_CACERT_BADFILE; - } - else { - /* Just continue with a warning if no strict certificate - verification is required. */ - infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); - } - } - else { - /* Everything is fine. */ - infof(data, "successfully set certificate verify locations:\n"); - } + SSL_CONN_CONFIG(CAfile)? + SSL_CONN_CONFIG(CAfile): "none", + SSL_CONN_CONFIG(CApath)? + SSL_CONN_CONFIG(CApath) : "none"); + return CURLE_SSL_CACERT_BADFILE; + } + else { + /* Just continue with a warning if no strict certificate + verification is required. */ + infof(data, "error setting certificate verify locations," + " continuing anyway:\n"); + } + } + else { + /* Everything is fine. */ + infof(data, "successfully set certificate verify locations:\n"); + } infof(data, " CAfile: %s\n", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none"); infof(data, " CApath: %s\n", SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none"); - } - - /* Load the client certificate, and private key */ + } + + /* Load the client certificate, and private key */ if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) { - int file_type = do_file_type(SSL_SET_OPTION(cert_type)); - + int file_type = do_file_type(SSL_SET_OPTION(cert_type)); + if(SSL_CTX_use_certificate_file(backend->ctx, SSL_SET_OPTION(primary.clientcert), file_type) != 1) { - failf(data, "unable to use client certificate (no key or wrong pass" - " phrase?)"); - return CURLE_SSL_CONNECT_ERROR; - } - - file_type = do_file_type(SSL_SET_OPTION(key_type)); + failf(data, "unable to use client certificate (no key or wrong pass" + " phrase?)"); + return CURLE_SSL_CONNECT_ERROR; + } + + file_type = do_file_type(SSL_SET_OPTION(key_type)); if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key), - file_type) != 1) { - failf(data, "unable to set private key"); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif /* !NO_FILESYSTEM */ - - /* SSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ + file_type) != 1) { + failf(data, "unable to set private key"); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* !NO_FILESYSTEM */ + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ SSL_CTX_set_verify(backend->ctx, - SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER: - SSL_VERIFY_NONE, - NULL); - -#ifdef HAVE_SNI - if(sni) { - struct in_addr addr4; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif + SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER: + SSL_VERIFY_NONE, + NULL); + +#ifdef HAVE_SNI + if(sni) { + struct in_addr addr4; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; +#endif #ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; #else const char * const hostname = conn->host.name; #endif - size_t hostname_len = strlen(hostname); - if((hostname_len < USHRT_MAX) && - (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) && -#ifdef ENABLE_IPV6 - (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) && -#endif + size_t hostname_len = strlen(hostname); + if((hostname_len < USHRT_MAX) && + (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) && +#ifdef ENABLE_IPV6 + (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) && +#endif (wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, hostname, - (unsigned short)hostname_len) != 1)) { - infof(data, "WARNING: failed to configure server name indication (SNI) " - "TLS extension\n"); - } - } -#endif - - /* give application a chance to interfere with SSL set up. */ - if(data->set.ssl.fsslctx) { + (unsigned short)hostname_len) != 1)) { + infof(data, "WARNING: failed to configure server name indication (SNI) " + "TLS extension\n"); + } + } +#endif + + /* give application a chance to interfere with SSL set up. */ + if(data->set.ssl.fsslctx) { CURLcode result = (*data->set.ssl.fsslctx)(data, backend->ctx, - data->set.ssl.fsslctxp); - if(result) { - failf(data, "error signaled by ssl ctx callback"); - return result; - } - } -#ifdef NO_FILESYSTEM - else if(SSL_CONN_CONFIG(verifypeer)) { - failf(data, "SSL: Certificates can't be loaded because wolfSSL was built" - " with \"no filesystem\". Either disable peer verification" - " (insecure) or if you are building an application with libcurl you" - " can load certificates via CURLOPT_SSL_CTX_FUNCTION."); - return CURLE_SSL_CONNECT_ERROR; - } -#endif - - /* Let's make an SSL structure */ + data->set.ssl.fsslctxp); + if(result) { + failf(data, "error signaled by ssl ctx callback"); + return result; + } + } +#ifdef NO_FILESYSTEM + else if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "SSL: Certificates can't be loaded because wolfSSL was built" + " with \"no filesystem\". Either disable peer verification" + " (insecure) or if you are building an application with libcurl you" + " can load certificates via CURLOPT_SSL_CTX_FUNCTION."); + return CURLE_SSL_CONNECT_ERROR; + } +#endif + + /* Let's make an SSL structure */ if(backend->handle) SSL_free(backend->handle); backend->handle = SSL_new(backend->ctx); if(!backend->handle) { - failf(data, "SSL: couldn't create a context (handle)!"); - return CURLE_OUT_OF_MEMORY; - } - -#ifdef HAVE_ALPN - if(conn->bits.tls_enable_alpn) { - char protocols[128]; - *protocols = '\0'; - - /* wolfSSL's ALPN protocol name list format is a comma separated string of - protocols in descending order of preference, eg: "h2,http/1.1" */ - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { - strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ","); - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1); - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - + failf(data, "SSL: couldn't create a context (handle)!"); + return CURLE_OUT_OF_MEMORY; + } + +#ifdef HAVE_ALPN + if(conn->bits.tls_enable_alpn) { + char protocols[128]; + *protocols = '\0'; + + /* wolfSSL's ALPN protocol name list format is a comma separated string of + protocols in descending order of preference, eg: "h2,http/1.1" */ + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2) { + strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ","); + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1); + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + if(wolfSSL_UseALPN(backend->handle, protocols, - (unsigned)strlen(protocols), - WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) { - failf(data, "SSL: failed setting ALPN protocols"); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif /* HAVE_ALPN */ - + (unsigned)strlen(protocols), + WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) { + failf(data, "SSL: failed setting ALPN protocols"); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* HAVE_ALPN */ + #ifdef OPENSSL_EXTRA if(Curl_tls_keylog_enabled()) { /* Ensure the Client Random is preserved. */ @@ -500,52 +500,52 @@ wolfssl_connect_step1(struct connectdata *conn, } #endif /* OPENSSL_EXTRA */ - /* Check if there's a cached ID we can/should use here! */ - if(SSL_SET_OPTION(primary.sessionid)) { - void *ssl_sessionid = NULL; - - Curl_ssl_sessionid_lock(conn); - if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { - /* we got a session id, use it! */ + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + void *ssl_sessionid = NULL; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ if(!SSL_set_session(backend->handle, ssl_sessionid)) { - char error_buffer[WOLFSSL_MAX_ERROR_SZ]; - Curl_ssl_sessionid_unlock(conn); - failf(data, "SSL: SSL_set_session failed: %s", + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + Curl_ssl_sessionid_unlock(conn); + failf(data, "SSL: SSL_set_session failed: %s", ERR_error_string(SSL_get_error(backend->handle, 0), - error_buffer)); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - infof(data, "SSL re-using session ID\n"); - } - Curl_ssl_sessionid_unlock(conn); - } - - /* pass the raw socket into the SSL layer */ + error_buffer)); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + /* pass the raw socket into the SSL layer */ if(!SSL_set_fd(backend->handle, (int)sockfd)) { - failf(data, "SSL: SSL_set_fd failed"); - return CURLE_SSL_CONNECT_ERROR; - } - - connssl->connecting_state = ssl_connect_2; - return CURLE_OK; -} - - -static CURLcode -wolfssl_connect_step2(struct connectdata *conn, - int sockindex) -{ - int ret = -1; - struct Curl_easy *data = conn->data; + failf(data, "SSL: SSL_set_fd failed"); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + + +static CURLcode +wolfssl_connect_step2(struct connectdata *conn, + int sockindex) +{ + int ret = -1; + struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; #ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - const char * const dispname = SSL_IS_PROXY() ? - conn->http_proxy.host.dispname : conn->host.dispname; - const char * const pinnedpubkey = SSL_IS_PROXY() ? + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const char * const dispname = SSL_IS_PROXY() ? + conn->http_proxy.host.dispname : conn->host.dispname; + const char * const pinnedpubkey = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; #else @@ -554,17 +554,17 @@ wolfssl_connect_step2(struct connectdata *conn, const char * const pinnedpubkey = data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; #endif - - conn->recv[sockindex] = wolfssl_recv; - conn->send[sockindex] = wolfssl_send; - - /* Enable RFC2818 checks */ - if(SSL_CONN_CONFIG(verifyhost)) { + + conn->recv[sockindex] = wolfssl_recv; + conn->send[sockindex] = wolfssl_send; + + /* Enable RFC2818 checks */ + if(SSL_CONN_CONFIG(verifyhost)) { ret = wolfSSL_check_domain_name(backend->handle, hostname); - if(ret == SSL_FAILURE) - return CURLE_OUT_OF_MEMORY; - } - + if(ret == SSL_FAILURE) + return CURLE_OUT_OF_MEMORY; + } + ret = SSL_connect(backend->handle); #ifdef OPENSSL_EXTRA @@ -591,559 +591,559 @@ wolfssl_connect_step2(struct connectdata *conn, } #endif /* OPENSSL_EXTRA */ - if(ret != 1) { - char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + if(ret != 1) { + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; int detail = SSL_get_error(backend->handle, ret); - - if(SSL_ERROR_WANT_READ == detail) { - connssl->connecting_state = ssl_connect_2_reading; - return CURLE_OK; - } - else if(SSL_ERROR_WANT_WRITE == detail) { - connssl->connecting_state = ssl_connect_2_writing; - return CURLE_OK; - } - /* There is no easy way to override only the CN matching. - * This will enable the override of both mismatching SubjectAltNames - * as also mismatching CN fields */ - else if(DOMAIN_NAME_MISMATCH == detail) { -#if 1 - failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n", - dispname); - return CURLE_PEER_FAILED_VERIFICATION; -#else - /* When the wolfssl_check_domain_name() is used and you desire to - * continue on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost - * == 0', CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA - * error. The only way to do this is currently to switch the - * Wolfssl_check_domain_name() in and out based on the - * 'conn->ssl_config.verifyhost' value. */ - if(SSL_CONN_CONFIG(verifyhost)) { - failf(data, - "\tsubject alt name(s) or common name do not match \"%s\"\n", - dispname); - return CURLE_PEER_FAILED_VERIFICATION; - } - else { - infof(data, - "\tsubject alt name(s) and/or common name do not match \"%s\"\n", - dispname); - return CURLE_OK; - } -#endif - } -#if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */ - else if(ASN_NO_SIGNER_E == detail) { - if(SSL_CONN_CONFIG(verifypeer)) { - failf(data, "\tCA signer not available for verification\n"); - return CURLE_SSL_CACERT_BADFILE; - } - else { - /* Just continue with a warning if no strict certificate - verification is required. */ - infof(data, "CA signer not available for verification, " - "continuing anyway\n"); - } - } -#endif - else { - failf(data, "SSL_connect failed with error %d: %s", detail, - ERR_error_string(detail, error_buffer)); - return CURLE_SSL_CONNECT_ERROR; - } - } - - if(pinnedpubkey) { -#ifdef KEEP_PEER_CERT - X509 *x509; - const char *x509_der; - int x509_der_len; + + if(SSL_ERROR_WANT_READ == detail) { + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + } + else if(SSL_ERROR_WANT_WRITE == detail) { + connssl->connecting_state = ssl_connect_2_writing; + return CURLE_OK; + } + /* There is no easy way to override only the CN matching. + * This will enable the override of both mismatching SubjectAltNames + * as also mismatching CN fields */ + else if(DOMAIN_NAME_MISMATCH == detail) { +#if 1 + failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n", + dispname); + return CURLE_PEER_FAILED_VERIFICATION; +#else + /* When the wolfssl_check_domain_name() is used and you desire to + * continue on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost + * == 0', CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA + * error. The only way to do this is currently to switch the + * Wolfssl_check_domain_name() in and out based on the + * 'conn->ssl_config.verifyhost' value. */ + if(SSL_CONN_CONFIG(verifyhost)) { + failf(data, + "\tsubject alt name(s) or common name do not match \"%s\"\n", + dispname); + return CURLE_PEER_FAILED_VERIFICATION; + } + else { + infof(data, + "\tsubject alt name(s) and/or common name do not match \"%s\"\n", + dispname); + return CURLE_OK; + } +#endif + } +#if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */ + else if(ASN_NO_SIGNER_E == detail) { + if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "\tCA signer not available for verification\n"); + return CURLE_SSL_CACERT_BADFILE; + } + else { + /* Just continue with a warning if no strict certificate + verification is required. */ + infof(data, "CA signer not available for verification, " + "continuing anyway\n"); + } + } +#endif + else { + failf(data, "SSL_connect failed with error %d: %s", detail, + ERR_error_string(detail, error_buffer)); + return CURLE_SSL_CONNECT_ERROR; + } + } + + if(pinnedpubkey) { +#ifdef KEEP_PEER_CERT + X509 *x509; + const char *x509_der; + int x509_der_len; struct Curl_X509certificate x509_parsed; struct Curl_asn1Element *pubkey; - CURLcode result; - + CURLcode result; + x509 = SSL_get_peer_certificate(backend->handle); - if(!x509) { - failf(data, "SSL: failed retrieving server certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - x509_der = (const char *)wolfSSL_X509_get_der(x509, &x509_der_len); - if(!x509_der) { - failf(data, "SSL: failed retrieving ASN.1 server certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - memset(&x509_parsed, 0, sizeof(x509_parsed)); - if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - pubkey = &x509_parsed.subjectPublicKeyInfo; - if(!pubkey->header || pubkey->end <= pubkey->header) { - failf(data, "SSL: failed retrieving public key from server certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - result = Curl_pin_peer_pubkey(data, - pinnedpubkey, - (const unsigned char *)pubkey->header, - (size_t)(pubkey->end - pubkey->header)); - if(result) { - failf(data, "SSL: public key does not match pinned public key!"); - return result; - } -#else - failf(data, "Library lacks pinning support built-in"); - return CURLE_NOT_BUILT_IN; -#endif - } - -#ifdef HAVE_ALPN - if(conn->bits.tls_enable_alpn) { - int rc; - char *protocol = NULL; - unsigned short protocol_len = 0; - + if(!x509) { + failf(data, "SSL: failed retrieving server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + x509_der = (const char *)wolfSSL_X509_get_der(x509, &x509_der_len); + if(!x509_der) { + failf(data, "SSL: failed retrieving ASN.1 server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + memset(&x509_parsed, 0, sizeof(x509_parsed)); + if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + pubkey = &x509_parsed.subjectPublicKeyInfo; + if(!pubkey->header || pubkey->end <= pubkey->header) { + failf(data, "SSL: failed retrieving public key from server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + result = Curl_pin_peer_pubkey(data, + pinnedpubkey, + (const unsigned char *)pubkey->header, + (size_t)(pubkey->end - pubkey->header)); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } +#else + failf(data, "Library lacks pinning support built-in"); + return CURLE_NOT_BUILT_IN; +#endif + } + +#ifdef HAVE_ALPN + if(conn->bits.tls_enable_alpn) { + int rc; + char *protocol = NULL; + unsigned short protocol_len = 0; + rc = wolfSSL_ALPN_GetProtocol(backend->handle, &protocol, &protocol_len); - - if(rc == SSL_SUCCESS) { - infof(data, "ALPN, server accepted to use %.*s\n", protocol_len, - protocol); - - if(protocol_len == ALPN_HTTP_1_1_LENGTH && - !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) - conn->negnpn = CURL_HTTP_VERSION_1_1; -#ifdef USE_NGHTTP2 - else if(data->set.httpversion >= CURL_HTTP_VERSION_2 && - protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) - conn->negnpn = CURL_HTTP_VERSION_2; -#endif - else - infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len, - protocol); - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); - } - else if(rc == SSL_ALPN_NOT_FOUND) - infof(data, "ALPN, server did not agree to a protocol\n"); - else { - failf(data, "ALPN, failure getting protocol, error %d", rc); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif /* HAVE_ALPN */ - - connssl->connecting_state = ssl_connect_3; -#if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) - infof(data, "SSL connection using %s / %s\n", + + if(rc == SSL_SUCCESS) { + infof(data, "ALPN, server accepted to use %.*s\n", protocol_len, + protocol); + + if(protocol_len == ALPN_HTTP_1_1_LENGTH && + !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) + conn->negnpn = CURL_HTTP_VERSION_1_1; +#ifdef USE_NGHTTP2 + else if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN && + !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID, + NGHTTP2_PROTO_VERSION_ID_LEN)) + conn->negnpn = CURL_HTTP_VERSION_2; +#endif + else + infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len, + protocol); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } + else if(rc == SSL_ALPN_NOT_FOUND) + infof(data, "ALPN, server did not agree to a protocol\n"); + else { + failf(data, "ALPN, failure getting protocol, error %d", rc); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* HAVE_ALPN */ + + connssl->connecting_state = ssl_connect_3; +#if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) + infof(data, "SSL connection using %s / %s\n", wolfSSL_get_version(backend->handle), wolfSSL_get_cipher_name(backend->handle)); -#else - infof(data, "SSL connected\n"); -#endif - - return CURLE_OK; -} - - -static CURLcode -wolfssl_connect_step3(struct connectdata *conn, - int sockindex) -{ - CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; +#else + infof(data, "SSL connected\n"); +#endif + + return CURLE_OK; +} + + +static CURLcode +wolfssl_connect_step3(struct connectdata *conn, + int sockindex) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - if(SSL_SET_OPTION(primary.sessionid)) { - bool incache; - SSL_SESSION *our_ssl_sessionid; - void *old_ssl_sessionid = NULL; - + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + SSL_SESSION *our_ssl_sessionid; + void *old_ssl_sessionid = NULL; + our_ssl_sessionid = SSL_get_session(backend->handle); - - Curl_ssl_sessionid_lock(conn); - incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, - sockindex)); - if(incache) { - if(old_ssl_sessionid != our_ssl_sessionid) { - infof(data, "old SSL session ID is stale, removing\n"); - Curl_ssl_delsessionid(conn, old_ssl_sessionid); - incache = FALSE; - } - } - - if(!incache) { - result = Curl_ssl_addsessionid(conn, our_ssl_sessionid, - 0 /* unknown size */, sockindex); - if(result) { - Curl_ssl_sessionid_unlock(conn); - failf(data, "failed to store ssl session"); - return result; - } - } - Curl_ssl_sessionid_unlock(conn); - } - - connssl->connecting_state = ssl_connect_done; - - return result; -} - - -static ssize_t wolfssl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, + sockindex)); + if(incache) { + if(old_ssl_sessionid != our_ssl_sessionid) { + infof(data, "old SSL session ID is stale, removing\n"); + Curl_ssl_delsessionid(conn, old_ssl_sessionid); + incache = FALSE; + } + } + + if(!incache) { + result = Curl_ssl_addsessionid(conn, our_ssl_sessionid, + 0 /* unknown size */, sockindex); + if(result) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "failed to store ssl session"); + return result; + } + } + Curl_ssl_sessionid_unlock(conn); + } + + connssl->connecting_state = ssl_connect_done; + + return result; +} + + +static ssize_t wolfssl_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; int rc = SSL_write(backend->handle, mem, memlen); - - if(rc < 0) { + + if(rc < 0) { int err = SSL_get_error(backend->handle, rc); - - switch(err) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - /* there's data pending, re-invoke SSL_write() */ - *curlcode = CURLE_AGAIN; - return -1; - default: - failf(conn->data, "SSL write: %s, errno %d", - ERR_error_string(err, error_buffer), - SOCKERRNO); - *curlcode = CURLE_SEND_ERROR; - return -1; - } - } - return rc; -} - -static void Curl_wolfssl_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + switch(err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_write() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, "SSL write: %s, errno %d", + ERR_error_string(err, error_buffer), + SOCKERRNO); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + } + return rc; +} + +static void Curl_wolfssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - + if(backend->handle) { (void)SSL_shutdown(backend->handle); SSL_free(backend->handle); backend->handle = NULL; - } + } if(backend->ctx) { SSL_CTX_free(backend->ctx); backend->ctx = NULL; - } -} - -static ssize_t wolfssl_recv(struct connectdata *conn, + } +} + +static ssize_t wolfssl_recv(struct connectdata *conn, int num, char *buf, size_t buffersize, CURLcode *curlcode) -{ - struct ssl_connect_data *connssl = &conn->ssl[num]; +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; struct ssl_backend_data *backend = connssl->backend; - char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; int nread = SSL_read(backend->handle, buf, buffsize); - - if(nread < 0) { + + if(nread < 0) { int err = SSL_get_error(backend->handle, nread); - - switch(err) { - case SSL_ERROR_ZERO_RETURN: /* no more data */ - break; - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - /* there's data pending, re-invoke SSL_read() */ - *curlcode = CURLE_AGAIN; - return -1; - default: - failf(conn->data, "SSL read: %s, errno %d", - ERR_error_string(err, error_buffer), - SOCKERRNO); - *curlcode = CURLE_RECV_ERROR; - return -1; - } - } - return nread; -} - - -static void Curl_wolfssl_session_free(void *ptr) -{ - (void)ptr; - /* wolfSSL reuses sessions on own, no free */ -} - - -static size_t Curl_wolfssl_version(char *buffer, size_t size) -{ -#if LIBWOLFSSL_VERSION_HEX >= 0x03006000 - return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version()); -#elif defined(WOLFSSL_VERSION) - return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION); -#endif -} - - -static int Curl_wolfssl_init(void) -{ + + switch(err) { + case SSL_ERROR_ZERO_RETURN: /* no more data */ + break; + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_read() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, "SSL read: %s, errno %d", + ERR_error_string(err, error_buffer), + SOCKERRNO); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + } + return nread; +} + + +static void Curl_wolfssl_session_free(void *ptr) +{ + (void)ptr; + /* wolfSSL reuses sessions on own, no free */ +} + + +static size_t Curl_wolfssl_version(char *buffer, size_t size) +{ +#if LIBWOLFSSL_VERSION_HEX >= 0x03006000 + return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version()); +#elif defined(WOLFSSL_VERSION) + return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION); +#endif +} + + +static int Curl_wolfssl_init(void) +{ #ifdef OPENSSL_EXTRA Curl_tls_keylog_open(); #endif - return (wolfSSL_Init() == SSL_SUCCESS); -} - - -static void Curl_wolfssl_cleanup(void) -{ - wolfSSL_Cleanup(); + return (wolfSSL_Init() == SSL_SUCCESS); +} + + +static void Curl_wolfssl_cleanup(void) +{ + wolfSSL_Cleanup(); #ifdef OPENSSL_EXTRA Curl_tls_keylog_close(); #endif -} - - +} + + static bool Curl_wolfssl_data_pending(const struct connectdata *conn, int connindex) -{ - const struct ssl_connect_data *connssl = &conn->ssl[connindex]; +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; struct ssl_backend_data *backend = connssl->backend; if(backend->handle) /* SSL is in use */ return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE; - else - return FALSE; -} - - -/* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ -static int Curl_wolfssl_shutdown(struct connectdata *conn, int sockindex) -{ - int retval = 0; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + else + return FALSE; +} + + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +static int Curl_wolfssl_shutdown(struct connectdata *conn, int sockindex) +{ + int retval = 0; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - + if(backend->handle) { SSL_free(backend->handle); backend->handle = NULL; - } - return retval; -} - - -static CURLcode -wolfssl_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode result; - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1 == connssl->connecting_state) { - /* Find out how much more time we're allowed */ + } + return retval; +} + + +static CURLcode +wolfssl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - result = wolfssl_connect_step1(conn, sockindex); - if(result) - return result; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - /* check allowed time left */ + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = wolfssl_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading - || connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing == - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading == - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, - nonblocking?0:timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if - * this connection is part of a multi handle and this loop would - * execute again. This permits the owner of a multi handle to - * abort a connection attempt before step2 has completed while - * ensuring that a client using select() or epoll() will always - * have a valid fdset to wait on. - */ - result = wolfssl_connect_step2(conn, sockindex); - if(result || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return result; - } /* repeat step2 until all transactions are done. */ - - if(ssl_connect_3 == connssl->connecting_state) { - result = wolfssl_connect_step3(conn, sockindex); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = wolfssl_recv; - conn->send[sockindex] = wolfssl_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - - -static CURLcode Curl_wolfssl_connect_nonblocking(struct connectdata *conn, - int sockindex, bool *done) -{ - return wolfssl_connect_common(conn, sockindex, TRUE, done); -} - - -static CURLcode Curl_wolfssl_connect(struct connectdata *conn, int sockindex) -{ - CURLcode result; - bool done = FALSE; - - result = wolfssl_connect_common(conn, sockindex, FALSE, &done); - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -static CURLcode Curl_wolfssl_random(struct Curl_easy *data, - unsigned char *entropy, size_t length) -{ + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading + || connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if + * this connection is part of a multi handle and this loop would + * execute again. This permits the owner of a multi handle to + * abort a connection attempt before step2 has completed while + * ensuring that a client using select() or epoll() will always + * have a valid fdset to wait on. + */ + result = wolfssl_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + result = wolfssl_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = wolfssl_recv; + conn->send[sockindex] = wolfssl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + + +static CURLcode Curl_wolfssl_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return wolfssl_connect_common(conn, sockindex, TRUE, done); +} + + +static CURLcode Curl_wolfssl_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = wolfssl_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static CURLcode Curl_wolfssl_random(struct Curl_easy *data, + unsigned char *entropy, size_t length) +{ WC_RNG rng; - (void)data; - if(wc_InitRng(&rng)) - return CURLE_FAILED_INIT; - if(length > UINT_MAX) - return CURLE_FAILED_INIT; - if(wc_RNG_GenerateBlock(&rng, entropy, (unsigned)length)) - return CURLE_FAILED_INIT; - if(wc_FreeRng(&rng)) - return CURLE_FAILED_INIT; - return CURLE_OK; -} - -static CURLcode Curl_wolfssl_sha256sum(const unsigned char *tmp, /* input */ + (void)data; + if(wc_InitRng(&rng)) + return CURLE_FAILED_INIT; + if(length > UINT_MAX) + return CURLE_FAILED_INIT; + if(wc_RNG_GenerateBlock(&rng, entropy, (unsigned)length)) + return CURLE_FAILED_INIT; + if(wc_FreeRng(&rng)) + return CURLE_FAILED_INIT; + return CURLE_OK; +} + +static CURLcode Curl_wolfssl_sha256sum(const unsigned char *tmp, /* input */ size_t tmplen, unsigned char *sha256sum /* output */, size_t unused) -{ +{ wc_Sha256 SHA256pw; - (void)unused; - wc_InitSha256(&SHA256pw); - wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen); - wc_Sha256Final(&SHA256pw, sha256sum); - return CURLE_OK; -} - -static void *Curl_wolfssl_get_internals(struct ssl_connect_data *connssl, + (void)unused; + wc_InitSha256(&SHA256pw); + wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen); + wc_Sha256Final(&SHA256pw, sha256sum); + return CURLE_OK; +} + +static void *Curl_wolfssl_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) -{ +{ struct ssl_backend_data *backend = connssl->backend; - (void)info; + (void)info; return backend->handle; -} - -const struct Curl_ssl Curl_ssl_wolfssl = { - { CURLSSLBACKEND_WOLFSSL, "WolfSSL" }, /* info */ - -#ifdef KEEP_PEER_CERT - SSLSUPP_PINNEDPUBKEY | -#endif - SSLSUPP_SSL_CTX, - - sizeof(struct ssl_backend_data), - - Curl_wolfssl_init, /* init */ - Curl_wolfssl_cleanup, /* cleanup */ - Curl_wolfssl_version, /* version */ - Curl_none_check_cxn, /* check_cxn */ - Curl_wolfssl_shutdown, /* shutdown */ - Curl_wolfssl_data_pending, /* data_pending */ - Curl_wolfssl_random, /* random */ - Curl_none_cert_status_request, /* cert_status_request */ - Curl_wolfssl_connect, /* connect */ - Curl_wolfssl_connect_nonblocking, /* connect_nonblocking */ - Curl_wolfssl_get_internals, /* get_internals */ - Curl_wolfssl_close, /* close_one */ - Curl_none_close_all, /* close_all */ - Curl_wolfssl_session_free, /* session_free */ - Curl_none_set_engine, /* set_engine */ - Curl_none_set_engine_default, /* set_engine_default */ - Curl_none_engines_list, /* engines_list */ - Curl_none_false_start, /* false_start */ - Curl_none_md5sum, /* md5sum */ - Curl_wolfssl_sha256sum /* sha256sum */ -}; - -#endif +} + +const struct Curl_ssl Curl_ssl_wolfssl = { + { CURLSSLBACKEND_WOLFSSL, "WolfSSL" }, /* info */ + +#ifdef KEEP_PEER_CERT + SSLSUPP_PINNEDPUBKEY | +#endif + SSLSUPP_SSL_CTX, + + sizeof(struct ssl_backend_data), + + Curl_wolfssl_init, /* init */ + Curl_wolfssl_cleanup, /* cleanup */ + Curl_wolfssl_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_wolfssl_shutdown, /* shutdown */ + Curl_wolfssl_data_pending, /* data_pending */ + Curl_wolfssl_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_wolfssl_connect, /* connect */ + Curl_wolfssl_connect_nonblocking, /* connect_nonblocking */ + Curl_wolfssl_get_internals, /* get_internals */ + Curl_wolfssl_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_wolfssl_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + Curl_wolfssl_sha256sum /* sha256sum */ +}; + +#endif diff --git a/contrib/libs/curl/lib/vtls/wolfssl.h b/contrib/libs/curl/lib/vtls/wolfssl.h index b2d7fb53c1..d411e6913e 100644 --- a/contrib/libs/curl/lib/vtls/wolfssl.h +++ b/contrib/libs/curl/lib/vtls/wolfssl.h @@ -1,31 +1,31 @@ -#ifndef HEADER_CURL_WOLFSSL_H -#define HEADER_CURL_WOLFSSL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * +#ifndef HEADER_CURL_WOLFSSL_H +#define HEADER_CURL_WOLFSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_WOLFSSL - -extern const struct Curl_ssl Curl_ssl_wolfssl; - -#endif /* USE_WOLFSSL */ -#endif /* HEADER_CURL_WOLFSSL_H */ + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_WOLFSSL + +extern const struct Curl_ssl Curl_ssl_wolfssl; + +#endif /* USE_WOLFSSL */ +#endif /* HEADER_CURL_WOLFSSL_H */ diff --git a/contrib/libs/curl/lib/wildcard.c b/contrib/libs/curl/lib/wildcard.c index 068cf0da23..105bcce4ed 100644 --- a/contrib/libs/curl/lib/wildcard.c +++ b/contrib/libs/curl/lib/wildcard.c @@ -22,8 +22,8 @@ #include "curl_setup.h" -#ifndef CURL_DISABLE_FTP - +#ifndef CURL_DISABLE_FTP + #include "wildcard.h" #include "llist.h" #include "fileinfo.h" @@ -69,5 +69,5 @@ void Curl_wildcard_dtor(struct WildcardData *wc) wc->customptr = NULL; wc->state = CURLWC_INIT; } - -#endif /* if disabled */ + +#endif /* if disabled */ diff --git a/contrib/libs/curl/lib/wildcard.h b/contrib/libs/curl/lib/wildcard.h index aad3ac4a32..081be9ed93 100644 --- a/contrib/libs/curl/lib/wildcard.h +++ b/contrib/libs/curl/lib/wildcard.h @@ -22,9 +22,9 @@ * ***************************************************************************/ -#include "curl_setup.h" +#include "curl_setup.h" -#ifndef CURL_DISABLE_FTP +#ifndef CURL_DISABLE_FTP #include "llist.h" /* list of wildcard process states */ @@ -59,9 +59,9 @@ void Curl_wildcard_dtor(struct WildcardData *wc); struct Curl_easy; -#else -/* FTP is disabled */ -#define Curl_wildcard_dtor(x) -#endif - +#else +/* FTP is disabled */ +#define Curl_wildcard_dtor(x) +#endif + #endif /* HEADER_CURL_WILDCARD_H */ diff --git a/contrib/libs/curl/lib/x509asn1.c b/contrib/libs/curl/lib/x509asn1.c index b89a02b9d0..d7cf9eb2af 100644 --- a/contrib/libs/curl/lib/x509asn1.c +++ b/contrib/libs/curl/lib/x509asn1.c @@ -23,7 +23,7 @@ #include "curl_setup.h" #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ - defined(USE_WOLFSSL) || defined(USE_SCHANNEL) + defined(USE_WOLFSSL) || defined(USE_SCHANNEL) #include <curl/curl.h> #include "urldata.h" @@ -120,7 +120,7 @@ static const char *getASN1Element(struct Curl_asn1Element *elem, if an error occurs. */ if(!beg || !end || beg >= end || !*beg || (size_t)(end - beg) > CURL_ASN1_MAX) - return NULL; + return NULL; /* Process header byte. */ elem->header = beg; @@ -129,12 +129,12 @@ static const char *getASN1Element(struct Curl_asn1Element *elem, elem->class = (b >> 6) & 3; b &= 0x1F; if(b == 0x1F) - return NULL; /* Long tag values not supported here. */ + return NULL; /* Long tag values not supported here. */ elem->tag = b; /* Process length. */ if(beg >= end) - return NULL; + return NULL; b = (unsigned char) *beg++; if(!(b & 0x80)) len = b; @@ -142,40 +142,40 @@ static const char *getASN1Element(struct Curl_asn1Element *elem, /* Unspecified length. Since we have all the data, we can determine the effective length by skipping element until an end element is found. */ if(!elem->constructed) - return NULL; + return NULL; elem->beg = beg; while(beg < end && *beg) { beg = getASN1Element(&lelem, beg, end); if(!beg) - return NULL; + return NULL; } if(beg >= end) - return NULL; + return NULL; elem->end = beg; return beg + 1; } else if((unsigned)b > (size_t)(end - beg)) - return NULL; /* Does not fit in source. */ + return NULL; /* Does not fit in source. */ else { /* Get long length. */ len = 0; do { if(len & 0xFF000000L) - return NULL; /* Lengths > 32 bits are not supported. */ + return NULL; /* Lengths > 32 bits are not supported. */ len = (len << 8) | (unsigned char) *beg++; } while(--b); } if(len > (size_t)(end - beg)) - return NULL; /* Element data does not fit in source. */ + return NULL; /* Element data does not fit in source. */ elem->beg = beg; elem->end = beg + len; return elem->end; } -/* - * Search the null terminated OID or OID identifier in local table. - * Return the table entry pointer or NULL if not found. - */ +/* + * Search the null terminated OID or OID identifier in local table. + * Return the table entry pointer or NULL if not found. + */ static const struct Curl_OID *searchOID(const char *oid) { const struct Curl_OID *op; @@ -183,26 +183,26 @@ static const struct Curl_OID *searchOID(const char *oid) if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid)) return op; - return NULL; + return NULL; } -/* - * Convert an ASN.1 Boolean value into its string representation. Return the - * dynamically allocated string, or NULL if source is not an ASN.1 Boolean - * value. - */ - +/* + * Convert an ASN.1 Boolean value into its string representation. Return the + * dynamically allocated string, or NULL if source is not an ASN.1 Boolean + * value. + */ + static const char *bool2str(const char *beg, const char *end) { if(end - beg != 1) - return NULL; + return NULL; return strdup(*beg? "TRUE": "FALSE"); } -/* - * Convert an ASN.1 octet string to a printable string. - * Return the dynamically allocated string, or NULL if an error occurs. - */ +/* + * Convert an ASN.1 octet string to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *octet2str(const char *beg, const char *end) { size_t n = end - beg; @@ -223,22 +223,22 @@ static const char *bit2str(const char *beg, const char *end) Return the dynamically allocated string, or NULL if an error occurs. */ if(++beg > end) - return NULL; + return NULL; return octet2str(beg, end); } -/* - * Convert an ASN.1 integer value into its string representation. - * Return the dynamically allocated string, or NULL if source is not an - * ASN.1 integer value. - */ +/* + * Convert an ASN.1 integer value into its string representation. + * Return the dynamically allocated string, or NULL if source is not an + * ASN.1 integer value. + */ static const char *int2str(const char *beg, const char *end) { unsigned long val = 0; size_t n = end - beg; if(!n) - return NULL; + return NULL; if(n > 4) return octet2str(beg, end); @@ -253,13 +253,13 @@ static const char *int2str(const char *beg, const char *end) return curl_maprintf("%s%lx", val >= 10? "0x": "", val); } -/* - * Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the - * destination buffer dynamically. The allocation size will normally be too - * large: this is to avoid buffer overflows. - * Terminate the string with a nul byte and return the converted - * string length. - */ +/* + * Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the + * destination buffer dynamically. The allocation size will normally be too + * large: this is to avoid buffer overflows. + * Terminate the string with a nul byte and return the converted + * string length. + */ static ssize_t utf8asn1str(char **to, int type, const char *from, const char *end) { @@ -268,7 +268,7 @@ utf8asn1str(char **to, int type, const char *from, const char *end) size_t outlength; char *buf; - *to = NULL; + *to = NULL; switch(type) { case CURL_ASN1_BMP_STRING: size = 2; @@ -303,9 +303,9 @@ utf8asn1str(char **to, int type, const char *from, const char *end) } else { for(outlength = 0; from < end;) { - int charsize; - unsigned int wc; - + int charsize; + unsigned int wc; + wc = 0; switch(size) { case 4: @@ -347,49 +347,49 @@ utf8asn1str(char **to, int type, const char *from, const char *end) return outlength; } -/* - * Convert an ASN.1 String into its UTF-8 string representation. - * Return the dynamically allocated string, or NULL if an error occurs. - */ +/* + * Convert an ASN.1 String into its UTF-8 string representation. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *string2str(int type, const char *beg, const char *end) { char *buf; if(utf8asn1str(&buf, type, beg, end) < 0) - return NULL; + return NULL; return buf; } -/* - * Decimal ASCII encode unsigned integer `x' into the buflen sized buffer at - * buf. Return the total number of encoded digits, even if larger than - * `buflen'. - */ -static size_t encodeUint(char *buf, size_t buflen, unsigned int x) +/* + * Decimal ASCII encode unsigned integer `x' into the buflen sized buffer at + * buf. Return the total number of encoded digits, even if larger than + * `buflen'. + */ +static size_t encodeUint(char *buf, size_t buflen, unsigned int x) { - size_t i = 0; + size_t i = 0; unsigned int y = x / 10; if(y) { - i = encodeUint(buf, buflen, y); + i = encodeUint(buf, buflen, y); x -= y * 10; } - if(i < buflen) + if(i < buflen) buf[i] = (char) ('0' + x); i++; - if(i < buflen) + if(i < buflen) buf[i] = '\0'; /* Store a terminator if possible. */ return i; } -/* - * Convert an ASN.1 OID into its dotted string representation. - * Store the result in th `n'-byte buffer at `buf'. - * Return the converted string length, or 0 on errors. - */ -static size_t encodeOID(char *buf, size_t buflen, - const char *beg, const char *end) +/* + * Convert an ASN.1 OID into its dotted string representation. + * Store the result in th `n'-byte buffer at `buf'. + * Return the converted string length, or 0 on errors. + */ +static size_t encodeOID(char *buf, size_t buflen, + const char *beg, const char *end) { - size_t i; + size_t i; unsigned int x; unsigned int y; @@ -397,52 +397,52 @@ static size_t encodeOID(char *buf, size_t buflen, y = *(const unsigned char *) beg++; x = y / 40; y -= x * 40; - i = encodeUint(buf, buflen, x); - if(i < buflen) + i = encodeUint(buf, buflen, x); + if(i < buflen) buf[i] = '.'; i++; - if(i >= buflen) - i += encodeUint(NULL, 0, y); - else - i += encodeUint(buf + i, buflen - i, y); + if(i >= buflen) + i += encodeUint(NULL, 0, y); + else + i += encodeUint(buf + i, buflen - i, y); /* Process the trailing numbers. */ while(beg < end) { - if(i < buflen) + if(i < buflen) buf[i] = '.'; i++; x = 0; do { if(x & 0xFF000000) - return 0; + return 0; y = *(const unsigned char *) beg++; x = (x << 7) | (y & 0x7F); } while(y & 0x80); - if(i >= buflen) - i += encodeUint(NULL, 0, x); - else - i += encodeUint(buf + i, buflen - i, x); + if(i >= buflen) + i += encodeUint(NULL, 0, x); + else + i += encodeUint(buf + i, buflen - i, x); } - if(i < buflen) + if(i < buflen) buf[i] = '\0'; return i; } -/* - * Convert an ASN.1 OID into its dotted or symbolic string representation. - * Return the dynamically allocated string, or NULL if an error occurs. - */ - +/* + * Convert an ASN.1 OID into its dotted or symbolic string representation. + * Return the dynamically allocated string, or NULL if an error occurs. + */ + static const char *OID2str(const char *beg, const char *end, bool symbolic) { - char *buf = NULL; + char *buf = NULL; if(beg < end) { - size_t buflen = encodeOID(NULL, 0, beg, end); - if(buflen) { - buf = malloc(buflen + 1); /* one extra for the zero byte */ + size_t buflen = encodeOID(NULL, 0, beg, end); + if(buflen) { + buf = malloc(buflen + 1); /* one extra for the zero byte */ if(buf) { - encodeOID(buf, buflen, beg, end); - buf[buflen] = '\0'; + encodeOID(buf, buflen, beg, end); + buf[buflen] = '\0'; if(symbolic) { const struct Curl_OID *op = searchOID(buf); @@ -485,7 +485,7 @@ static const char *GTime2str(const char *beg, const char *end) sec2 = fracp[-1]; break; default: - return NULL; + return NULL; } /* Scan for timezone, measure fractional seconds. */ @@ -521,10 +521,10 @@ static const char *GTime2str(const char *beg, const char *end) sep, tzl, tzp); } -/* - * Convert an ASN.1 UTC time to a printable string. - * Return the dynamically allocated string, or NULL if an error occurs. - */ +/* + * Convert an ASN.1 UTC time to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *UTime2str(const char *beg, const char *end) { const char *tzp; @@ -541,12 +541,12 @@ static const char *UTime2str(const char *beg, const char *end) case 2: break; default: - return NULL; + return NULL; } /* Process timezone. */ if(tzp >= end) - return NULL; + return NULL; if(*tzp == 'Z') { tzp = "GMT"; end = tzp + 3; @@ -561,14 +561,14 @@ static const char *UTime2str(const char *beg, const char *end) tzl, tzp); } -/* - * Convert an ASN.1 element to a printable string. - * Return the dynamically allocated string, or NULL if an error occurs. - */ +/* + * Convert an ASN.1 element to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *ASN1tostr(struct Curl_asn1Element *elem, int type) { if(elem->constructed) - return NULL; /* No conversion of structured elements. */ + return NULL; /* No conversion of structured elements. */ if(!type) type = elem->tag; /* Type not forced: use element tag as type. */ @@ -602,13 +602,13 @@ static const char *ASN1tostr(struct Curl_asn1Element *elem, int type) return string2str(type, elem->beg, elem->end); } - return NULL; /* Unsupported. */ + return NULL; /* Unsupported. */ } -/* - * ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at - * `buf'. Return the total string length, even if larger than `buflen'. - */ +/* + * ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at + * `buf'. Return the total string length, even if larger than `buflen'. + */ static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn) { struct Curl_asn1Element rdn; @@ -644,7 +644,7 @@ static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn) for(p3 = str; isupper(*p3); p3++) ; for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) { - if(l < buflen) + if(l < buflen) buf[l] = *p3; l++; } @@ -652,14 +652,14 @@ static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn) /* Encode attribute name. */ for(p3 = str; *p3; p3++) { - if(l < buflen) + if(l < buflen) buf[l] = *p3; l++; } free((char *) str); /* Generate equal sign. */ - if(l < buflen) + if(l < buflen) buf[l] = '='; l++; @@ -668,7 +668,7 @@ static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn) if(!str) return -1; for(p3 = str; *p3; p3++) { - if(l < buflen) + if(l < buflen) buf[l] = *p3; l++; } @@ -679,29 +679,29 @@ static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn) return l; } -/* - * Convert an ASN.1 distinguished name into a printable string. - * Return the dynamically allocated string, or NULL if an error occurs. - */ +/* + * Convert an ASN.1 distinguished name into a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ static const char *DNtostr(struct Curl_asn1Element *dn) { - char *buf = NULL; - ssize_t buflen = encodeDN(NULL, 0, dn); + char *buf = NULL; + ssize_t buflen = encodeDN(NULL, 0, dn); - if(buflen >= 0) { - buf = malloc(buflen + 1); + if(buflen >= 0) { + buf = malloc(buflen + 1); if(buf) { - encodeDN(buf, buflen + 1, dn); - buf[buflen] = '\0'; + encodeDN(buf, buflen + 1, dn); + buf[buflen] = '\0'; } } - return buf; + return buf; } /* - * ASN.1 parse an X509 certificate into structure subfields. - * Syntax is assumed to have already been checked by the SSL backend. - * See RFC 5280. + * ASN.1 parse an X509 certificate into structure subfields. + * Syntax is assumed to have already been checked by the SSL backend. + * See RFC 5280. */ int Curl_parseX509(struct Curl_X509certificate *cert, const char *beg, const char *end) @@ -817,11 +817,11 @@ int Curl_parseX509(struct Curl_X509certificate *cert, return 0; } - -/* - * Copy at most 64-characters, terminate with a newline and returns the - * effective number of stored characters. - */ + +/* + * Copy at most 64-characters, terminate with a newline and returns the + * effective number of stored characters. + */ static size_t copySubstring(char *to, const char *from) { size_t i; @@ -886,9 +886,9 @@ static void do_pubkey(struct Curl_easy *data, int certnum, return; if(strcasecompare(algo, "rsaEncryption")) { - const char *q; - unsigned long len; - + const char *q; + unsigned long len; + p = getASN1Element(&elem, pk.beg, pk.end); if(!p) return; @@ -897,11 +897,11 @@ static void do_pubkey(struct Curl_easy *data, int certnum, for(q = elem.beg; !*q && q < elem.end; q++) ; len = (unsigned long)((elem.end - q) * 8); - if(len) { - unsigned int i; + if(len) { + unsigned int i; for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1) len--; - } + } if(len > 32) elem.beg = q; /* Strip leading zero bytes. */ if(!certnum) @@ -1104,7 +1104,7 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn, return CURLE_OK; } -#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */ +#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */ #if defined(USE_GSKIT) @@ -1121,15 +1121,15 @@ static const char *checkOID(const char *beg, const char *end, ccp = getASN1Element(&e, beg, end); if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER) - return NULL; + return NULL; p = OID2str(e.beg, e.end, FALSE); if(!p) - return NULL; + return NULL; matched = !strcmp(p, oid); free((char *) p); - return matched? ccp: NULL; + return matched? ccp: NULL; } CURLcode Curl_verifyhost(struct connectdata *conn, diff --git a/contrib/libs/curl/lib/x509asn1.h b/contrib/libs/curl/lib/x509asn1.h index fdc02f9352..849714492d 100644 --- a/contrib/libs/curl/lib/x509asn1.h +++ b/contrib/libs/curl/lib/x509asn1.h @@ -26,7 +26,7 @@ #include "curl_setup.h" #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ - defined(USE_WOLFSSL) || defined(USE_SCHANNEL) + defined(USE_WOLFSSL) || defined(USE_SCHANNEL) #include "urldata.h" @@ -129,5 +129,5 @@ CURLcode Curl_extract_certinfo(struct connectdata *conn, int certnum, const char *beg, const char *end); CURLcode Curl_verifyhost(struct connectdata *conn, const char *beg, const char *end); -#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */ +#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */ #endif /* HEADER_CURL_X509ASN1_H */ |