aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/base64.c64
-rw-r--r--lib/curl_base64.h11
-rw-r--r--lib/curl_ntlm.c16
-rw-r--r--lib/http.c36
-rw-r--r--lib/http_digest.c13
-rw-r--r--lib/http_negotiate.c33
-rw-r--r--lib/http_negotiate_sspi.c25
-rw-r--r--lib/http_ntlm.c45
-rw-r--r--lib/krb4.c39
-rw-r--r--lib/krb5.c17
-rw-r--r--lib/ldap.c24
-rw-r--r--lib/openldap.c19
-rw-r--r--lib/security.c36
-rw-r--r--lib/smtp.c135
-rw-r--r--lib/warnless.c19
-rw-r--r--lib/warnless.h2
-rw-r--r--tests/server/getpart.c6
-rw-r--r--tests/unit/unit1302.c65
18 files changed, 380 insertions, 225 deletions
diff --git a/lib/base64.c b/lib/base64.c
index 812fd67c2..23ebb4aa9 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -68,12 +68,19 @@ static void decodeQuantum(unsigned char *dest, const char *src)
/*
* Curl_base64_decode()
*
- * Given a base64 string at src, decode it and return an allocated memory in
- * the *outptr. Returns the length of the decoded data.
+ * Given a base64 NUL-terminated string at src, decode it and return a
+ * 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
*/
-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 equalsTerm = 0;
@@ -84,6 +91,7 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
unsigned char *newstr;
*outptr = NULL;
+ *outlen = 0;
while((src[length] != '=') && src[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 */
if(numQuantums == 0)
- return 0;
+ return CURLE_OK;
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. */
newstr = malloc(rawlen+4);
if(!newstr)
- return 0;
+ return CURLE_OUT_OF_MEMORY;
*outptr = newstr;
@@ -124,23 +132,34 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
newstr[i] = lastQuantum[i];
newstr[i] = '\0'; /* zero terminate */
- return rawlen;
+
+ *outlen = rawlen; /* return size of decoded data */
+
+ return CURLE_OK;
}
/*
* Curl_base64_encode()
*
- * Returns the length of the newly created base64 string. The third argument
- * is a pointer to an allocated area holding the base64 data. If something
- * went wrong, 0 is returned.
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * 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
*/
-size_t Curl_base64_encode(struct SessionHandle *data,
- const char *inputbuff, size_t insize,
- char **outptr)
+CURLcode Curl_base64_encode(struct SessionHandle *data,
+ const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen)
{
- CURLcode res;
+ CURLcode error;
unsigned char ibuf[3];
unsigned char obuf[4];
int i;
@@ -151,24 +170,25 @@ size_t Curl_base64_encode(struct SessionHandle *data,
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)
insize = strlen(indata);
base64data = output = malloc(insize*4/3+4);
if(NULL == output)
- return 0;
+ return CURLE_OUT_OF_MEMORY;
/*
* The base64 data needs to be created using the network encoding
* 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.
*/
- res = Curl_convert_clone(data, indata, insize, &convbuf);
- if(res) {
+ error = Curl_convert_clone(data, indata, insize, &convbuf);
+ if(error) {
free(output);
- return 0;
+ return error;
}
if(convbuf)
@@ -215,12 +235,14 @@ size_t Curl_base64_encode(struct SessionHandle *data,
}
output += 4;
}
- *output=0;
- *outptr = base64data; /* make it return the actual data memory */
+ *output = '\0';
+ *outptr = base64data; /* return pointer to new data, allocated memory */
if(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 ---- */
diff --git a/lib/curl_base64.h b/lib/curl_base64.h
index 2498a0a22..6e200d2ec 100644
--- a/lib/curl_base64.h
+++ b/lib/curl_base64.h
@@ -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
* you should have received as part of this distribution. The terms
@@ -22,10 +22,11 @@
*
***************************************************************************/
-size_t Curl_base64_encode(struct SessionHandle *data,
- const char *inputbuff, size_t insize,
- char **outptr);
+CURLcode Curl_base64_encode(struct SessionHandle *data,
+ const char *inputbuff, size_t insize,
+ 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 */
diff --git a/lib/curl_ntlm.c b/lib/curl_ntlm.c
index c0289e5d4..b555f5ab6 100644
--- a/lib/curl_ntlm.c
+++ b/lib/curl_ntlm.c
@@ -305,16 +305,22 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
(*) -> Optional
*/
- size_t size;
- unsigned char *buffer;
+ size_t size = 0;
+ unsigned char *buffer = NULL;
+ CURLcode error;
#if defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_WINDOWS_SSPI)
(void)data;
#endif
- size = Curl_base64_decode(header, &buffer);
- if(!buffer)
- return CURLE_OUT_OF_MEMORY;
+ error = Curl_base64_decode(header, &buffer, &size);
+ if(error)
+ return error;
+
+ if(!buffer) {
+ infof(data, "NTLM handshake failure (unhandled condition)\n");
+ return CURLE_REMOTE_ACCESS_DENIED;
+ }
#ifdef USE_WINDOWS_SSPI
ntlm->type_2 = malloc(size + 1);
diff --git a/lib/http.c b/lib/http.c
index 4952ddd64..edf3e163f 100644
--- a/lib/http.c
+++ b/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)
{
- char *authorization;
- struct SessionHandle *data=conn->data;
+ size_t size = 0;
+ char *authorization = NULL;
+ struct SessionHandle *data = conn->data;
char **userp;
const char *user;
const char *pwd;
+ CURLcode error;
if(proxy) {
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);
- if(Curl_base64_encode(data, data->state.buffer,
- strlen(data->state.buffer),
- &authorization) > 0) {
- if(*userp)
- free(*userp);
- *userp = aprintf( "%sAuthorization: Basic %s\r\n",
- proxy?"Proxy-":"",
- authorization);
- free(authorization);
- if(!*userp)
- return CURLE_OUT_OF_MEMORY;
- }
- else
+
+ error = Curl_base64_encode(data,
+ data->state.buffer, strlen(data->state.buffer),
+ &authorization, &size);
+ if(error)
+ return error;
+
+ if(!authorization)
+ return CURLE_REMOTE_ACCESS_DENIED;
+
+ Curl_safefree(*userp);
+ *userp = aprintf("%sAuthorization: Basic %s\r\n",
+ proxy?"Proxy-":"",
+ authorization);
+ free(authorization);
+ if(!*userp)
return CURLE_OUT_OF_MEMORY;
+
return CURLE_OK;
}
diff --git a/lib/http_digest.c b/lib/http_digest.c
index 3ca0389e9..b41e62306 100644
--- a/lib/http_digest.c
+++ b/lib/http_digest.c
@@ -280,7 +280,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
unsigned char *ha1;
unsigned char ha2[33];/* 32 digits and 1 zero byte */
char cnoncebuf[7];
- char *cnonce;
+ char *cnonce = NULL;
+ size_t cnonce_sz = 0;
char *tmp = NULL;
struct timeval now;
@@ -343,10 +344,12 @@ CURLcode Curl_output_digest(struct connectdata *conn,
/* Generate a cnonce */
now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", (long)now.tv_sec);
- if(Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), &cnonce))
- d->cnonce = cnonce;
- else
- return CURLE_OUT_OF_MEMORY;
+
+ rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
+ &cnonce, &cnonce_sz);
+ if(rc)
+ return rc;
+ d->cnonce = cnonce;
}
/*
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index b3d870c9c..f0cf16b9e 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -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 output_token = GSS_C_EMPTY_BUFFER;
int ret;
- size_t len, rawlen;
+ size_t len;
+ size_t rawlen = 0;
bool gss;
const char* protocol;
+ CURLcode error;
while(*header && ISSPACE(*header))
header++;
@@ -183,9 +185,9 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
len = strlen(header);
if(len > 0) {
- rawlen = Curl_base64_decode(header,
- (unsigned char **)&input_token.value);
- if(rawlen == 0)
+ error = Curl_base64_decode(header,
+ (unsigned char **)&input_token.value, &rawlen);
+ if(error || rawlen == 0)
return -1;
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:
&conn->data->state.negotiate;
char *encoded = NULL;
- size_t len;
+ size_t len = 0;
char *userp;
+ CURLcode error;
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
if(checkprefix("Negotiate", neg_ctx->protocol)) {
@@ -317,13 +320,21 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
}
}
#endif
- len = Curl_base64_encode(conn->data,
- neg_ctx->output_token.value,
- neg_ctx->output_token.length,
- &encoded);
+ error = Curl_base64_encode(conn->data,
+ neg_ctx->output_token.value,
+ neg_ctx->output_token.length,
+ &encoded, &len);
+ if(error) {
+ Curl_safefree(neg_ctx->output_token.value);
+ neg_ctx->output_token.value = NULL;
+ return error;
+ }
- if(len == 0)
- return CURLE_OUT_OF_MEMORY;
+ if(len == 0) {
+ 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-" : "",
neg_ctx->protocol, encoded);
diff --git a/lib/http_negotiate_sspi.c b/lib/http_negotiate_sspi.c
index 875ed3cfd..08d016274 100644
--- a/lib/http_negotiate_sspi.c
+++ b/lib/http_negotiate_sspi.c
@@ -82,7 +82,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
{
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
&conn->data->state.negotiate;
- BYTE *input_token = 0;
+ BYTE *input_token = 0;
SecBufferDesc out_buff_desc;
SecBuffer out_sec_buff;
SecBufferDesc in_buff_desc;
@@ -94,6 +94,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
size_t len = 0, input_token_len = 0;
bool gss = FALSE;
const char* protocol;
+ CURLcode error;
while(*header && ISSPACE(*header))
header++;
@@ -176,9 +177,10 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
if(!input_token)
return -1;
- input_token_len = Curl_base64_decode(header,
- (unsigned char **)&input_token);
- if(input_token_len == 0)
+ error = Curl_base64_decode(header,
+ (unsigned char **)&input_token,
+ &input_token_len);
+ if(error || input_token_len == 0)
return -1;
}
@@ -238,16 +240,19 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
&conn->data->state.negotiate;
char *encoded = NULL;
- size_t len;
+ size_t len = 0;
char *userp;
+ CURLcode error;
- len = Curl_base64_encode(conn->data,
- (const char*)neg_ctx->output_token,
- neg_ctx->output_token_length,
- &encoded);
+ error = Curl_base64_encode(conn->data,
+ (const char*)neg_ctx->output_token,
+ neg_ctx->output_token_length,
+ &encoded, &len);
+ if(error)
+ return error;
if(len == 0)
- return CURLE_OUT_OF_MEMORY;
+ return CURLE_REMOTE_ACCESS_DENIED;
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
neg_ctx->protocol, encoded);
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index 2c60e5275..c5ee679a9 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -455,8 +455,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
{
size_t size = 0;
char *base64 = NULL;
+ size_t base64_sz = 0;
unsigned char ntlmbuf[NTLM_BUFSIZE];
- CURLcode res;
+ CURLcode error;
/* 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 */
@@ -516,14 +517,19 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
/* Create a type-1 message */
- res = Curl_ntlm_create_type1_message(userp, passwdp,
- ntlm, ntlmbuf, &size);
+ error = Curl_ntlm_create_type1_message(userp, passwdp,
+ ntlm, ntlmbuf, &size);
+ if(error)
+ return error;
- if(CURLE_OK == res) {
- /* now size is the size of the base64 encoded package size */
- size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
+ 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(size > 0) {
+ if(base64_sz > 0) {
Curl_safefree(*allocuserpwd);
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
proxy ? "Proxy-" : "",
@@ -532,35 +538,36 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
free(base64);
}
}
- else
- return CURLE_OUT_OF_MEMORY; /* FIX TODO */
break;
case NTLMSTATE_TYPE2:
/* We already received the type-2 message, create a type-3 message */
- res = Curl_ntlm_create_type3_message(conn->data, userp, passwdp,
- ntlm, ntlmbuf, &size);
+ error = Curl_ntlm_create_type3_message(conn->data, userp, passwdp,
+ ntlm, ntlmbuf, &size);
+ if(error)
+ return error;
- if(CURLE_OK == res) {
+ if(size > 0) {
/* convert the binary blob into base64 */
- size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
+ error = Curl_base64_encode(NULL, (char *)ntlmbuf, size,
+ &base64, &base64_sz);
+ if(error)
+ return error;
- if(size > 0) {
+ if(base64_sz > 0) {
Curl_safefree(*allocuserpwd);
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
proxy ? "Proxy-" : "",
base64);
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
free(base64);
+
+ ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
+ authp->done = TRUE;
}
}
- else
- return CURLE_OUT_OF_MEMORY; /* FIX TODO */
-
- ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
- authp->done = TRUE;
break;
diff --git a/lib/krb4.c b/lib/krb4.c
index 30b1c664e..2c5676a63 100644
--- a/lib/krb4.c
+++ b/lib/krb4.c
@@ -201,7 +201,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
int ret;
char *p;
unsigned char *ptr;
- size_t len;
+ size_t len = 0;
KTEXT_ST adat;
MSG_DAT msg_data;
int checksum;
@@ -212,6 +212,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
int l = sizeof(conn->local_addr);
struct SessionHandle *data = conn->data;
CURLcode result;
+ size_t base64_sz = 0;
if(getsockname(conn->sock[FIRSTSOCKET],
(struct sockaddr *)LOCAL_ADDR, &l) < 0)
@@ -247,8 +248,10 @@ krb4_auth(void *app_data, struct connectdata *conn)
}
#endif
- if(Curl_base64_encode(conn->data, (char *)adat.dat, adat.length, &p) < 1) {
- Curl_failf(data, "Out of memory base64-encoding");
+ result = Curl_base64_encode(conn->data, (char *)adat.dat, adat.length,
+ &p, &base64_sz)
+ if(result) {
+ Curl_failf(data, "base64-encoding: %s", curl_easy_strerror(result));
return AUTH_CONTINUE;
}
@@ -273,10 +276,15 @@ krb4_auth(void *app_data, struct connectdata *conn)
return AUTH_ERROR;
}
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) {
free(ptr);
- len=0;
+ ptr = NULL;
+ len = 0;
}
if(!len || !ptr) {
Curl_failf(data, "Failed to decode base64 from server");
@@ -330,11 +338,12 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
char *name;
char *p;
char passwd[100];
- size_t tmp;
+ size_t tmp = 0;
ssize_t nread;
enum protection_level save;
CURLcode result;
unsigned char *ptr;
+ size_t base64_sz = 0;
save = krb4_set_command_prot(conn, PROT_PRIVATE);
@@ -360,10 +369,15 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
}
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)) {
free(ptr);
- tmp=0;
+ ptr = NULL;
+ tmp = 0;
}
if(!tmp || !ptr) {
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(schedule, 0, sizeof(schedule));
memset(passwd, 0, sizeof(passwd));
- if(Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length, &p)
- < 1) {
- failf(conn->data, "Out of memory base64-encoding.");
+ result = Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length,
+ &p, &base64_sz)
+ if(result) {
+ Curl_failf(conn->data, "base64-encoding: %s", curl_easy_strerror(result));
krb4_set_command_prot(conn, save);
- return CURLE_OUT_OF_MEMORY;
+ return result;
}
memset (tktcopy.dat, 0, tktcopy.length);
diff --git a/lib/krb5.c b/lib/krb5.c
index 0422cda35..c5f635c1e 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -172,6 +172,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
gss_name_t gssname;
gss_ctx_id_t *context = app_data;
struct gss_channel_bindings_struct chan;
+ size_t base64_sz = 0;
if(getsockname(conn->sock[FIRSTSOCKET],
(struct sockaddr *)LOCAL_ADDR, &l) < 0)
@@ -251,9 +252,10 @@ krb5_auth(void *app_data, struct connectdata *conn)
}
if(output_buffer.length != 0) {
- if(Curl_base64_encode(data, (char *)output_buffer.value,
- output_buffer.length, &p) < 1) {
- Curl_infof(data, "Out of memory base64-encoding\n");
+ result = Curl_base64_encode(data, (char *)output_buffer.value,
+ output_buffer.length, &p, &base64_sz)
+ if(result) {
+ Curl_infof(data,"base64-encoding: %s\n", curl_easy_strerror(result));
ret = AUTH_CONTINUE;
break;
}
@@ -281,10 +283,11 @@ krb5_auth(void *app_data, struct connectdata *conn)
p = data->state.buffer + 4;
p = strstr(p, "ADAT=");
if(p) {
- _gssresp.length = Curl_base64_decode(p + 5, (unsigned char **)
- &_gssresp.value);
- if(_gssresp.length < 1) {
- Curl_failf(data, "Out of memory base64-encoding\n");
+ result = Curl_base64_decode(p + 5,
+ (unsigned char **)&_gssresp.value,
+ &_gssresp.length);
+ if(result) {
+ Curl_failf(data,"base64-decoding: %s", curl_easy_strerror(result));
ret = AUTH_CONTINUE;
break;
}
diff --git a/lib/ldap.c b/lib/ldap.c
index 9692ed9d7..0fcbc22e0 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -176,9 +176,9 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
struct SessionHandle *data=conn->data;
int ldap_proto = LDAP_VERSION3;
int ldap_ssl = 0;
- char *val_b64;
- size_t val_b64_sz;
- curl_off_t dlsize=0;
+ char *val_b64 = NULL;
+ size_t val_b64_sz = 0;
+ curl_off_t dlsize = 0;
#ifdef LDAP_OPT_NETWORK_TIMEOUT
struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */
#endif
@@ -405,10 +405,20 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
(char *)attribute +
(strlen((char *)attribute) - 7)) == 0)) {
/* Binary attribute, encode to base64. */
- val_b64_sz = Curl_base64_encode(data,
- vals[i]->bv_val,
- vals[i]->bv_len,
- &val_b64);
+ CURLcode error = Curl_base64_encode(data,
+ vals[i]->bv_val,
+ vals[i]->bv_len,
+ &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) {
Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);
free(val_b64);
diff --git a/lib/openldap.c b/lib/openldap.c
index 69523cb37..070892524 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -544,12 +544,21 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
}
}
if(binary || binval) {
- char *val_b64;
+ char *val_b64 = NULL;
+ size_t val_b64_sz = 0;
/* Binary value, encode to base64. */
- size_t val_b64_sz = Curl_base64_encode(data,
- bvals[i].bv_val,
- bvals[i].bv_len,
- &val_b64);
+ CURLcode error = Curl_base64_encode(data,
+ bvals[i].bv_val,
+ bvals[i].bv_len,
+ &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);
data->req.bytecount += 2;
if(val_b64_sz > 0) {
diff --git a/lib/security.c b/lib/security.c
index af61f3aed..595a7337e 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -61,6 +61,7 @@
#include "ftp.h"
#include "sendf.h"
#include "rawstr.h"
+#include "warnless.h"
/* The last #include file should be: */
#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,
const char *from, int length)
{
- size_t bytes;
- size_t htonl_bytes;
- char *buffer;
+ int bytes, htonl_bytes; /* 32-bit integers for htonl */
+ char *buffer = NULL;
char *cmd_buffer;
+ size_t cmd_size = 0;
+ CURLcode error;
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);
@@ -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,
(void**)&buffer, conn);
+ if(!buffer || bytes <= 0)
+ return; /* error */
+
if(iscmd) {
- bytes = Curl_base64_encode(conn->data, buffer, bytes, &cmd_buffer);
- if(bytes > 0) {
+ error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
+ &cmd_buffer, &cmd_size);
+ if(error) {
+ free(buffer);
+ return; /* error */
+ }
+ if(cmd_size > 0) {
static const char *enc = "ENC ";
static const char *mic = "MIC ";
if(prot_level == PROT_PRIVATE)
@@ -307,7 +317,7 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
else
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);
infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
cmd_buffer);
@@ -317,7 +327,7 @@ static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
else {
htonl_bytes = 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);
}
@@ -362,14 +372,20 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
int decoded_len;
char *buf;
int ret_code;
+ size_t decoded_sz = 0;
+ CURLcode error;
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
- decoded_len = Curl_base64_decode(buffer + 4, (unsigned char **)&buf);
- if(decoded_len <= 0) {
+ error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
+ if(error || decoded_sz == 0)
+ return -1;
+
+ if(decoded_sz > (size_t)INT_MAX) {
free(buf);
return -1;
}
+ decoded_len = curlx_uztosi(decoded_sz);
decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
level, conn);
diff --git a/lib/smtp.c b/lib/smtp.c
index 5fa989346..9550c0fcc 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -341,7 +341,8 @@ static CURLcode smtp_state_helo(struct connectdata *conn)
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];
size_t ulen;
@@ -350,8 +351,11 @@ static size_t smtp_auth_plain_data(struct connectdata * conn, char * * outptr)
ulen = strlen(conn->user);
plen = strlen(conn->passwd);
- if(2 * ulen + plen + 2 > sizeof plainauth)
- return 0;
+ if(2 * ulen + plen + 2 > sizeof plainauth) {
+ *outlen = 0;
+ *outptr = NULL;
+ return CURLE_OUT_OF_MEMORY; /* plainauth too small */
+ }
memcpy(plainauth, conn->user, ulen);
plainauth[ulen] = '\0';
@@ -359,21 +363,25 @@ static size_t smtp_auth_plain_data(struct connectdata * conn, char * * outptr)
plainauth[2 * ulen + 1] = '\0';
memcpy(plainauth + 2 * ulen + 2, conn->passwd, plen);
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;
-
- ulen = strlen(conn->user);
+ size_t ulen = strlen(conn->user);
if(!ulen) {
*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)
@@ -409,13 +417,13 @@ static CURLcode smtp_authenticate(struct connectdata *conn)
mech = "PLAIN";
state1 = SMTP_AUTHPLAIN;
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) {
mech = "LOGIN";
state1 = SMTP_AUTHLOGIN;
state2 = SMTP_AUTHPASSWD;
- l = smtp_auth_login_user(conn, &initresp);
+ result = smtp_auth_login_user(conn, &initresp, &l);
}
else {
infof(conn->data, "No known auth mechanisms supported!\n");
@@ -423,24 +431,20 @@ static CURLcode smtp_authenticate(struct connectdata *conn)
}
if(!result) {
- if(!l)
- result = CURLE_OUT_OF_MEMORY;
- else if(initresp &&
- l + strlen(mech) <= 512 - 8) { /* AUTH <mech> ...<crlf> */
+ if(initresp &&
+ l + strlen(mech) <= 512 - 8) { /* AUTH <mech> ...<crlf> */
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
- free(initresp);
if(!result)
state(conn, state2);
}
else {
- Curl_safefree(initresp);
-
result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
if(!result)
state(conn, state1);
}
+ Curl_safefree(initresp);
}
}
@@ -571,8 +575,8 @@ static CURLcode smtp_state_authplain_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
- size_t l;
- char * plainauth;
+ size_t l = 0;
+ char * plainauth = NULL;
(void)instate; /* no use for this yet */
@@ -581,16 +585,16 @@ static CURLcode smtp_state_authplain_resp(struct connectdata *conn,
result = CURLE_LOGIN_DENIED;
}
else {
- l = smtp_auth_plain_data(conn, &plainauth);
+ result = smtp_auth_plain_data(conn, &plainauth, &l);
- if(!l)
- result = CURLE_OUT_OF_MEMORY;
- else {
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", plainauth);
- free(plainauth);
+ if(!result) {
+ if(plainauth) {
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", plainauth);
- if(!result)
- state(conn, SMTP_AUTH);
+ if(!result)
+ state(conn, SMTP_AUTH);
+ }
+ Curl_safefree(plainauth);
}
}
@@ -604,8 +608,8 @@ static CURLcode smtp_state_authlogin_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
- size_t l;
- char * authuser;
+ size_t l = 0;
+ char * authuser = NULL;
(void)instate; /* no use for this yet */
@@ -614,16 +618,16 @@ static CURLcode smtp_state_authlogin_resp(struct connectdata *conn,
result = CURLE_LOGIN_DENIED;
}
else {
- l = smtp_auth_login_user(conn, &authuser);
+ result = smtp_auth_login_user(conn, &authuser, &l);
- if(!l)
- result = CURLE_OUT_OF_MEMORY;
- else {
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authuser);
- free(authuser);
+ if(!result) {
+ if(authuser) {
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authuser);
- if(!result)
- state(conn, SMTP_AUTHPASSWD);
+ if(!result)
+ state(conn, SMTP_AUTHPASSWD);
+ }
+ Curl_safefree(authuser);
}
}
@@ -638,8 +642,8 @@ static CURLcode smtp_state_authpasswd_resp(struct connectdata *conn,
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
size_t plen;
- size_t l;
- char *authpasswd;
+ size_t l = 0;
+ char *authpasswd = NULL;
(void)instate; /* no use for this yet */
@@ -653,16 +657,16 @@ static CURLcode smtp_state_authpasswd_resp(struct connectdata *conn,
if(!plen)
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "=");
else {
- l = Curl_base64_encode(data, conn->passwd, plen, &authpasswd);
+ result = Curl_base64_encode(data, conn->passwd, plen, &authpasswd, &l);
- if(!l)
- result = CURLE_OUT_OF_MEMORY;
- else {
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authpasswd);
- free(authpasswd);
+ if(!result) {
+ if(authpasswd) {
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authpasswd);
- if(!result)
- state(conn, SMTP_AUTH);
+ if(!result)
+ 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;
unsigned char * chlg;
size_t chlglen;
- size_t l;
- char * rplyb64;
+ size_t l = 0;
+ char * rplyb64 = NULL;
HMAC_context * ctxt;
unsigned char digest[16];
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) {
chlg64[l] = '\0';
- chlglen = Curl_base64_decode(chlg64, &chlg);
- if(!chlglen)
- return CURLE_OUT_OF_MEMORY;
+ result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+ if(result)
+ return result;
}
}
@@ -723,17 +727,14 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
(unsigned int)(strlen(conn->passwd)));
if(!ctxt) {
- if(chlg)
- free(chlg);
-
+ Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY;
}
if(chlglen > 0)
Curl_HMAC_update(ctxt, chlg, (unsigned int)(chlglen));
- if(chlg)
- free(chlg);
+ Curl_safefree(chlg);
Curl_HMAC_final(ctxt, digest);
@@ -746,16 +747,16 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,
digest[12], digest[13], digest[14], digest[15]);
/* 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)
- result = CURLE_OUT_OF_MEMORY;
- else {
- result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
- free(rplyb64);
+ if(!result) {
+ if(rplyb64) {
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
- if(!result)
- state(conn, SMTP_AUTH);
+ if(!result)
+ state(conn, SMTP_AUTH);
+ }
+ Curl_safefree(rplyb64);
}
return result;
diff --git a/lib/warnless.c b/lib/warnless.c
index 37d15ce87..0f5fb5f4d 100644
--- a/lib/warnless.c
+++ b/lib/warnless.c
@@ -268,6 +268,25 @@ size_t curlx_sotouz(curl_off_t sonum)
#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__)
int curlx_FD_ISSET(int fd, fd_set *fdset)
diff --git a/lib/warnless.h b/lib/warnless.h
index 9ac59ac29..27cf57c31 100644
--- a/lib/warnless.h
+++ b/lib/warnless.h
@@ -38,6 +38,8 @@ ssize_t curlx_uztosz(size_t uznum);
size_t curlx_sotouz(curl_off_t sonum);
+size_t curlx_sitouz(int sinum);
+
#if defined(__INTEL_COMPILER) && defined(__unix__)
int curlx_FD_ISSET(int fd, fd_set *fdset);
diff --git a/tests/server/getpart.c b/tests/server/getpart.c
index 743cb21b9..2351e1cc3 100644
--- a/tests/server/getpart.c
+++ b/tests/server/getpart.c
@@ -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
* 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) {
/* 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;
if(!src_len || !src_buf) {
/*
diff --git a/tests/unit/unit1302.c b/tests/unit/unit1302.c
index 7a61ec062..fc50c8865 100644
--- a/tests/unit/unit1302.c
+++ b/tests/unit/unit1302.c
@@ -45,63 +45,80 @@ UNITTEST_START
char *output;
unsigned char *decoded;
-size_t rc;
+size_t size = 0;
+unsigned char anychar = 'x';
+CURLcode rc;
-rc = Curl_base64_encode(data, "i", 1, &output);
-fail_unless( rc == 4 , "return code should be 4" );
+rc = Curl_base64_encode(data, "i", 1, &output, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 4, "size should be 4");
verify_memory( output, "aQ==", 4);
Curl_safefree(output);
-rc = Curl_base64_encode(data, "ii", 2, &output);
-fail_unless( rc == 4 , "return code should be 4" );
+rc = Curl_base64_encode(data, "ii", 2, &output, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 4, "size should be 4");
verify_memory( output, "aWk=", 4);
Curl_safefree(output);
-rc = Curl_base64_encode(data, "iii", 3, &output);
-fail_unless( rc == 4 , "return code should be 4" );
+rc = Curl_base64_encode(data, "iii", 3, &output, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 4, "size should be 4");
verify_memory( output, "aWlp", 4);
Curl_safefree(output);
-rc = Curl_base64_encode(data, "iiii", 4, &output);
-fail_unless( rc == 8 , "return code should be 8" );
+rc = Curl_base64_encode(data, "iiii", 4, &output, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 8, "size should be 8");
verify_memory( output, "aWlpaQ==", 8);
Curl_safefree(output);
/* 0 length makes it do strlen() */
-rc = Curl_base64_encode(data, "iiii", 0, &output);
-fail_unless( rc == 8 , "return code should be 8" );
+rc = Curl_base64_encode(data, "iiii", 0, &output, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 8, "size should be 8");
verify_memory( output, "aWlpaQ==", 8);
Curl_safefree(output);
-rc = Curl_base64_decode("aWlpaQ==", &decoded);
-fail_unless(rc == 4, "return code should be 4");
+rc = Curl_base64_decode("aWlpaQ==", &decoded, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 4, "size should be 4");
verify_memory(decoded, "iiii", 4);
Curl_safefree(decoded);
-rc = Curl_base64_decode("aWlp", &decoded);
-fail_unless(rc == 3, "return code should be 3");
+rc = Curl_base64_decode("aWlp", &decoded, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 3, "size should be 3");
verify_memory(decoded, "iii", 3);
Curl_safefree(decoded);
-rc = Curl_base64_decode("aWk=", &decoded);
-fail_unless(rc == 2, "return code should be 2");
+rc = Curl_base64_decode("aWk=", &decoded, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 2, "size should be 2");
verify_memory(decoded, "ii", 2);
Curl_safefree(decoded);
-rc = Curl_base64_decode("aQ==", &decoded);
-fail_unless(rc == 1, "return code should be 1");
+rc = Curl_base64_decode("aQ==", &decoded, &size);
+fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
+fail_unless(size == 1, "size should be 1");
verify_memory(decoded, "i", 2);
Curl_safefree(decoded);
/* this is an illegal input */
-decoded = NULL;
-rc = Curl_base64_decode("aQ", &decoded);
-fail_unless(rc == 0, "return code should be 0");
+size = 1; /* not zero */
+decoded = &anychar; /* not NULL */
+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");
/* this is garbage input that libcurl decodes as far as possible */
-rc = Curl_base64_decode("a\x1f==", &decoded);
-fail_unless(rc == 1, "return code should be 1");
+size = 0;
+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);
UNITTEST_STOP