Markus Moeller has re-implemented several of the coder functions for use
by Kerberos helpers.
This patch seeks to de-duplicate them and combine the resulting code
back into the libmiscencoding.la "base64.h" implementation.
Changes include:
* old function API renamed to old_*() and existing code update to use
the names. Some code has been updated to use the new API.
* new estimator base64_encode_len()/base64_decode_len() function added
to provide details of much much buffer space the output will require.
* new API encoder and decoder functions added which accept caller
provided buffers and encode/decode an arbitrary string into them.
* also fixes a bug where if the input text or output buffer was too
short the coder functions would crop a few bytes off the end of the result.
Some optimizations have been added by myself over and above Markus changes:
* optimized to short-circuit on several more variations of empty input
and nil result buffer.
* sub-loop optimizations added to reduce the number of if() calls made
by the new code.
* split encoder into terminated (C-str) and non-terminated variants.
I have also now documented both old and new APIs functions.
Amos
--
Please be using
Current Stable Squid 2.7.STABLE9 or 3.1.12
Beta testers wanted for 3.2.0.7 and 3.1.12.1
=== modified file 'helpers/negotiate_auth/kerberos/Makefile.am'
--- helpers/negotiate_auth/kerberos/Makefile.am 2010-08-13 12:05:25 +0000
+++ helpers/negotiate_auth/kerberos/Makefile.am 2011-04-16 15:24:58 +0000
@@ -5,17 +5,22 @@
libexec_PROGRAMS = negotiate_kerberos_auth negotiate_kerberos_auth_test
-SOURCE = negotiate_kerberos_auth.cc base64.cc base64.h
-SOURCE_test = negotiate_kerberos_auth_test.cc base64.cc base64.h
-
-negotiate_kerberos_auth_SOURCES = $(SOURCE)
AM_CPPFLAGS = $(INCLUDES) -I$(srcdir)
-negotiate_kerberos_auth_test_SOURCES = $(SOURCE_test)
-
-
+
+negotiate_kerberos_auth_SOURCES = negotiate_kerberos_auth.cc
negotiate_kerberos_auth_LDFLAGS =
-negotiate_kerberos_auth_LDADD = $(COMPAT_LIB) $(XTRA_LIBS) $(KRB5LIBS)
+negotiate_kerberos_auth_LDADD = \
+ $(top_builddir)/lib/libmiscencoding.la \
+ $(COMPAT_LIB) \
+ $(KRB5LIBS) \
+ $(XTRA_LIBS)
+
+negotiate_kerberos_auth_test_SOURCES = negotiate_kerberos_auth_test.cc
negotiate_kerberos_auth_test_LDFLAGS =
-negotiate_kerberos_auth_test_LDADD = $(COMPAT_LIB) $(XTRA_LIBS) $(KRB5LIBS)
+negotiate_kerberos_auth_test_LDADD = \
+ $(top_builddir)/lib/libmiscencoding.la \
+ $(COMPAT_LIB) \
+ $(KRB5LIBS) \
+ $(XTRA_LIBS)
man_MANS = negotiate_kerberos_auth.8
=== removed file 'helpers/negotiate_auth/kerberos/base64.cc'
--- helpers/negotiate_auth/kerberos/base64.cc 2010-11-20 11:31:38 +0000
+++ helpers/negotiate_auth/kerberos/base64.cc 1970-01-01 00:00:00 +0000
@@ -1,161 +0,0 @@
-/*
- * Markus Moeller has modified the following code from Squid
- */
-
-#include "config.h"
-#include "base64.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-static void ska_base64_init(void);
-
-static int base64_initialized = 0;
-#define BASE64_VALUE_SZ 256
-int base64_value[BASE64_VALUE_SZ];
-const char base64_code[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-
-static void
-ska_base64_init(void)
-{
- int i;
-
- for (i = 0; i < BASE64_VALUE_SZ; i++)
- base64_value[i] = -1;
-
- for (i = 0; i < 64; i++)
- base64_value[(int) base64_code[i]] = i;
- base64_value[(int) '='] = 0;
-
- base64_initialized = 1;
-}
-
-void
-ska_base64_decode(char *result, const char *data, int result_size)
-{
- int j;
- int c;
- long val;
- if (!data)
- return;
- if (!base64_initialized)
- ska_base64_init();
- val = c = 0;
-
- for (j = 0; *data; data++) {
- unsigned int k = ((unsigned char) *data) % BASE64_VALUE_SZ;
- if (base64_value[k] < 0)
- continue;
- val <<= 6;
- val += base64_value[k];
- if (++c < 4)
- continue;
- /* One quantum of four encoding characters/24 bit */
- if (j >= result_size)
- break;
- result[j++] = val >> 16; /* High 8 bits */
- if (j >= result_size)
- break;
- result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
- if (j >= result_size)
- break;
- result[j++] = val & 0xff; /* Low 8 bits */
- val = c = 0;
- }
- return;
-}
-
-/* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
-void
-ska_base64_encode(char *result, const char *data, int result_size,
- int data_size)
-{
- int bits = 0;
- int char_count = 0;
- int out_cnt = 0;
-
- if (!data)
- return;
-
- if (!base64_initialized)
- ska_base64_init();
-
- while (data_size--) {
- int c = (unsigned char) *data++;
- bits += c;
- char_count++;
- if (char_count == 3) {
- if (out_cnt >= result_size)
- break;
- result[out_cnt++] = base64_code[bits >> 18];
- if (out_cnt >= result_size)
- break;
- result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
- if (out_cnt >= result_size)
- break;
- result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
- if (out_cnt >= result_size)
- break;
- result[out_cnt++] = base64_code[bits & 0x3f];
- bits = 0;
- char_count = 0;
- } else {
- bits <<= 8;
- }
- }
- if (char_count != 0) {
- bits <<= 16 - (8 * char_count);
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = base64_code[bits >> 18];
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
- if (char_count == 1) {
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = '=';
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = '=';
- } else {
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = '=';
- }
- }
-end:
- if (out_cnt >= result_size) {
- result[result_size - 1] = '\0'; /* terminate */
- } else {
- result[out_cnt] = '\0'; /* terminate */
- }
- return;
-}
-
-int
-ska_base64_encode_len(int len)
-{
- return ((len + 2) / 3 * 4) + 1;
-}
-
-int
-ska_base64_decode_len(const char *data)
-{
- int i, j;
-
- j = 0;
- for (i = strlen(data) - 1; i >= 0; i--) {
- if (data[i] == '=')
- j++;
- if (data[i] != '=')
- break;
- }
- return strlen(data) / 4 * 3 - j;
-}
=== removed file 'helpers/negotiate_auth/kerberos/base64.h'
--- helpers/negotiate_auth/kerberos/base64.h 2010-08-14 00:12:49 +0000
+++ helpers/negotiate_auth/kerberos/base64.h 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-/*
- * Markus Moeller has modified the following code from Squid
- */
-
-void ska_base64_decode(char *result, const char *data, int result_size);
-void ska_base64_encode(char *result, const char *data, int result_size,
- int data_size);
-
-int ska_base64_encode_len(int len);
-int ska_base64_decode_len(const char *data);
=== modified file 'helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc'
--- helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 2011-03-14 06:15:51 +0000
+++ helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 2011-04-20 13:46:46 +0000
@@ -374,13 +374,12 @@
fprintf(stdout, "BH Invalid negotiate request\n");
continue;
}
- input_token.length = ska_base64_decode_len(buf + 3);
+ input_token.length = base64_decode_len(buf + 3);
debug((char *) "%s| %s: DEBUG: Decode '%s' (decoded length: %d).\n",
LogTime(), PROGRAM, buf + 3, (int) input_token.length);
input_token.value = xmalloc(input_token.length);
- ska_base64_decode((char *) input_token.value, buf + 3, input_token.length);
-
+ base64_decode((char *) input_token.value, buf + 3, input_token.length);
if ((input_token.length >= sizeof ntlmProtocol + 1) &&
(!memcmp(input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
@@ -427,14 +426,14 @@
if (output_token.length) {
spnegoToken = (const unsigned char *) output_token.value;
spnegoTokenLength = output_token.length;
- token = (char *) xmalloc(ska_base64_encode_len(spnegoTokenLength));
+ token = (char *) xmalloc(base64_encode_len(spnegoTokenLength));
if (token == NULL) {
debug((char *) "%s| %s: ERROR: Not enough memory\n", LogTime(), PROGRAM);
fprintf(stdout, "BH Not enough memory\n");
goto cleanup;
}
- ska_base64_encode(token, (const char *) spnegoToken,
- ska_base64_encode_len(spnegoTokenLength), spnegoTokenLength);
+ base64_encode_str(token, (const char *) spnegoToken,
+ base64_encode_len(spnegoTokenLength), spnegoTokenLength);
if (check_gss_err(major_status, minor_status, "gss_accept_sec_context()", log))
goto cleanup;
=== modified file 'helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc'
--- helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc 2011-03-14 06:15:51 +0000
+++ helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc 2011-04-20 13:45:51 +0000
@@ -196,9 +196,9 @@
goto cleanup;
if (output_token.length) {
- token = (char *) xmalloc(ska_base64_encode_len(output_token.length));
- ska_base64_encode(token, (const char *) output_token.value,
- ska_base64_encode_len(output_token.length), output_token.length);
+ token = (char *) xmalloc(base64_encode_len(output_token.length));
+ base64_encode_str(token, (const char *) output_token.value,
+ base64_encode_len(output_token.length), output_token.length);
}
cleanup:
gss_delete_sec_context(&minor_status, &gss_context, NULL);
=== modified file 'helpers/negotiate_auth/wrapper/Makefile.am'
--- helpers/negotiate_auth/wrapper/Makefile.am 2011-04-15 11:51:15 +0000
+++ helpers/negotiate_auth/wrapper/Makefile.am 2011-04-16 04:35:08 +0000
@@ -4,5 +4,8 @@
libexec_PROGRAMS = negotiate_wrapper_auth
-negotiate_wrapper_auth_SOURCES = negotiate_wrapper.cc nw_base64.cc nw_base64.h
-negotiate_wrapper_auth_LDADD = $(COMPAT_LIB) $(XTRA_LIBS)
+negotiate_wrapper_auth_SOURCES = negotiate_wrapper.cc
+negotiate_wrapper_auth_LDADD = \
+ $(top_builddir)/lib/libmiscencoding.la \
+ $(COMPAT_LIB) \
+ $(XTRA_LIBS)
=== modified file 'helpers/negotiate_auth/wrapper/negotiate_wrapper.cc'
--- helpers/negotiate_auth/wrapper/negotiate_wrapper.cc 2011-04-19 13:20:31 +0000
+++ helpers/negotiate_auth/wrapper/negotiate_wrapper.cc 2011-04-20 06:11:07 +0000
@@ -26,7 +26,7 @@
*/
#include "config.h"
-#include "nw_base64.h"
+#include "base64.h"
#if HAVE_STRING_H
#include <string.h>
@@ -346,7 +346,7 @@
fprintf(stdout, "BH Invalid negotiate request\n");
continue;
}
- length = nw_base64_decode_len(buf + 3);
+ length = base64_decode_len(buf + 3);
if (debug)
fprintf(stderr, "%s| %s: Decode '%s' (decoded length: %d).\n",
LogTime(), PROGRAM, buf + 3, (int) length);
@@ -356,7 +356,7 @@
return 1;
}
- nw_base64_decode(token, buf + 3, length);
+ base64_decode(token, buf + 3, length);
if ((static_cast<size_t>(length) >= sizeof(ntlmProtocol) + 1) &&
(!memcmp(token, ntlmProtocol, sizeof ntlmProtocol))) {
=== removed file 'helpers/negotiate_auth/wrapper/nw_base64.cc'
--- helpers/negotiate_auth/wrapper/nw_base64.cc 2011-04-16 14:43:18 +0000
+++ helpers/negotiate_auth/wrapper/nw_base64.cc 1970-01-01 00:00:00 +0000
@@ -1,83 +0,0 @@
-/*
- * Markus Moeller has modified the following code from Squid
- */
-#include "config.h"
-#include "nw_base64.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-static void nw_base64_init(void);
-
-static int base64_initialized = 0;
-#define BASE64_VALUE_SZ 256
-int base64_value[BASE64_VALUE_SZ];
-const char base64_code[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-
-static void
-nw_base64_init(void)
-{
- int i;
-
- for (i = 0; i < BASE64_VALUE_SZ; i++)
- base64_value[i] = -1;
-
- for (i = 0; i < 64; i++)
- base64_value[(int) base64_code[i]] = i;
- base64_value[(int)'='] = 0;
-
- base64_initialized = 1;
-}
-
-void
-nw_base64_decode(char *result, const char *data, int result_size)
-{
- int j;
- int c;
- long val;
- if (!data)
- return;
- if (!base64_initialized)
- nw_base64_init();
- val = c = 0;
-
- for (j = 0; *data; data++) {
- unsigned int k = ((unsigned char) *data) % BASE64_VALUE_SZ;
- if (base64_value[k] < 0)
- continue;
- val <<= 6;
- val += base64_value[k];
- if (++c < 4)
- continue;
- /* One quantum of four encoding characters/24 bit */
- if (j >= result_size)
- break;
- result[j++] = val >> 16; /* High 8 bits */
- if (j >= result_size)
- break;
- result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
- if (j >= result_size)
- break;
- result[j++] = val & 0xff; /* Low 8 bits */
- val = c = 0;
- }
- return;
-}
-
-int
-nw_base64_decode_len(const char *data)
-{
- int i, j;
-
- j = 0;
- for (i = strlen(data) - 1; i >= 0; i--) {
- if (data[i] == '=')
- j++;
- if (data[i] != '=')
- break;
- }
- return strlen(data) / 4 * 3 - j;
-}
=== removed file 'helpers/negotiate_auth/wrapper/nw_base64.h'
--- helpers/negotiate_auth/wrapper/nw_base64.h 2011-04-15 11:51:15 +0000
+++ helpers/negotiate_auth/wrapper/nw_base64.h 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
-#ifndef _NW_BASE64_H
-#define _NW_BASE64_H
-
-/*
- * Markus Moeller has modified the following code from Squid
- */
-
-void nw_base64_decode(char *result, const char *data, int result_size);
-int nw_base64_decode_len(const char *data);
-
-#endif
=== modified file 'helpers/ntlm_auth/fake/ntlm_fake_auth.cc'
--- helpers/ntlm_auth/fake/ntlm_fake_auth.cc 2011-01-25 21:30:11 +0000
+++ helpers/ntlm_auth/fake/ntlm_fake_auth.cc 2011-04-19 02:43:57 +0000
@@ -174,7 +174,7 @@
*p = '\0'; /* strip \n */
buflen = strlen(buf); /* keep this so we only scan the buffer for \0 once per loop */
if (buflen > 3)
- packet = (ntlmhdr*)base64_decode(buf + 3);
+ packet = (ntlmhdr*)old_base64_decode(buf + 3);
if (buflen > 3 && NTLM_packet_debug_enabled) {
strncpy(helper_command, buf, 2);
helper_command[2] = '\0';
=== modified file 'helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc'
--- helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc 2011-04-09 02:37:59 +0000
+++ helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc 2011-04-16 13:28:41 +0000
@@ -525,9 +525,9 @@
if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */
/* figure out what we got */
- decoded = base64_decode(buf + 3);
+ decoded = old_base64_decode(buf + 3);
/* Note: we don't need to manage memory at this point, since
- * base64_decode returns a pointer to static storage.
+ * old_base64_decode returns a pointer to static storage.
*/
if (!decoded) { /* decoding failure, return error */
=== modified file 'include/base64.h'
--- include/base64.h 2010-11-02 00:12:43 +0000
+++ include/base64.h 2011-04-20 13:47:45 +0000
@@ -5,10 +5,53 @@
extern "C" {
#endif
- extern char *base64_decode(const char *coded);
- extern const char *base64_encode(const char *decoded);
+ // Decoding functions
+
+ /// Calculate the decoded length of a given nul-terminated blob.
+ /// NUL pointer and empty strings are accepted, result is zero.
+ /// Any return value <= zero means no decoded result can be produced.
+ extern int base64_decode_len(const char *data);
+
+ /// Decode a base-64 encoded blob into a provided buffer.
+ /// Will not terminate the resulting string.
+ /// In-place decoding overlap is supported if result is equal or earlier that the source pointer.
+ ///
+ /// \return number of bytes filled in result.
+ extern int base64_decode(char *result, const char *p, unsigned int result_size);
+
+ // Old decoder. Now a wrapper for the new.
+ // Output is presented in a static buffer which will only remain valid until next call.
+ // Ensures a nul-terminated result. Will always return non-NULL.
+ extern char *old_base64_decode(const char *coded);
+
+
+ // Encoding functions
+
+ /// Calculate the buffer size required to hold the encoded form of a string of length 'len'.
+ extern int base64_encode_len(int len);
+
+ /// Base-64 encode a string into a given buffer.
+ /// Will not terminate the resulting string.
+ /// \return the number of bytes filled in result.
+ extern int base64_encode(char *result, const char *data, int result_size, int data_size);
+
+ /// Base-64 encode a string into a given buffer.
+ /// Will terminate the resulting string.
+ /// \return the number of bytes filled in result. Including the terminator.
+ extern int base64_encode_str(char *result, const char *data, int result_size, int data_size);
+
+ /// Base-64 encode a binary array.
+ /// Output is presented in a static buffer which will only remain valid until next call.
+ /// Ensures a nul-terminated result. Will always return non-NULL.
extern const char *base64_encode_bin(const char *data, int len);
+ // Old decoder. Now a wrapper for the new.
+ // Output is presented in a static buffer which will only remain valid until next call.
+ // Ensures a nul-terminated result. Will always return non-NULL.
+ // Will terminate the resulting string.
+ extern const char *old_base64_encode(const char *decoded);
+
+
#ifdef __cplusplus
}
#endif
=== modified file 'lib/base64.c'
--- lib/base64.c 2010-11-01 05:44:28 +0000
+++ lib/base64.c 2011-04-28 04:57:44 +0000
@@ -1,5 +1,10 @@
/*
* $Id$
+ *
+ * AUTHOR: Unknown
+ * AUTHOR: Markus Moeller
+ *
+ * Encoders adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments.
*/
#include "config.h"
@@ -37,19 +42,49 @@
base64_initialized = 1;
}
+int
+base64_decode_len(const char *data)
+{
+ int i, j;
+
+ if (!data || !*data)
+ return 0;
+
+ j = 0;
+ for (i = strlen(data) - 1; i >= 0; i--) {
+ if (data[i] == '=')
+ j++;
+ if (data[i] != '=')
+ break;
+ }
+ return strlen(data) / 4 * 3 - j;
+}
+
+// old version. Wrapper for the new.
char *
-base64_decode(const char *p)
+old_base64_decode(const char *p)
{
static char result[BASE64_RESULT_SZ];
- int j;
- int c;
- long val;
+ memset(result, '\0', sizeof(result));
if (!p)
return NULL;
+ base64_decode(result, p, sizeof(result));
+ result[BASE64_RESULT_SZ-1] = '\0';
+ return result;
+}
+
+int
+base64_decode(char *result, const char *p, unsigned int result_size)
+{
+ int j = 0;
+ int c;
+ long val;
+ if (!p || !result || result_size == 0)
+ return j;
if (!base64_initialized)
base64_init();
val = c = 0;
- for (j = 0; *p && j + 4 < BASE64_RESULT_SZ; p++) {
+ for (; *p; p++) {
unsigned int k = ((unsigned char) *p) % BASE64_VALUE_SZ;
if (base64_value[k] < 0)
continue;
@@ -58,39 +93,95 @@
if (++c < 4)
continue;
/* One quantum of four encoding characters/24 bit */
- result[j++] = (val >> 16) & 0xff; /* High 8 bits */
- result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
- result[j++] = val & 0xff; /* Low 8 bits */
+ if (j+4 <= result_size) {
+ // Speed optimization: plenty of space, avoid some per-byte checks.
+ result[j++] = (val >> 16) & 0xff; /* High 8 bits */
+ result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
+ result[j++] = val & 0xff; /* Low 8 bits */
+ } else {
+ // part-quantum goes a bit slower with per-byte checks
+ result[j++] = (val >> 16) & 0xff; /* High 8 bits */
+ if (j == result_size)
+ return j;
+ result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
+ if (j == result_size)
+ return j;
+ result[j++] = val & 0xff; /* Low 8 bits */
+ }
+ if (j == result_size)
+ return j;
val = c = 0;
}
- result[j] = 0;
- return result;
-}
-
-/* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
+ return j;
+}
+
+int
+base64_encode_len(int len)
+{
+ return ((len + 2) / 3 * 4) + 1;
+}
+
const char *
-base64_encode(const char *decoded_str)
+old_base64_encode(const char *decoded_str)
{
static char result[BASE64_RESULT_SZ];
+ base64_encode_str(result, decoded_str, sizeof(result), strlen(decoded_str));
+ return result;
+}
+
+int
+base64_encode_str(char *result, const char *data, int result_size, int data_size)
+{
+ int used = base64_encode(result, data, result_size, data_size);
+ /* terminate */
+ if (used >= result_size) {
+ result[result_size - 1] = '\0';
+ return result_size;
+ } else {
+ result[used++] = '\0';
+ }
+ return used;
+}
+
+/* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
+int
+base64_encode(char *result, const char *data, int result_size, int data_size)
+{
int bits = 0;
int char_count = 0;
int out_cnt = 0;
- int c;
- if (!decoded_str)
- return decoded_str;
+ if (!data || !*data || !result || result_size < 1 || data_size < 1)
+ return 0;
if (!base64_initialized)
base64_init();
- while ((c = (unsigned char) *decoded_str++) && out_cnt < sizeof(result) - 5) {
+ while (data_size--) {
+ int c = (unsigned char) *data++;
bits += c;
char_count++;
if (char_count == 3) {
- result[out_cnt++] = base64_code[bits >> 18];
- result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
- result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
- result[out_cnt++] = base64_code[bits & 0x3f];
+ if (out_cnt >= result_size)
+ break;
+ if (out_cnt+4 <= result_size) {
+ result[out_cnt++] = base64_code[bits >> 18];
+ result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
+ result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
+ result[out_cnt++] = base64_code[bits & 0x3f];
+ } else {
+ // part-quantum goes a bit slower with per-byte checks
+ result[out_cnt++] = base64_code[bits >> 18];
+ if (out_cnt >= result_size)
+ break;
+ result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
+ if (out_cnt >= result_size)
+ break;
+ result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
+ if (out_cnt >= result_size)
+ break;
+ result[out_cnt++] = base64_code[bits & 0x3f];
+ }
bits = 0;
char_count = 0;
} else {
@@ -99,18 +190,29 @@
}
if (char_count != 0) {
bits <<= 16 - (8 * char_count);
+ if (out_cnt >= result_size)
+ return result_size;
result[out_cnt++] = base64_code[bits >> 18];
+ if (out_cnt >= result_size)
+ return result_size;
result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
if (char_count == 1) {
+ if (out_cnt >= result_size)
+ return result_size;
result[out_cnt++] = '=';
+ if (out_cnt >= result_size)
+ return result_size;
result[out_cnt++] = '=';
} else {
+ if (out_cnt >= result_size)
+ return result_size;
result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
+ if (out_cnt >= result_size)
+ return result_size;
result[out_cnt++] = '=';
}
}
- result[out_cnt] = '\0'; /* terminate */
- return result;
+ return (out_cnt >= result_size?result_size:out_cnt);
}
/* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
=== modified file 'src/HttpHeader.cc'
--- src/HttpHeader.cc 2011-03-22 12:23:25 +0000
+++ src/HttpHeader.cc 2011-04-16 13:25:52 +0000
@@ -1414,7 +1414,7 @@
if (!*field) /* no authorization cookie */
return NULL;
- return base64_decode(field);
+ return old_base64_decode(field);
}
ETag
=== modified file 'src/adaptation/icap/ModXact.cc'
--- src/adaptation/icap/ModXact.cc 2011-04-07 12:42:02 +0000
+++ src/adaptation/icap/ModXact.cc 2011-04-16 15:38:01 +0000
@@ -1425,7 +1425,7 @@
if (request->auth_user_request != NULL) {
char const *name = request->auth_user_request->username();
if (name) {
- const char *value = TheConfig.client_username_encode ? base64_encode(name) : name;
+ const char *value = TheConfig.client_username_encode ? old_base64_encode(name) : name;
buf.Printf("%s: %s\r\n", TheConfig.client_username_header, value);
}
}
=== modified file 'src/http.cc'
--- src/http.cc 2011-04-06 16:25:36 +0000
+++ src/http.cc 2011-04-16 15:38:59 +0000
@@ -1606,7 +1606,7 @@
snprintf(loginbuf, sizeof(loginbuf), "%s%s", username, orig_request->peer_login + 1);
httpHeaderPutStrf(hdr_out, header, "Basic %s",
- base64_encode(loginbuf));
+ old_base64_encode(loginbuf));
return;
}
@@ -1619,7 +1619,7 @@
SQUIDSTRINGPRINT(orig_request->extacl_user),
SQUIDSTRINGPRINT(orig_request->extacl_passwd));
httpHeaderPutStrf(hdr_out, header, "Basic %s",
- base64_encode(loginbuf));
+ old_base64_encode(loginbuf));
return;
}
@@ -1640,7 +1640,7 @@
#endif /* HAVE_KRB5 && HAVE_GSSAPI */
httpHeaderPutStrf(hdr_out, header, "Basic %s",
- base64_encode(orig_request->peer_login));
+ old_base64_encode(orig_request->peer_login));
return;
}
@@ -1771,7 +1771,7 @@
if (!hdr_out->has(HDR_AUTHORIZATION)) {
if (!request->flags.proxying && *request->login) {
httpHeaderPutStrf(hdr_out, HDR_AUTHORIZATION, "Basic %s",
- base64_encode(request->login));
+ old_base64_encode(request->login));
}
}
=== modified file 'tools/cachemgr.cc'
--- tools/cachemgr.cc 2011-04-12 11:33:32 +0000
+++ tools/cachemgr.cc 2011-04-20 13:44:10 +0000
@@ -1053,16 +1053,17 @@
return;
/* host | time | user | passwd */
- snprintf(buf, sizeof(buf), "%s|%d|%s|%s",
- req->hostname,
- (int) now,
- req->user_name ? req->user_name : "",
- req->passwd);
-
+ int blen = snprintf(buf, sizeof(buf), "%s|%d|%s|%s",
+ req->hostname,
+ (int) now,
+ req->user_name ? req->user_name : "",
+ req->passwd);
debug("cmgr: pre-encoded for pub: %s\n", buf);
- debug("cmgr: encoded: '%s'\n", base64_encode(buf));
- req->pub_auth = xstrdup(base64_encode(buf));
+ int elen = base64_encode_len(blen);
+ req->pub_auth = (char *) xmalloc(elen);
+ base64_encode_str(req->pub_auth, buf, elen, blen);
+ debug("cmgr: encoded: '%s'\n", req->pub_auth);
}
static void
@@ -1080,7 +1081,9 @@
if (!req->pub_auth || strlen(req->pub_auth) < 4 + strlen(safe_str(req->hostname)))
return;
- buf = xstrdup(base64_decode(req->pub_auth));
+ int alen = base64_decode_len(req->pub_auth);
+ buf = (char*)xmalloc(alen);
+ base64_decode(buf, req->pub_auth, sizeof(req->pub_auth));
debug("cmgr: length ok\n");
@@ -1136,16 +1139,18 @@
{
static char buf[1024];
size_t stringLength = 0;
- const char *str64;
if (!req->passwd)
return "";
- snprintf(buf, sizeof(buf), "%s:%s",
- req->user_name ? req->user_name : "",
- req->passwd);
+ int blen = snprintf(buf, sizeof(buf), "%s:%s",
+ req->user_name ? req->user_name : "",
+ req->passwd);
- str64 = base64_encode(buf);
+ int alen = base64_encode_len(blen);
+ char *str64 = static_cast<char*>(xmalloc(alen));
+ if (base64_encode_str(str64, buf, alen, blen) == 0)
+ return "";
stringLength += snprintf(buf, sizeof(buf), "Authorization: Basic %s\r\n", str64);
=== modified file 'tools/squidclient.cc'
--- tools/squidclient.cc 2011-02-17 14:57:33 +0000
+++ tools/squidclient.cc 2011-04-16 15:41:44 +0000
@@ -489,7 +489,7 @@
exit(1);
}
snprintf(buf, BUFSIZ, "%s:%s", user, password);
- snprintf(buf, BUFSIZ, "Proxy-Authorization: Basic %s\r\n", base64_encode(buf));
+ snprintf(buf, BUFSIZ, "Proxy-Authorization: Basic %s\r\n", old_base64_encode(buf));
strcat(msg, buf);
}
if (www_user) {
@@ -504,7 +504,7 @@
exit(1);
}
snprintf(buf, BUFSIZ, "%s:%s", user, password);
- snprintf(buf, BUFSIZ, "Authorization: Basic %s\r\n", base64_encode(buf));
+ snprintf(buf, BUFSIZ, "Authorization: Basic %s\r\n", old_base64_encode(buf));
strcat(msg, buf);
}
#if HAVE_GSSAPI