mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
base64: fix Curl_base64_encode and Curl_base64_decode interfaces
Previous interfaces for these libcurl internal functions did not allow to tell apart a legitimate zero size result from an error condition. These functions now return a CURLcode indicating function success or otherwise specific error. Output size is returned using a pointer argument. All usage of these two functions, and others closely related, has been adapted to the new interfaces. Relative error and OOM handling adapted or added where missing. Unit test 1302 also adapted.
This commit is contained in:
parent
cce6508242
commit
fd00b382b2
62
lib/base64.c
62
lib/base64.c
@ -68,12 +68,19 @@ static void decodeQuantum(unsigned char *dest, const char *src)
|
|||||||
/*
|
/*
|
||||||
* Curl_base64_decode()
|
* Curl_base64_decode()
|
||||||
*
|
*
|
||||||
* Given a base64 string at src, decode it and return an allocated memory in
|
* Given a base64 NUL-terminated string at src, decode it and return a
|
||||||
* the *outptr. Returns the length of the decoded data.
|
* pointer in *outptr to a newly allocated memory area holding decoded
|
||||||
|
* data. Size of decoded data is returned in variable pointed by outlen.
|
||||||
|
*
|
||||||
|
* Returns CURLE_OK on success, otherwise specific error code. Function
|
||||||
|
* output shall not be considered valid unless CURLE_OK is returned.
|
||||||
|
*
|
||||||
|
* When decoded data length is 0, returns NULL in *outptr.
|
||||||
*
|
*
|
||||||
* @unittest: 1302
|
* @unittest: 1302
|
||||||
*/
|
*/
|
||||||
size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
CURLcode Curl_base64_decode(const char *src,
|
||||||
|
unsigned char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
size_t equalsTerm = 0;
|
size_t equalsTerm = 0;
|
||||||
@ -84,6 +91,7 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
|||||||
unsigned char *newstr;
|
unsigned char *newstr;
|
||||||
|
|
||||||
*outptr = NULL;
|
*outptr = NULL;
|
||||||
|
*outlen = 0;
|
||||||
|
|
||||||
while((src[length] != '=') && src[length])
|
while((src[length] != '=') && src[length])
|
||||||
length++;
|
length++;
|
||||||
@ -97,7 +105,7 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
|||||||
|
|
||||||
/* Don't allocate a buffer if the decoded length is 0 */
|
/* Don't allocate a buffer if the decoded length is 0 */
|
||||||
if(numQuantums == 0)
|
if(numQuantums == 0)
|
||||||
return 0;
|
return CURLE_OK;
|
||||||
|
|
||||||
rawlen = (numQuantums * 3) - equalsTerm;
|
rawlen = (numQuantums * 3) - equalsTerm;
|
||||||
|
|
||||||
@ -105,7 +113,7 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
|||||||
(which may be partially thrown out) and the zero terminator. */
|
(which may be partially thrown out) and the zero terminator. */
|
||||||
newstr = malloc(rawlen+4);
|
newstr = malloc(rawlen+4);
|
||||||
if(!newstr)
|
if(!newstr)
|
||||||
return 0;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
*outptr = newstr;
|
*outptr = newstr;
|
||||||
|
|
||||||
@ -124,23 +132,34 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
|||||||
newstr[i] = lastQuantum[i];
|
newstr[i] = lastQuantum[i];
|
||||||
|
|
||||||
newstr[i] = '\0'; /* zero terminate */
|
newstr[i] = '\0'; /* zero terminate */
|
||||||
return rawlen;
|
|
||||||
|
*outlen = rawlen; /* return size of decoded data */
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_base64_encode()
|
* Curl_base64_encode()
|
||||||
*
|
*
|
||||||
* Returns the length of the newly created base64 string. The third argument
|
* Given a pointer to an input buffer and an input size, encode it and
|
||||||
* is a pointer to an allocated area holding the base64 data. If something
|
* return a pointer in *outptr to a newly allocated memory area holding
|
||||||
* went wrong, 0 is returned.
|
* encoded data. Size of encoded data is returned in variable pointed by
|
||||||
|
* outlen.
|
||||||
|
*
|
||||||
|
* Input length of 0 indicates input buffer holds a NUL-terminated string.
|
||||||
|
*
|
||||||
|
* Returns CURLE_OK on success, otherwise specific error code. Function
|
||||||
|
* output shall not be considered valid unless CURLE_OK is returned.
|
||||||
|
*
|
||||||
|
* When encoded data length is 0, returns NULL in *outptr.
|
||||||
*
|
*
|
||||||
* @unittest: 1302
|
* @unittest: 1302
|
||||||
*/
|
*/
|
||||||
size_t Curl_base64_encode(struct SessionHandle *data,
|
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||||
const char *inputbuff, size_t insize,
|
const char *inputbuff, size_t insize,
|
||||||
char **outptr)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
CURLcode res;
|
CURLcode error;
|
||||||
unsigned char ibuf[3];
|
unsigned char ibuf[3];
|
||||||
unsigned char obuf[4];
|
unsigned char obuf[4];
|
||||||
int i;
|
int i;
|
||||||
@ -151,24 +170,25 @@ size_t Curl_base64_encode(struct SessionHandle *data,
|
|||||||
|
|
||||||
const char *indata = inputbuff;
|
const char *indata = inputbuff;
|
||||||
|
|
||||||
*outptr = NULL; /* set to NULL in case of failure before we reach the end */
|
*outptr = NULL;
|
||||||
|
*outlen = 0;
|
||||||
|
|
||||||
if(0 == insize)
|
if(0 == insize)
|
||||||
insize = strlen(indata);
|
insize = strlen(indata);
|
||||||
|
|
||||||
base64data = output = malloc(insize*4/3+4);
|
base64data = output = malloc(insize*4/3+4);
|
||||||
if(NULL == output)
|
if(NULL == output)
|
||||||
return 0;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The base64 data needs to be created using the network encoding
|
* The base64 data needs to be created using the network encoding
|
||||||
* not the host encoding. And we can't change the actual input
|
* not the host encoding. And we can't change the actual input
|
||||||
* so we copy it to a buffer, translate it, and use that instead.
|
* so we copy it to a buffer, translate it, and use that instead.
|
||||||
*/
|
*/
|
||||||
res = Curl_convert_clone(data, indata, insize, &convbuf);
|
error = Curl_convert_clone(data, indata, insize, &convbuf);
|
||||||
if(res) {
|
if(error) {
|
||||||
free(output);
|
free(output);
|
||||||
return 0;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(convbuf)
|
if(convbuf)
|
||||||
@ -215,12 +235,14 @@ size_t Curl_base64_encode(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
output += 4;
|
output += 4;
|
||||||
}
|
}
|
||||||
*output=0;
|
*output = '\0';
|
||||||
*outptr = base64data; /* make it return the actual data memory */
|
*outptr = base64data; /* return pointer to new data, allocated memory */
|
||||||
|
|
||||||
if(convbuf)
|
if(convbuf)
|
||||||
free(convbuf);
|
free(convbuf);
|
||||||
|
|
||||||
return strlen(base64data); /* return the length of the new data */
|
*outlen = strlen(base64data); /* return the length of the new data */
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
/* ---- End of Base64 Encoding ---- */
|
/* ---- End of Base64 Encoding ---- */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -22,10 +22,11 @@
|
|||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
size_t Curl_base64_encode(struct SessionHandle *data,
|
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||||
const char *inputbuff, size_t insize,
|
const char *inputbuff, size_t insize,
|
||||||
char **outptr);
|
char **outptr, size_t *outlen);
|
||||||
|
|
||||||
size_t Curl_base64_decode(const char *src, unsigned char **outptr);
|
CURLcode Curl_base64_decode(const char *src,
|
||||||
|
unsigned char **outptr, size_t *outlen);
|
||||||
|
|
||||||
#endif /* HEADER_CURL_BASE64_H */
|
#endif /* HEADER_CURL_BASE64_H */
|
||||||
|
@ -305,16 +305,22 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
|||||||
(*) -> Optional
|
(*) -> Optional
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size_t size;
|
size_t size = 0;
|
||||||
unsigned char *buffer;
|
unsigned char *buffer = NULL;
|
||||||
|
CURLcode error;
|
||||||
|
|
||||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_WINDOWS_SSPI)
|
#if defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_WINDOWS_SSPI)
|
||||||
(void)data;
|
(void)data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size = Curl_base64_decode(header, &buffer);
|
error = Curl_base64_decode(header, &buffer, &size);
|
||||||
if(!buffer)
|
if(error)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return error;
|
||||||
|
|
||||||
|
if(!buffer) {
|
||||||
|
infof(data, "NTLM handshake failure (unhandled condition)\n");
|
||||||
|
return CURLE_REMOTE_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_SSPI
|
#ifdef USE_WINDOWS_SSPI
|
||||||
ntlm->type_2 = malloc(size + 1);
|
ntlm->type_2 = malloc(size + 1);
|
||||||
|
28
lib/http.c
28
lib/http.c
@ -231,11 +231,13 @@ static char *copy_header_value(const char *h)
|
|||||||
*/
|
*/
|
||||||
static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||||
{
|
{
|
||||||
char *authorization;
|
size_t size = 0;
|
||||||
struct SessionHandle *data=conn->data;
|
char *authorization = NULL;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
char **userp;
|
char **userp;
|
||||||
const char *user;
|
const char *user;
|
||||||
const char *pwd;
|
const char *pwd;
|
||||||
|
CURLcode error;
|
||||||
|
|
||||||
if(proxy) {
|
if(proxy) {
|
||||||
userp = &conn->allocptr.proxyuserpwd;
|
userp = &conn->allocptr.proxyuserpwd;
|
||||||
@ -249,20 +251,24 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
|
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
|
||||||
if(Curl_base64_encode(data, data->state.buffer,
|
|
||||||
strlen(data->state.buffer),
|
error = Curl_base64_encode(data,
|
||||||
&authorization) > 0) {
|
data->state.buffer, strlen(data->state.buffer),
|
||||||
if(*userp)
|
&authorization, &size);
|
||||||
free(*userp);
|
if(error)
|
||||||
*userp = aprintf( "%sAuthorization: Basic %s\r\n",
|
return error;
|
||||||
|
|
||||||
|
if(!authorization)
|
||||||
|
return CURLE_REMOTE_ACCESS_DENIED;
|
||||||
|
|
||||||
|
Curl_safefree(*userp);
|
||||||
|
*userp = aprintf("%sAuthorization: Basic %s\r\n",
|
||||||
proxy?"Proxy-":"",
|
proxy?"Proxy-":"",
|
||||||
authorization);
|
authorization);
|
||||||
free(authorization);
|
free(authorization);
|
||||||
if(!*userp)
|
if(!*userp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
|
||||||
else
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
unsigned char *ha1;
|
unsigned char *ha1;
|
||||||
unsigned char ha2[33];/* 32 digits and 1 zero byte */
|
unsigned char ha2[33];/* 32 digits and 1 zero byte */
|
||||||
char cnoncebuf[7];
|
char cnoncebuf[7];
|
||||||
char *cnonce;
|
char *cnonce = NULL;
|
||||||
|
size_t cnonce_sz = 0;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
|
||||||
@ -343,10 +344,12 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
/* Generate a cnonce */
|
/* Generate a cnonce */
|
||||||
now = Curl_tvnow();
|
now = Curl_tvnow();
|
||||||
snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", (long)now.tv_sec);
|
snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", (long)now.tv_sec);
|
||||||
if(Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), &cnonce))
|
|
||||||
|
rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
|
||||||
|
&cnonce, &cnonce_sz);
|
||||||
|
if(rc)
|
||||||
|
return rc;
|
||||||
d->cnonce = cnonce;
|
d->cnonce = cnonce;
|
||||||
else
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -138,9 +138,11 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||||
int ret;
|
int ret;
|
||||||
size_t len, rawlen;
|
size_t len;
|
||||||
|
size_t rawlen = 0;
|
||||||
bool gss;
|
bool gss;
|
||||||
const char* protocol;
|
const char* protocol;
|
||||||
|
CURLcode error;
|
||||||
|
|
||||||
while(*header && ISSPACE(*header))
|
while(*header && ISSPACE(*header))
|
||||||
header++;
|
header++;
|
||||||
@ -183,9 +185,9 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
|
|
||||||
len = strlen(header);
|
len = strlen(header);
|
||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
rawlen = Curl_base64_decode(header,
|
error = Curl_base64_decode(header,
|
||||||
(unsigned char **)&input_token.value);
|
(unsigned char **)&input_token.value, &rawlen);
|
||||||
if(rawlen == 0)
|
if(error || rawlen == 0)
|
||||||
return -1;
|
return -1;
|
||||||
input_token.length = rawlen;
|
input_token.length = rawlen;
|
||||||
|
|
||||||
@ -270,8 +272,9 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
|||||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||||
&conn->data->state.negotiate;
|
&conn->data->state.negotiate;
|
||||||
char *encoded = NULL;
|
char *encoded = NULL;
|
||||||
size_t len;
|
size_t len = 0;
|
||||||
char *userp;
|
char *userp;
|
||||||
|
CURLcode error;
|
||||||
|
|
||||||
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
||||||
if(checkprefix("Negotiate", neg_ctx->protocol)) {
|
if(checkprefix("Negotiate", neg_ctx->protocol)) {
|
||||||
@ -317,13 +320,21 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
len = Curl_base64_encode(conn->data,
|
error = Curl_base64_encode(conn->data,
|
||||||
neg_ctx->output_token.value,
|
neg_ctx->output_token.value,
|
||||||
neg_ctx->output_token.length,
|
neg_ctx->output_token.length,
|
||||||
&encoded);
|
&encoded, &len);
|
||||||
|
if(error) {
|
||||||
|
Curl_safefree(neg_ctx->output_token.value);
|
||||||
|
neg_ctx->output_token.value = NULL;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
if(len == 0)
|
if(len == 0) {
|
||||||
return CURLE_OUT_OF_MEMORY;
|
Curl_safefree(neg_ctx->output_token.value);
|
||||||
|
neg_ctx->output_token.value = NULL;
|
||||||
|
return CURLE_REMOTE_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
||||||
neg_ctx->protocol, encoded);
|
neg_ctx->protocol, encoded);
|
||||||
|
@ -94,6 +94,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
size_t len = 0, input_token_len = 0;
|
size_t len = 0, input_token_len = 0;
|
||||||
bool gss = FALSE;
|
bool gss = FALSE;
|
||||||
const char* protocol;
|
const char* protocol;
|
||||||
|
CURLcode error;
|
||||||
|
|
||||||
while(*header && ISSPACE(*header))
|
while(*header && ISSPACE(*header))
|
||||||
header++;
|
header++;
|
||||||
@ -176,9 +177,10 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
if(!input_token)
|
if(!input_token)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
input_token_len = Curl_base64_decode(header,
|
error = Curl_base64_decode(header,
|
||||||
(unsigned char **)&input_token);
|
(unsigned char **)&input_token,
|
||||||
if(input_token_len == 0)
|
&input_token_len);
|
||||||
|
if(error || input_token_len == 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,16 +240,19 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
|||||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||||
&conn->data->state.negotiate;
|
&conn->data->state.negotiate;
|
||||||
char *encoded = NULL;
|
char *encoded = NULL;
|
||||||
size_t len;
|
size_t len = 0;
|
||||||
char *userp;
|
char *userp;
|
||||||
|
CURLcode error;
|
||||||
|
|
||||||
len = Curl_base64_encode(conn->data,
|
error = Curl_base64_encode(conn->data,
|
||||||
(const char*)neg_ctx->output_token,
|
(const char*)neg_ctx->output_token,
|
||||||
neg_ctx->output_token_length,
|
neg_ctx->output_token_length,
|
||||||
&encoded);
|
&encoded, &len);
|
||||||
|
if(error)
|
||||||
|
return error;
|
||||||
|
|
||||||
if(len == 0)
|
if(len == 0)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_REMOTE_ACCESS_DENIED;
|
||||||
|
|
||||||
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
||||||
neg_ctx->protocol, encoded);
|
neg_ctx->protocol, encoded);
|
||||||
|
@ -455,8 +455,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
char *base64 = NULL;
|
char *base64 = NULL;
|
||||||
|
size_t base64_sz = 0;
|
||||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||||
CURLcode res;
|
CURLcode error;
|
||||||
|
|
||||||
/* point to the address of the pointer that holds the string to sent to the
|
/* point to the address of the pointer that holds the string to sent to the
|
||||||
server, which is for a plain host or for a HTTP proxy */
|
server, which is for a plain host or for a HTTP proxy */
|
||||||
@ -516,14 +517,19 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
|
|
||||||
/* Create a type-1 message */
|
/* Create a type-1 message */
|
||||||
|
|
||||||
res = Curl_ntlm_create_type1_message(userp, passwdp,
|
error = Curl_ntlm_create_type1_message(userp, passwdp,
|
||||||
ntlm, ntlmbuf, &size);
|
ntlm, ntlmbuf, &size);
|
||||||
|
if(error)
|
||||||
if(CURLE_OK == res) {
|
return error;
|
||||||
/* now size is the size of the base64 encoded package size */
|
|
||||||
size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
|
|
||||||
|
|
||||||
if(size > 0) {
|
if(size > 0) {
|
||||||
|
/* convert the binary blob into base64 */
|
||||||
|
error = Curl_base64_encode(NULL, (char *)ntlmbuf, size,
|
||||||
|
&base64, &base64_sz);
|
||||||
|
if(error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if(base64_sz > 0) {
|
||||||
Curl_safefree(*allocuserpwd);
|
Curl_safefree(*allocuserpwd);
|
||||||
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||||
proxy ? "Proxy-" : "",
|
proxy ? "Proxy-" : "",
|
||||||
@ -532,35 +538,36 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
|||||||
free(base64);
|
free(base64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NTLMSTATE_TYPE2:
|
case NTLMSTATE_TYPE2:
|
||||||
/* We already received the type-2 message, create a type-3 message */
|
/* We already received the type-2 message, create a type-3 message */
|
||||||
|
|
||||||
res = Curl_ntlm_create_type3_message(conn->data, userp, passwdp,
|
error = Curl_ntlm_create_type3_message(conn->data, userp, passwdp,
|
||||||
ntlm, ntlmbuf, &size);
|
ntlm, ntlmbuf, &size);
|
||||||
|
if(error)
|
||||||
if(CURLE_OK == res) {
|
return error;
|
||||||
/* convert the binary blob into base64 */
|
|
||||||
size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
|
|
||||||
|
|
||||||
if(size > 0) {
|
if(size > 0) {
|
||||||
|
/* convert the binary blob into base64 */
|
||||||
|
error = Curl_base64_encode(NULL, (char *)ntlmbuf, size,
|
||||||
|
&base64, &base64_sz);
|
||||||
|
if(error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if(base64_sz > 0) {
|
||||||
Curl_safefree(*allocuserpwd);
|
Curl_safefree(*allocuserpwd);
|
||||||
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||||
proxy ? "Proxy-" : "",
|
proxy ? "Proxy-" : "",
|
||||||
base64);
|
base64);
|
||||||
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
|
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
|
||||||
free(base64);
|
free(base64);
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
|
||||||
|
|
||||||
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||||
authp->done = TRUE;
|
authp->done = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
39
lib/krb4.c
39
lib/krb4.c
@ -201,7 +201,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
|||||||
int ret;
|
int ret;
|
||||||
char *p;
|
char *p;
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
size_t len;
|
size_t len = 0;
|
||||||
KTEXT_ST adat;
|
KTEXT_ST adat;
|
||||||
MSG_DAT msg_data;
|
MSG_DAT msg_data;
|
||||||
int checksum;
|
int checksum;
|
||||||
@ -212,6 +212,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
|||||||
int l = sizeof(conn->local_addr);
|
int l = sizeof(conn->local_addr);
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
size_t base64_sz = 0;
|
||||||
|
|
||||||
if(getsockname(conn->sock[FIRSTSOCKET],
|
if(getsockname(conn->sock[FIRSTSOCKET],
|
||||||
(struct sockaddr *)LOCAL_ADDR, &l) < 0)
|
(struct sockaddr *)LOCAL_ADDR, &l) < 0)
|
||||||
@ -247,8 +248,10 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(Curl_base64_encode(conn->data, (char *)adat.dat, adat.length, &p) < 1) {
|
result = Curl_base64_encode(conn->data, (char *)adat.dat, adat.length,
|
||||||
Curl_failf(data, "Out of memory base64-encoding");
|
&p, &base64_sz)
|
||||||
|
if(result) {
|
||||||
|
Curl_failf(data, "base64-encoding: %s", curl_easy_strerror(result));
|
||||||
return AUTH_CONTINUE;
|
return AUTH_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,10 +276,15 @@ krb4_auth(void *app_data, struct connectdata *conn)
|
|||||||
return AUTH_ERROR;
|
return AUTH_ERROR;
|
||||||
}
|
}
|
||||||
p += 5;
|
p += 5;
|
||||||
len = Curl_base64_decode(p, &ptr);
|
result = Curl_base64_decode(p, &ptr, &len);
|
||||||
|
if(result) {
|
||||||
|
Curl_failf(data, "base64-decoding: %s", curl_easy_strerror(result));
|
||||||
|
return AUTH_ERROR;
|
||||||
|
}
|
||||||
if(len > sizeof(adat.dat)-1) {
|
if(len > sizeof(adat.dat)-1) {
|
||||||
free(ptr);
|
free(ptr);
|
||||||
len=0;
|
ptr = NULL;
|
||||||
|
len = 0;
|
||||||
}
|
}
|
||||||
if(!len || !ptr) {
|
if(!len || !ptr) {
|
||||||
Curl_failf(data, "Failed to decode base64 from server");
|
Curl_failf(data, "Failed to decode base64 from server");
|
||||||
@ -330,11 +338,12 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
char *name;
|
char *name;
|
||||||
char *p;
|
char *p;
|
||||||
char passwd[100];
|
char passwd[100];
|
||||||
size_t tmp;
|
size_t tmp = 0;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
enum protection_level save;
|
enum protection_level save;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
|
size_t base64_sz = 0;
|
||||||
|
|
||||||
save = krb4_set_command_prot(conn, PROT_PRIVATE);
|
save = krb4_set_command_prot(conn, PROT_PRIVATE);
|
||||||
|
|
||||||
@ -360,10 +369,15 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
p += 2;
|
p += 2;
|
||||||
tmp = Curl_base64_decode(p, &ptr);
|
result = Curl_base64_decode(p, &ptr, &tmp);
|
||||||
|
if(result) {
|
||||||
|
Curl_failf(conn->data, "base64-decoding: %s", curl_easy_strerror(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if(tmp >= sizeof(tkt.dat)) {
|
if(tmp >= sizeof(tkt.dat)) {
|
||||||
free(ptr);
|
free(ptr);
|
||||||
tmp=0;
|
ptr = NULL;
|
||||||
|
tmp = 0;
|
||||||
}
|
}
|
||||||
if(!tmp || !ptr) {
|
if(!tmp || !ptr) {
|
||||||
Curl_failf(conn->data, "Failed to decode base64 in reply");
|
Curl_failf(conn->data, "Failed to decode base64 in reply");
|
||||||
@ -404,11 +418,12 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
|
|||||||
memset(key, 0, sizeof(key));
|
memset(key, 0, sizeof(key));
|
||||||
memset(schedule, 0, sizeof(schedule));
|
memset(schedule, 0, sizeof(schedule));
|
||||||
memset(passwd, 0, sizeof(passwd));
|
memset(passwd, 0, sizeof(passwd));
|
||||||
if(Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length, &p)
|
result = Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length,
|
||||||
< 1) {
|
&p, &base64_sz)
|
||||||
failf(conn->data, "Out of memory base64-encoding.");
|
if(result) {
|
||||||
|
Curl_failf(conn->data, "base64-encoding: %s", curl_easy_strerror(result));
|
||||||
krb4_set_command_prot(conn, save);
|
krb4_set_command_prot(conn, save);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return result;
|
||||||
}
|
}
|
||||||
memset (tktcopy.dat, 0, tktcopy.length);
|
memset (tktcopy.dat, 0, tktcopy.length);
|
||||||
|
|
||||||
|
17
lib/krb5.c
17
lib/krb5.c
@ -172,6 +172,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
|||||||
gss_name_t gssname;
|
gss_name_t gssname;
|
||||||
gss_ctx_id_t *context = app_data;
|
gss_ctx_id_t *context = app_data;
|
||||||
struct gss_channel_bindings_struct chan;
|
struct gss_channel_bindings_struct chan;
|
||||||
|
size_t base64_sz = 0;
|
||||||
|
|
||||||
if(getsockname(conn->sock[FIRSTSOCKET],
|
if(getsockname(conn->sock[FIRSTSOCKET],
|
||||||
(struct sockaddr *)LOCAL_ADDR, &l) < 0)
|
(struct sockaddr *)LOCAL_ADDR, &l) < 0)
|
||||||
@ -251,9 +252,10 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(output_buffer.length != 0) {
|
if(output_buffer.length != 0) {
|
||||||
if(Curl_base64_encode(data, (char *)output_buffer.value,
|
result = Curl_base64_encode(data, (char *)output_buffer.value,
|
||||||
output_buffer.length, &p) < 1) {
|
output_buffer.length, &p, &base64_sz)
|
||||||
Curl_infof(data, "Out of memory base64-encoding\n");
|
if(result) {
|
||||||
|
Curl_infof(data,"base64-encoding: %s\n", curl_easy_strerror(result));
|
||||||
ret = AUTH_CONTINUE;
|
ret = AUTH_CONTINUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -281,10 +283,11 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
|||||||
p = data->state.buffer + 4;
|
p = data->state.buffer + 4;
|
||||||
p = strstr(p, "ADAT=");
|
p = strstr(p, "ADAT=");
|
||||||
if(p) {
|
if(p) {
|
||||||
_gssresp.length = Curl_base64_decode(p + 5, (unsigned char **)
|
result = Curl_base64_decode(p + 5,
|
||||||
&_gssresp.value);
|
(unsigned char **)&_gssresp.value,
|
||||||
if(_gssresp.length < 1) {
|
&_gssresp.length);
|
||||||
Curl_failf(data, "Out of memory base64-encoding\n");
|
if(result) {
|
||||||
|
Curl_failf(data,"base64-decoding: %s", curl_easy_strerror(result));
|
||||||
ret = AUTH_CONTINUE;
|
ret = AUTH_CONTINUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
20
lib/ldap.c
20
lib/ldap.c
@ -176,9 +176,9 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
|||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
int ldap_proto = LDAP_VERSION3;
|
int ldap_proto = LDAP_VERSION3;
|
||||||
int ldap_ssl = 0;
|
int ldap_ssl = 0;
|
||||||
char *val_b64;
|
char *val_b64 = NULL;
|
||||||
size_t val_b64_sz;
|
size_t val_b64_sz = 0;
|
||||||
curl_off_t dlsize=0;
|
curl_off_t dlsize = 0;
|
||||||
#ifdef LDAP_OPT_NETWORK_TIMEOUT
|
#ifdef LDAP_OPT_NETWORK_TIMEOUT
|
||||||
struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */
|
struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */
|
||||||
#endif
|
#endif
|
||||||
@ -405,10 +405,20 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
|||||||
(char *)attribute +
|
(char *)attribute +
|
||||||
(strlen((char *)attribute) - 7)) == 0)) {
|
(strlen((char *)attribute) - 7)) == 0)) {
|
||||||
/* Binary attribute, encode to base64. */
|
/* Binary attribute, encode to base64. */
|
||||||
val_b64_sz = Curl_base64_encode(data,
|
CURLcode error = Curl_base64_encode(data,
|
||||||
vals[i]->bv_val,
|
vals[i]->bv_val,
|
||||||
vals[i]->bv_len,
|
vals[i]->bv_len,
|
||||||
&val_b64);
|
&val_b64,
|
||||||
|
&val_b64_sz);
|
||||||
|
if(error) {
|
||||||
|
ldap_value_free_len(vals);
|
||||||
|
ldap_memfree(attribute);
|
||||||
|
ldap_memfree(dn);
|
||||||
|
if(ber)
|
||||||
|
ber_free(ber, 0);
|
||||||
|
status = error;
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
if(val_b64_sz > 0) {
|
if(val_b64_sz > 0) {
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);
|
Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);
|
||||||
free(val_b64);
|
free(val_b64);
|
||||||
|
@ -544,12 +544,21 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(binary || binval) {
|
if(binary || binval) {
|
||||||
char *val_b64;
|
char *val_b64 = NULL;
|
||||||
|
size_t val_b64_sz = 0;
|
||||||
/* Binary value, encode to base64. */
|
/* Binary value, encode to base64. */
|
||||||
size_t val_b64_sz = Curl_base64_encode(data,
|
CURLcode error = Curl_base64_encode(data,
|
||||||
bvals[i].bv_val,
|
bvals[i].bv_val,
|
||||||
bvals[i].bv_len,
|
bvals[i].bv_len,
|
||||||
&val_b64);
|
&val_b64,
|
||||||
|
&val_b64_sz);
|
||||||
|
if(error) {
|
||||||
|
ber_memfree(bvals);
|
||||||
|
ber_free(ber, 0);
|
||||||
|
ldap_msgfree(result);
|
||||||
|
*err = error;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
|
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
|
||||||
data->req.bytecount += 2;
|
data->req.bytecount += 2;
|
||||||
if(val_b64_sz > 0) {
|
if(val_b64_sz > 0) {
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include "ftp.h"
|
#include "ftp.h"
|
||||||
#include "sendf.h"
|
#include "sendf.h"
|
||||||
#include "rawstr.h"
|
#include "rawstr.h"
|
||||||
|
#include "warnless.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
@ -280,12 +281,13 @@ static ssize_t sec_recv(struct connectdata *conn, int sockindex,
|
|||||||
static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
|
static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
|
||||||
const char *from, int length)
|
const char *from, int length)
|
||||||
{
|
{
|
||||||
size_t bytes;
|
int bytes, htonl_bytes; /* 32-bit integers for htonl */
|
||||||
size_t htonl_bytes;
|
char *buffer = NULL;
|
||||||
char *buffer;
|
|
||||||
char *cmd_buffer;
|
char *cmd_buffer;
|
||||||
|
size_t cmd_size = 0;
|
||||||
|
CURLcode error;
|
||||||
enum protection_level prot_level = conn->data_prot;
|
enum protection_level prot_level = conn->data_prot;
|
||||||
bool iscmd = prot_level == PROT_CMD;
|
bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE
|
||||||
|
|
||||||
DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
|
DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
|
||||||
|
|
||||||
@ -297,9 +299,17 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
|
|||||||
}
|
}
|
||||||
bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
|
bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
|
||||||
(void**)&buffer, conn);
|
(void**)&buffer, conn);
|
||||||
|
if(!buffer || bytes <= 0)
|
||||||
|
return; /* error */
|
||||||
|
|
||||||
if(iscmd) {
|
if(iscmd) {
|
||||||
bytes = Curl_base64_encode(conn->data, buffer, bytes, &cmd_buffer);
|
error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
|
||||||
if(bytes > 0) {
|
&cmd_buffer, &cmd_size);
|
||||||
|
if(error) {
|
||||||
|
free(buffer);
|
||||||
|
return; /* error */
|
||||||
|
}
|
||||||
|
if(cmd_size > 0) {
|
||||||
static const char *enc = "ENC ";
|
static const char *enc = "ENC ";
|
||||||
static const char *mic = "MIC ";
|
static const char *mic = "MIC ";
|
||||||
if(prot_level == PROT_PRIVATE)
|
if(prot_level == PROT_PRIVATE)
|
||||||
@ -307,7 +317,7 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
|
|||||||
else
|
else
|
||||||
socket_write(conn, fd, mic, 4);
|
socket_write(conn, fd, mic, 4);
|
||||||
|
|
||||||
socket_write(conn, fd, cmd_buffer, bytes);
|
socket_write(conn, fd, cmd_buffer, cmd_size);
|
||||||
socket_write(conn, fd, "\r\n", 2);
|
socket_write(conn, fd, "\r\n", 2);
|
||||||
infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
|
infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
|
||||||
cmd_buffer);
|
cmd_buffer);
|
||||||
@ -317,7 +327,7 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
|
|||||||
else {
|
else {
|
||||||
htonl_bytes = htonl(bytes);
|
htonl_bytes = htonl(bytes);
|
||||||
socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
|
socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
|
||||||
socket_write(conn, fd, buffer, bytes);
|
socket_write(conn, fd, buffer, curlx_sitouz(bytes));
|
||||||
}
|
}
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
@ -362,14 +372,20 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
|
|||||||
int decoded_len;
|
int decoded_len;
|
||||||
char *buf;
|
char *buf;
|
||||||
int ret_code;
|
int ret_code;
|
||||||
|
size_t decoded_sz = 0;
|
||||||
|
CURLcode error;
|
||||||
|
|
||||||
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
|
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
|
||||||
|
|
||||||
decoded_len = Curl_base64_decode(buffer + 4, (unsigned char **)&buf);
|
error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
|
||||||
if(decoded_len <= 0) {
|
if(error || decoded_sz == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(decoded_sz > (size_t)INT_MAX) {
|
||||||
free(buf);
|
free(buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
decoded_len = curlx_uztosi(decoded_sz);
|
||||||
|
|
||||||
decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
|
decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
|
||||||
level, conn);
|
level, conn);
|
||||||
|
109
lib/smtp.c
109
lib/smtp.c
@ -341,7 +341,8 @@ static CURLcode smtp_state_helo(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t smtp_auth_plain_data(struct connectdata * conn, char * * outptr)
|
static CURLcode smtp_auth_plain_data(struct connectdata *conn,
|
||||||
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
char plainauth[2 * MAX_CURL_USER_LENGTH + MAX_CURL_PASSWORD_LENGTH];
|
char plainauth[2 * MAX_CURL_USER_LENGTH + MAX_CURL_PASSWORD_LENGTH];
|
||||||
size_t ulen;
|
size_t ulen;
|
||||||
@ -350,8 +351,11 @@ static size_t smtp_auth_plain_data(struct connectdata * conn, char * * outptr)
|
|||||||
ulen = strlen(conn->user);
|
ulen = strlen(conn->user);
|
||||||
plen = strlen(conn->passwd);
|
plen = strlen(conn->passwd);
|
||||||
|
|
||||||
if(2 * ulen + plen + 2 > sizeof plainauth)
|
if(2 * ulen + plen + 2 > sizeof plainauth) {
|
||||||
return 0;
|
*outlen = 0;
|
||||||
|
*outptr = NULL;
|
||||||
|
return CURLE_OUT_OF_MEMORY; /* plainauth too small */
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(plainauth, conn->user, ulen);
|
memcpy(plainauth, conn->user, ulen);
|
||||||
plainauth[ulen] = '\0';
|
plainauth[ulen] = '\0';
|
||||||
@ -359,21 +363,25 @@ static size_t smtp_auth_plain_data(struct connectdata * conn, char * * outptr)
|
|||||||
plainauth[2 * ulen + 1] = '\0';
|
plainauth[2 * ulen + 1] = '\0';
|
||||||
memcpy(plainauth + 2 * ulen + 2, conn->passwd, plen);
|
memcpy(plainauth + 2 * ulen + 2, conn->passwd, plen);
|
||||||
return Curl_base64_encode(conn->data, plainauth, 2 * ulen + plen + 2,
|
return Curl_base64_encode(conn->data, plainauth, 2 * ulen + plen + 2,
|
||||||
outptr);
|
outptr, outlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t smtp_auth_login_user(struct connectdata * conn, char * * outptr)
|
static CURLcode smtp_auth_login_user(struct connectdata *conn,
|
||||||
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
size_t ulen;
|
size_t ulen = strlen(conn->user);
|
||||||
|
|
||||||
ulen = strlen(conn->user);
|
|
||||||
|
|
||||||
if(!ulen) {
|
if(!ulen) {
|
||||||
*outptr = strdup("=");
|
*outptr = strdup("=");
|
||||||
return *outptr? 1: 0;
|
if(*outptr) {
|
||||||
|
*outlen = (size_t) 1;
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
*outlen = 0;
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Curl_base64_encode(conn->data, conn->user, ulen, outptr);
|
return Curl_base64_encode(conn->data, conn->user, ulen, outptr, outlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode smtp_authenticate(struct connectdata *conn)
|
static CURLcode smtp_authenticate(struct connectdata *conn)
|
||||||
@ -409,13 +417,13 @@ static CURLcode smtp_authenticate(struct connectdata *conn)
|
|||||||
mech = "PLAIN";
|
mech = "PLAIN";
|
||||||
state1 = SMTP_AUTHPLAIN;
|
state1 = SMTP_AUTHPLAIN;
|
||||||
state2 = SMTP_AUTH;
|
state2 = SMTP_AUTH;
|
||||||
l = smtp_auth_plain_data(conn, &initresp);
|
result = smtp_auth_plain_data(conn, &initresp, &l);
|
||||||
}
|
}
|
||||||
else if(smtpc->authmechs & SMTP_AUTH_LOGIN) {
|
else if(smtpc->authmechs & SMTP_AUTH_LOGIN) {
|
||||||
mech = "LOGIN";
|
mech = "LOGIN";
|
||||||
state1 = SMTP_AUTHLOGIN;
|
state1 = SMTP_AUTHLOGIN;
|
||||||
state2 = SMTP_AUTHPASSWD;
|
state2 = SMTP_AUTHPASSWD;
|
||||||
l = smtp_auth_login_user(conn, &initresp);
|
result = smtp_auth_login_user(conn, &initresp, &l);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
infof(conn->data, "No known auth mechanisms supported!\n");
|
infof(conn->data, "No known auth mechanisms supported!\n");
|
||||||
@ -423,24 +431,20 @@ static CURLcode smtp_authenticate(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
if(!l)
|
if(initresp &&
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
else if(initresp &&
|
|
||||||
l + strlen(mech) <= 512 - 8) { /* AUTH <mech> ...<crlf> */
|
l + strlen(mech) <= 512 - 8) { /* AUTH <mech> ...<crlf> */
|
||||||
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
|
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
|
||||||
free(initresp);
|
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, state2);
|
state(conn, state2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Curl_safefree(initresp);
|
|
||||||
|
|
||||||
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
|
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, state1);
|
state(conn, state1);
|
||||||
}
|
}
|
||||||
|
Curl_safefree(initresp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,8 +575,8 @@ static CURLcode smtp_state_authplain_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
size_t l;
|
size_t l = 0;
|
||||||
char * plainauth;
|
char * plainauth = NULL;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@ -581,17 +585,17 @@ static CURLcode smtp_state_authplain_resp(struct connectdata *conn,
|
|||||||
result = CURLE_LOGIN_DENIED;
|
result = CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
l = smtp_auth_plain_data(conn, &plainauth);
|
result = smtp_auth_plain_data(conn, &plainauth, &l);
|
||||||
|
|
||||||
if(!l)
|
if(!result) {
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
if(plainauth) {
|
||||||
else {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", plainauth);
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", plainauth);
|
||||||
free(plainauth);
|
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, SMTP_AUTH);
|
state(conn, SMTP_AUTH);
|
||||||
}
|
}
|
||||||
|
Curl_safefree(plainauth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -604,8 +608,8 @@ static CURLcode smtp_state_authlogin_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
size_t l;
|
size_t l = 0;
|
||||||
char * authuser;
|
char * authuser = NULL;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@ -614,17 +618,17 @@ static CURLcode smtp_state_authlogin_resp(struct connectdata *conn,
|
|||||||
result = CURLE_LOGIN_DENIED;
|
result = CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
l = smtp_auth_login_user(conn, &authuser);
|
result = smtp_auth_login_user(conn, &authuser, &l);
|
||||||
|
|
||||||
if(!l)
|
if(!result) {
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
if(authuser) {
|
||||||
else {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authuser);
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authuser);
|
||||||
free(authuser);
|
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, SMTP_AUTHPASSWD);
|
state(conn, SMTP_AUTHPASSWD);
|
||||||
}
|
}
|
||||||
|
Curl_safefree(authuser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -638,8 +642,8 @@ static CURLcode smtp_state_authpasswd_resp(struct connectdata *conn,
|
|||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
size_t plen;
|
size_t plen;
|
||||||
size_t l;
|
size_t l = 0;
|
||||||
char *authpasswd;
|
char *authpasswd = NULL;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@ -653,17 +657,17 @@ static CURLcode smtp_state_authpasswd_resp(struct connectdata *conn,
|
|||||||
if(!plen)
|
if(!plen)
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "=");
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "=");
|
||||||
else {
|
else {
|
||||||
l = Curl_base64_encode(data, conn->passwd, plen, &authpasswd);
|
result = Curl_base64_encode(data, conn->passwd, plen, &authpasswd, &l);
|
||||||
|
|
||||||
if(!l)
|
if(!result) {
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
if(authpasswd) {
|
||||||
else {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authpasswd);
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authpasswd);
|
||||||
free(authpasswd);
|
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, SMTP_AUTH);
|
state(conn, SMTP_AUTH);
|
||||||
}
|
}
|
||||||
|
Curl_safefree(authpasswd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,8 +686,8 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
|
|||||||
char * chlg64 = data->state.buffer;
|
char * chlg64 = data->state.buffer;
|
||||||
unsigned char * chlg;
|
unsigned char * chlg;
|
||||||
size_t chlglen;
|
size_t chlglen;
|
||||||
size_t l;
|
size_t l = 0;
|
||||||
char * rplyb64;
|
char * rplyb64 = NULL;
|
||||||
HMAC_context * ctxt;
|
HMAC_context * ctxt;
|
||||||
unsigned char digest[16];
|
unsigned char digest[16];
|
||||||
char reply[MAX_CURL_USER_LENGTH + 32 /* 2 * size of MD5 digest */ + 1];
|
char reply[MAX_CURL_USER_LENGTH + 32 /* 2 * size of MD5 digest */ + 1];
|
||||||
@ -711,9 +715,9 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
|
|||||||
if(++l) {
|
if(++l) {
|
||||||
chlg64[l] = '\0';
|
chlg64[l] = '\0';
|
||||||
|
|
||||||
chlglen = Curl_base64_decode(chlg64, &chlg);
|
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
||||||
if(!chlglen)
|
if(result)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,17 +727,14 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
|
|||||||
(unsigned int)(strlen(conn->passwd)));
|
(unsigned int)(strlen(conn->passwd)));
|
||||||
|
|
||||||
if(!ctxt) {
|
if(!ctxt) {
|
||||||
if(chlg)
|
Curl_safefree(chlg);
|
||||||
free(chlg);
|
|
||||||
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(chlglen > 0)
|
if(chlglen > 0)
|
||||||
Curl_HMAC_update(ctxt, chlg, (unsigned int)(chlglen));
|
Curl_HMAC_update(ctxt, chlg, (unsigned int)(chlglen));
|
||||||
|
|
||||||
if(chlg)
|
Curl_safefree(chlg);
|
||||||
free(chlg);
|
|
||||||
|
|
||||||
Curl_HMAC_final(ctxt, digest);
|
Curl_HMAC_final(ctxt, digest);
|
||||||
|
|
||||||
@ -746,17 +747,17 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
|
|||||||
digest[12], digest[13], digest[14], digest[15]);
|
digest[12], digest[13], digest[14], digest[15]);
|
||||||
|
|
||||||
/* Encode it to base64 and send it. */
|
/* Encode it to base64 and send it. */
|
||||||
l = Curl_base64_encode(data, reply, 0, &rplyb64);
|
result = Curl_base64_encode(data, reply, 0, &rplyb64, &l);
|
||||||
|
|
||||||
if(!l)
|
if(!result) {
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
if(rplyb64) {
|
||||||
else {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
|
||||||
free(rplyb64);
|
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, SMTP_AUTH);
|
state(conn, SMTP_AUTH);
|
||||||
}
|
}
|
||||||
|
Curl_safefree(rplyb64);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -268,6 +268,25 @@ size_t curlx_sotouz(curl_off_t sonum)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** signed int to unsigned size_t
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t curlx_sitouz(int sinum)
|
||||||
|
{
|
||||||
|
#ifdef __INTEL_COMPILER
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:810) /* conversion may lose significant bits */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEBUGASSERT(sinum >= 0);
|
||||||
|
return (size_t) sinum;
|
||||||
|
|
||||||
|
#ifdef __INTEL_COMPILER
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER) && defined(__unix__)
|
#if defined(__INTEL_COMPILER) && defined(__unix__)
|
||||||
|
|
||||||
int curlx_FD_ISSET(int fd, fd_set *fdset)
|
int curlx_FD_ISSET(int fd, fd_set *fdset)
|
||||||
|
@ -38,6 +38,8 @@ ssize_t curlx_uztosz(size_t uznum);
|
|||||||
|
|
||||||
size_t curlx_sotouz(curl_off_t sonum);
|
size_t curlx_sotouz(curl_off_t sonum);
|
||||||
|
|
||||||
|
size_t curlx_sitouz(int sinum);
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER) && defined(__unix__)
|
#if defined(__INTEL_COMPILER) && defined(__unix__)
|
||||||
|
|
||||||
int curlx_FD_ISSET(int fd, fd_set *fdset);
|
int curlx_FD_ISSET(int fd, fd_set *fdset);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -166,7 +166,9 @@ static int appenddata(char **dst_buf, /* dest buffer */
|
|||||||
|
|
||||||
if(src_b64) {
|
if(src_b64) {
|
||||||
/* base64 decode the given buffer */
|
/* base64 decode the given buffer */
|
||||||
src_len = Curl_base64_decode(src_buf, &buf64.as_uchar);
|
int error = (int) Curl_base64_decode(src_buf, &buf64.as_uchar, &src_len);
|
||||||
|
if(error)
|
||||||
|
return GPE_OUT_OF_MEMORY;
|
||||||
src_buf = buf64.as_char;
|
src_buf = buf64.as_char;
|
||||||
if(!src_len || !src_buf) {
|
if(!src_len || !src_buf) {
|
||||||
/*
|
/*
|
||||||
|
@ -45,63 +45,80 @@ UNITTEST_START
|
|||||||
|
|
||||||
char *output;
|
char *output;
|
||||||
unsigned char *decoded;
|
unsigned char *decoded;
|
||||||
size_t rc;
|
size_t size = 0;
|
||||||
|
unsigned char anychar = 'x';
|
||||||
|
CURLcode rc;
|
||||||
|
|
||||||
rc = Curl_base64_encode(data, "i", 1, &output);
|
rc = Curl_base64_encode(data, "i", 1, &output, &size);
|
||||||
fail_unless( rc == 4 , "return code should be 4" );
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 4, "size should be 4");
|
||||||
verify_memory( output, "aQ==", 4);
|
verify_memory( output, "aQ==", 4);
|
||||||
Curl_safefree(output);
|
Curl_safefree(output);
|
||||||
|
|
||||||
rc = Curl_base64_encode(data, "ii", 2, &output);
|
rc = Curl_base64_encode(data, "ii", 2, &output, &size);
|
||||||
fail_unless( rc == 4 , "return code should be 4" );
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 4, "size should be 4");
|
||||||
verify_memory( output, "aWk=", 4);
|
verify_memory( output, "aWk=", 4);
|
||||||
Curl_safefree(output);
|
Curl_safefree(output);
|
||||||
|
|
||||||
rc = Curl_base64_encode(data, "iii", 3, &output);
|
rc = Curl_base64_encode(data, "iii", 3, &output, &size);
|
||||||
fail_unless( rc == 4 , "return code should be 4" );
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 4, "size should be 4");
|
||||||
verify_memory( output, "aWlp", 4);
|
verify_memory( output, "aWlp", 4);
|
||||||
Curl_safefree(output);
|
Curl_safefree(output);
|
||||||
|
|
||||||
rc = Curl_base64_encode(data, "iiii", 4, &output);
|
rc = Curl_base64_encode(data, "iiii", 4, &output, &size);
|
||||||
fail_unless( rc == 8 , "return code should be 8" );
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 8, "size should be 8");
|
||||||
verify_memory( output, "aWlpaQ==", 8);
|
verify_memory( output, "aWlpaQ==", 8);
|
||||||
Curl_safefree(output);
|
Curl_safefree(output);
|
||||||
|
|
||||||
/* 0 length makes it do strlen() */
|
/* 0 length makes it do strlen() */
|
||||||
rc = Curl_base64_encode(data, "iiii", 0, &output);
|
rc = Curl_base64_encode(data, "iiii", 0, &output, &size);
|
||||||
fail_unless( rc == 8 , "return code should be 8" );
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 8, "size should be 8");
|
||||||
verify_memory( output, "aWlpaQ==", 8);
|
verify_memory( output, "aWlpaQ==", 8);
|
||||||
Curl_safefree(output);
|
Curl_safefree(output);
|
||||||
|
|
||||||
rc = Curl_base64_decode("aWlpaQ==", &decoded);
|
rc = Curl_base64_decode("aWlpaQ==", &decoded, &size);
|
||||||
fail_unless(rc == 4, "return code should be 4");
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 4, "size should be 4");
|
||||||
verify_memory(decoded, "iiii", 4);
|
verify_memory(decoded, "iiii", 4);
|
||||||
Curl_safefree(decoded);
|
Curl_safefree(decoded);
|
||||||
|
|
||||||
rc = Curl_base64_decode("aWlp", &decoded);
|
rc = Curl_base64_decode("aWlp", &decoded, &size);
|
||||||
fail_unless(rc == 3, "return code should be 3");
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 3, "size should be 3");
|
||||||
verify_memory(decoded, "iii", 3);
|
verify_memory(decoded, "iii", 3);
|
||||||
Curl_safefree(decoded);
|
Curl_safefree(decoded);
|
||||||
|
|
||||||
rc = Curl_base64_decode("aWk=", &decoded);
|
rc = Curl_base64_decode("aWk=", &decoded, &size);
|
||||||
fail_unless(rc == 2, "return code should be 2");
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 2, "size should be 2");
|
||||||
verify_memory(decoded, "ii", 2);
|
verify_memory(decoded, "ii", 2);
|
||||||
Curl_safefree(decoded);
|
Curl_safefree(decoded);
|
||||||
|
|
||||||
rc = Curl_base64_decode("aQ==", &decoded);
|
rc = Curl_base64_decode("aQ==", &decoded, &size);
|
||||||
fail_unless(rc == 1, "return code should be 1");
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 1, "size should be 1");
|
||||||
verify_memory(decoded, "i", 2);
|
verify_memory(decoded, "i", 2);
|
||||||
Curl_safefree(decoded);
|
Curl_safefree(decoded);
|
||||||
|
|
||||||
/* this is an illegal input */
|
/* this is an illegal input */
|
||||||
decoded = NULL;
|
size = 1; /* not zero */
|
||||||
rc = Curl_base64_decode("aQ", &decoded);
|
decoded = &anychar; /* not NULL */
|
||||||
fail_unless(rc == 0, "return code should be 0");
|
rc = Curl_base64_decode("aQ", &decoded, &size);
|
||||||
|
/* return code indiferent, but output shall be as follows */
|
||||||
|
fail_unless(size == 0, "size should be 0");
|
||||||
fail_if(decoded, "returned pointer should be NULL");
|
fail_if(decoded, "returned pointer should be NULL");
|
||||||
|
|
||||||
/* this is garbage input that libcurl decodes as far as possible */
|
/* this is garbage input that libcurl decodes as far as possible */
|
||||||
rc = Curl_base64_decode("a\x1f==", &decoded);
|
size = 0;
|
||||||
fail_unless(rc == 1, "return code should be 1");
|
decoded = NULL;
|
||||||
|
rc = Curl_base64_decode("a\x1f==", &decoded, &size);
|
||||||
|
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
|
||||||
|
fail_unless(size == 1, "size should be 1");
|
||||||
|
fail_if(!decoded, "returned pointer should not be NULL");
|
||||||
Curl_safefree(decoded);
|
Curl_safefree(decoded);
|
||||||
|
|
||||||
UNITTEST_STOP
|
UNITTEST_STOP
|
||||||
|
Loading…
Reference in New Issue
Block a user