aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/base64.c22
-rw-r--r--lib/base64.h2
-rw-r--r--lib/http_negotiate.c7
-rw-r--r--lib/http_ntlm.c8
-rw-r--r--lib/krb4.c22
-rw-r--r--tests/server/getpart.c7
6 files changed, 45 insertions, 23 deletions
diff --git a/lib/base64.c b/lib/base64.c
index 7cb66c5c4..54e4ed5d7 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -76,10 +76,10 @@ static void decodeQuantum(unsigned char *dest, const char *src)
/*
* Curl_base64_decode()
*
- * Given a base64 string at src, decode it into the memory pointed to by
- * dest. Returns the length of the decoded data.
+ * Given a base64 string at src, decode it and return an allocated memory in
+ * the *outptr. Returns the length of the decoded data.
*/
-size_t Curl_base64_decode(const char *src, char *dest)
+size_t Curl_base64_decode(const char *src, unsigned char **outptr)
{
int length = 0;
int equalsTerm = 0;
@@ -87,6 +87,9 @@ size_t Curl_base64_decode(const char *src, char *dest)
int numQuantums;
unsigned char lastQuantum[3];
size_t rawlen=0;
+ unsigned char *newstr;
+
+ *outptr = NULL;
while((src[length] != '=') && src[length])
length++;
@@ -97,15 +100,22 @@ size_t Curl_base64_decode(const char *src, char *dest)
rawlen = (numQuantums * 3) - equalsTerm;
+ newstr = malloc(rawlen+1);
+ if(!newstr)
+ return 0;
+
+ *outptr = newstr;
+
for(i = 0; i < numQuantums - 1; i++) {
- decodeQuantum((unsigned char *)dest, src);
- dest += 3; src += 4;
+ decodeQuantum((unsigned char *)newstr, src);
+ newstr += 3; src += 4;
}
decodeQuantum(lastQuantum, src);
for(i = 0; i < 3 - equalsTerm; i++)
- dest[i] = lastQuantum[i];
+ newstr[i] = lastQuantum[i];
+ newstr[i] = 0; /* zero terminate */
return rawlen;
}
diff --git a/lib/base64.h b/lib/base64.h
index 4f49f72d4..af8a59dc1 100644
--- a/lib/base64.h
+++ b/lib/base64.h
@@ -23,5 +23,5 @@
* $Id$
***************************************************************************/
size_t Curl_base64_encode(const char *input, size_t size, char **str);
-size_t Curl_base64_decode(const char *source, char *dest);
+size_t Curl_base64_decode(const char *source, unsigned char **outptr);
#endif
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 43f1da44b..68f769913 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -166,12 +166,7 @@ int Curl_input_negotiate(struct connectdata *conn, char *header)
len = strlen(header);
if (len > 0) {
- int rawlen;
- input_token.length = (len+3)/4 * 3;
- input_token.value = malloc(input_token.length);
- if (input_token.value == NULL)
- return ENOMEM;
- rawlen = Curl_base64_decode(header, input_token.value);
+ int rawlen = Curl_base64_decode(header, &input_token.value);
if (rawlen < 0)
return -1;
input_token.length = rawlen;
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index 62f1e7ef2..63a1126f9 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -123,17 +123,17 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
32 (48) start of data block
*/
size_t size;
- unsigned char *buffer = (unsigned char *)malloc(strlen(header));
- if (buffer == NULL)
+ unsigned char *buffer;
+ size = Curl_base64_decode(header, &buffer);
+ if(!buffer)
return CURLNTLM_BAD;
- size = Curl_base64_decode(header, (char *)buffer);
-
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
if(size >= 48)
/* the nonce of interest is index [24 .. 31], 8 bytes */
memcpy(ntlm->nonce, &buffer[24], 8);
+ /* FIX: add an else here! */
/* at index decimal 20, there's a 32bit NTLM flag field */
diff --git a/lib/krb4.c b/lib/krb4.c
index 37da95df3..7b04828ab 100644
--- a/lib/krb4.c
+++ b/lib/krb4.c
@@ -199,6 +199,7 @@ krb4_auth(void *app_data, struct connectdata *conn)
{
int ret;
char *p;
+ unsigned char *ptr;
int len;
KTEXT_ST adat;
MSG_DAT msg_data;
@@ -275,11 +276,17 @@ krb4_auth(void *app_data, struct connectdata *conn)
return AUTH_ERROR;
}
p += 5;
- len = Curl_base64_decode(p, (char *)adat.dat);
- if(len < 0) {
+ len = Curl_base64_decode(p, &ptr);
+ if(len > sizeof(adat.dat)-1) {
+ free(ptr);
+ len=0;
+ }
+ if(!len || !ptr) {
Curl_failf(data, "Failed to decode base64 from server");
return AUTH_ERROR;
}
+ memcpy((char *)adat.dat, ptr, len);
+ free(ptr);
adat.length = len;
ret = krb_rd_safe(adat.dat, adat.length, &d->key,
(struct sockaddr_in *)hisctladdr,
@@ -321,6 +328,7 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
ssize_t nread;
int save;
CURLcode result;
+ unsigned char *ptr;
save = Curl_set_command_prot(conn, prot_private);
@@ -346,12 +354,18 @@ CURLcode Curl_krb_kauth(struct connectdata *conn)
}
p += 2;
- tmp = Curl_base64_decode(p, (char *)tkt.dat);
- if(tmp < 0) {
+ tmp = Curl_base64_decode(p, &ptr);
+ if(len > sizeof(tkt.dat)-1) {
+ free(ptr);
+ len=0;
+ }
+ if(!len || !ptr) {
Curl_failf(conn->data, "Failed to decode base64 in reply.\n");
Curl_set_command_prot(conn, save);
return CURLE_FTP_WEIRD_SERVER_REPLY;
}
+ memcpy((char *)tkt.dat, ptr, tmp);
+ free(ptr);
tkt.length = tmp;
tktcopy.length = tkt.length;
diff --git a/tests/server/getpart.c b/tests/server/getpart.c
index 45576fafd..fa0f9cf52 100644
--- a/tests/server/getpart.c
+++ b/tests/server/getpart.c
@@ -61,11 +61,11 @@ char *appendstring(char *string, /* original string */
{
size_t len = strlen(buffer);
size_t needed_len = len + *stringlen + 1;
- char buf64[256]; /* big enough? */
+ unsigned char *buf64=NULL;
if(base64) {
/* decode the given buffer first */
- len = Curl_base64_decode(buffer, buf64); /* updated len */
+ len = Curl_base64_decode(buffer, &buf64); /* updated len */
buffer = buf64;
needed_len = len + *stringlen + 1; /* recalculate */
}
@@ -87,6 +87,9 @@ char *appendstring(char *string, /* original string */
*stringlen += len;
string[*stringlen]=0;
+ if(buf64)
+ free(buf64);
+
return string;
}