From 530102b3b16fdc6f008cdf312e5977a878f295db Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 10 Nov 2013 21:43:18 +0000 Subject: libcurl update git-svn-id: http://svn.miranda-ng.org/main/trunk@6864 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/FTPFileYM/curl/lib/http_digest.c | 139 ++++++++++++++++++------------- 1 file changed, 80 insertions(+), 59 deletions(-) (limited to 'plugins/FTPFileYM/curl/lib/http_digest.c') diff --git a/plugins/FTPFileYM/curl/lib/http_digest.c b/plugins/FTPFileYM/curl/lib/http_digest.c index f9f20d487f..f50f8033f9 100644 --- a/plugins/FTPFileYM/curl/lib/http_digest.c +++ b/plugins/FTPFileYM/curl/lib/http_digest.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -25,14 +25,13 @@ #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) #include "urldata.h" -#include "sendf.h" #include "rawstr.h" #include "curl_base64.h" #include "curl_md5.h" #include "http_digest.h" #include "strtok.h" -#include "url.h" /* for Curl_safefree() */ #include "curl_memory.h" +#include "sslgen.h" /* for Curl_rand() */ #include "non-ascii.h" /* included for Curl_convert_... prototypes */ #include "warnless.h" @@ -267,6 +266,38 @@ static void md5_to_ascii(unsigned char *source, /* 16 bytes */ snprintf((char *)&dest[i*2], 3, "%02x", source[i]); } +/* Perform quoted-string escaping as described in RFC2616 and its errata */ +static char *string_quoted(const char *source) +{ + char *dest, *d; + const char *s = source; + size_t n = 1; /* null terminator */ + + /* Calculate size needed */ + while(*s) { + ++n; + if(*s == '"' || *s == '\\') { + ++n; + } + ++s; + } + + dest = malloc(n); + if(dest) { + s = source; + d = dest; + while(*s) { + if(*s == '"' || *s == '\\') { + *d++ = '\\'; + } + *d++ = *s++; + } + *d = 0; + } + + return dest; +} + CURLcode Curl_output_digest(struct connectdata *conn, bool proxy, const unsigned char *request, @@ -278,16 +309,16 @@ CURLcode Curl_output_digest(struct connectdata *conn, unsigned char md5buf[16]; /* 16 bytes/128 bits */ unsigned char request_digest[33]; unsigned char *md5this; - unsigned char *ha1; + unsigned char ha1[33];/* 32 digits and 1 zero byte */ unsigned char ha2[33];/* 32 digits and 1 zero byte */ char cnoncebuf[33]; char *cnonce = NULL; size_t cnonce_sz = 0; char *tmp = NULL; - struct timeval now; - char **allocuserpwd; + size_t userlen; const char *userp; + char *userp_quoted; const char *passwdp; struct auth *authp; @@ -320,10 +351,7 @@ CURLcode Curl_output_digest(struct connectdata *conn, authp = &data->state.authhost; } - if(*allocuserpwd) { - Curl_safefree(*allocuserpwd); - *allocuserpwd = NULL; - } + Curl_safefree(*allocuserpwd); /* not set means empty */ if(!userp) @@ -342,10 +370,11 @@ CURLcode Curl_output_digest(struct connectdata *conn, d->nc = 1; if(!d->cnonce) { - /* Generate a cnonce */ - now = Curl_tvnow(); - snprintf(cnoncebuf, sizeof(cnoncebuf), "%32ld", - (long)now.tv_sec + now.tv_usec); + struct timeval now = Curl_tvnow(); + snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x", + Curl_rand(data), Curl_rand(data), + (unsigned int)now.tv_sec, + (unsigned int)now.tv_usec); rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), &cnonce, &cnonce_sz); @@ -372,12 +401,7 @@ CURLcode Curl_output_digest(struct connectdata *conn, CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ Curl_md5it(md5buf, md5this); - free(md5this); /* free this again */ - - ha1 = malloc(33); /* 32 digits and 1 zero byte */ - if(!ha1) - return CURLE_OUT_OF_MEMORY; - + Curl_safefree(md5this); md5_to_ascii(md5buf, ha1); if(d->algo == CURLDIGESTALGO_MD5SESS) { @@ -387,7 +411,7 @@ CURLcode Curl_output_digest(struct connectdata *conn, return CURLE_OUT_OF_MEMORY; CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */ Curl_md5it(md5buf, (unsigned char *)tmp); - free(tmp); /* free this again */ + Curl_safefree(tmp); md5_to_ascii(md5buf, ha1); } @@ -424,19 +448,21 @@ CURLcode Curl_output_digest(struct connectdata *conn, else md5this = (unsigned char *)aprintf("%s:%s", request, uripath); - if(!md5this) { - free(ha1); - return CURLE_OUT_OF_MEMORY; - } - if(d->qop && Curl_raw_equal(d->qop, "auth-int")) { - /* We don't support auth-int at the moment. I can't see a easy way to get - entity-body here */ - /* TODO: Append H(entity-body)*/ + /* We don't support auth-int for PUT or POST at the moment. + TODO: replace md5 of empty string with entity-body for PUT/POST */ + unsigned char *md5this2 = (unsigned char *) + aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e"); + Curl_safefree(md5this); + md5this = md5this2; } + + if(!md5this) + return CURLE_OUT_OF_MEMORY; + CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ Curl_md5it(md5buf, md5this); - free(md5this); /* free this again */ + Curl_safefree(md5this); md5_to_ascii(md5buf, ha2); if(d->qop) { @@ -454,20 +480,30 @@ CURLcode Curl_output_digest(struct connectdata *conn, d->nonce, ha2); } - free(ha1); if(!md5this) return CURLE_OUT_OF_MEMORY; CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ Curl_md5it(md5buf, md5this); - free(md5this); /* free this again */ + Curl_safefree(md5this); md5_to_ascii(md5buf, request_digest); /* for test case 64 (snooped from a Mozilla 1.3a request) Authorization: Digest username="testuser", realm="testrealm", \ nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca" + + Digest parameters are all quoted strings. Username which is provided by + the user will need double quotes and backslashes within it escaped. For + the other fields, this shouldn't be an issue. realm, nonce, and opaque + are copied as is from the server, escapes and all. cnonce is generated + with web-safe characters. uri is already percent encoded. nc is 8 hex + characters. algorithm and qop with standard values only contain web-safe + chracters. */ + userp_quoted = string_quoted(userp); + if(!userp_quoted) + return CURLE_OUT_OF_MEMORY; if(d->qop) { *allocuserpwd = @@ -481,7 +517,7 @@ CURLcode Curl_output_digest(struct connectdata *conn, "qop=%s, " "response=\"%s\"", proxy?"Proxy-":"", - userp, + userp_quoted, d->realm, d->nonce, uripath, /* this is the PATH part of the URL */ @@ -504,12 +540,13 @@ CURLcode Curl_output_digest(struct connectdata *conn, "uri=\"%s\", " "response=\"%s\"", proxy?"Proxy-":"", - userp, + userp_quoted, d->realm, d->nonce, uripath, /* this is the PATH part of the URL */ request_digest); } + Curl_safefree(userp_quoted); if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; @@ -533,10 +570,11 @@ CURLcode Curl_output_digest(struct connectdata *conn, } /* append CRLF + zero (3 bytes) to the userpwd header */ - tmp = realloc(*allocuserpwd, strlen(*allocuserpwd) + 3); + userlen = strlen(*allocuserpwd); + tmp = realloc(*allocuserpwd, userlen + 3); if(!tmp) return CURLE_OUT_OF_MEMORY; - strcat(tmp, "\r\n"); + strcpy(&tmp[userlen], "\r\n"); /* append the data */ *allocuserpwd = tmp; return CURLE_OK; @@ -544,29 +582,12 @@ CURLcode Curl_output_digest(struct connectdata *conn, static void digest_cleanup_one(struct digestdata *d) { - if(d->nonce) - free(d->nonce); - d->nonce = NULL; - - if(d->cnonce) - free(d->cnonce); - d->cnonce = NULL; - - if(d->realm) - free(d->realm); - d->realm = NULL; - - if(d->opaque) - free(d->opaque); - d->opaque = NULL; - - if(d->qop) - free(d->qop); - d->qop = NULL; - - if(d->algorithm) - free(d->algorithm); - d->algorithm = NULL; + Curl_safefree(d->nonce); + Curl_safefree(d->cnonce); + Curl_safefree(d->realm); + Curl_safefree(d->opaque); + Curl_safefree(d->qop); + Curl_safefree(d->algorithm); d->nc = 0; d->algo = CURLDIGESTALGO_MD5; /* default algorithm */ -- cgit v1.2.3