diff options
-rw-r--r-- | lib/base64.c | 22 | ||||
-rw-r--r-- | lib/base64.h | 2 | ||||
-rw-r--r-- | lib/http_negotiate.c | 7 | ||||
-rw-r--r-- | lib/http_ntlm.c | 8 | ||||
-rw-r--r-- | lib/krb4.c | 22 | ||||
-rw-r--r-- | tests/server/getpart.c | 7 |
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; } |