On 01/05/11 22:49, Markus Moeller wrote:
Hi Amos,

Sure. How do I get the changes ?

Markus


Did you not get the .patch file attached to the earlier email?
(attaching again anyways)

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/SSPI/negotiate_sspi_auth.cc'
--- helpers/negotiate_auth/SSPI/negotiate_sspi_auth.cc	2010-07-05 09:59:15 +0000
+++ helpers/negotiate_auth/SSPI/negotiate_sspi_auth.cc	2011-04-30 11:38:02 +0000
@@ -121,9 +121,11 @@
 manage_request()
 {
     char buf[HELPER_INPUT_BUFFER];
+    char decoded[HELPER_INPUT_BUFFER];
+    int decodedLen;
     char helper_command[3];
-    char *c, *decoded;
-    int plen, status;
+    char *c;
+    int status;
     int oversized = 0;
     char *ErrorMessage;
     static char cred[SSP_MAX_CRED_LEN + 1];
@@ -148,26 +150,22 @@
     }
 
     if ((strlen(buf) > 3) && Negotiate_packet_debug_enabled) {
-        decoded = base64_decode(buf + 3);
+        decodedLen = base64_decode(decoded, sizeof(decoded), buf+3);
         strncpy(helper_command, buf, 2);
         debug("Got '%s' from Squid with data:\n", helper_command);
-        hex_dump(decoded, ((strlen(buf) - 3) * 3) / 4);
+        hex_dump(decoded, decodedLen);
     } else
         debug("Got '%s' from Squid\n", buf);
 
     if (memcmp(buf, "YR ", 3) == 0) {	/* refresh-request */
         /* figure out what we got */
         decoded = base64_decode(buf + 3);
-        /*  Note: we don't need to manage memory at this point, since
-         *  base64_decode returns a pointer to static storage.
-         */
-        if (!decoded) {		/* decoding failure, return error */
+        if (decodedLen < sizeof(ntlmhdr)) {		/* decoding failure, return error */
             SEND("NA * Packet format error, couldn't base64-decode");
             return 1;
         }
         /* Obtain server blob against SSPI */
-        plen = (strlen(buf) - 3) * 3 / 4;	/* we only need it here. Optimization */
-        c = (char *) SSP_MakeNegotiateBlob(decoded, plen, &Done, &status, cred);
+        c = (char *) SSP_MakeNegotiateBlob(decoded, decodedLen, &Done, &status, cred);
 
         if (status == SSP_OK) {
             if (Done) {
@@ -175,10 +173,10 @@
                 have_serverblob = 0;
                 Done = FALSE;
                 if (Negotiate_packet_debug_enabled) {
-                    decoded = base64_decode(c);
+                    decodedLen = base64_decode(decoded, sizeof(decoded), c);
                     debug("sending 'AF' %s to squid with data:\n", cred);
                     if (c != NULL)
-                        hex_dump(decoded, (strlen(c) * 3) / 4);
+                        hex_dump(decoded, decodedLen);
                     else
                         fprintf(stderr, "No data available.\n");
                     printf("AF %s %s\n", c, cred);
@@ -186,9 +184,9 @@
                     SEND3("AF %s %s", c, cred);
             } else {
                 if (Negotiate_packet_debug_enabled) {
-                    decoded = base64_decode(c);
+                    decodedLen = base64_decode(decoded, sizeof(decoded), c);
                     debug("sending 'TT' to squid with data:\n");
-                    hex_dump(decoded, (strlen(c) * 3) / 4);
+                    hex_dump(decoded, decodedLen);
                     printf("TT %s\n", c);
                 } else {
                     SEND2("TT %s", c);
@@ -205,17 +203,13 @@
             return 1;
         }
         /* figure out what we got */
-        decoded = base64_decode(buf + 3);
-        /*  Note: we don't need to manage memory at this point, since
-         *  base64_decode returns a pointer to static storage.
-         */
-        if (!decoded) {		/* decoding failure, return error */
+        decodedLen = base64_decode(decoded, sizeof(decoded), buf+3);
+        if (decodedLen < sizeof(ntlmhdr)) {		/* decoding failure, return error */
             SEND("NA * Packet format error, couldn't base64-decode");
             return 1;
         }
         /* check against SSPI */
-        plen = (strlen(buf) - 3) * 3 / 4;	/* we only need it here. Optimization */
-        c = (char *) SSP_ValidateNegotiateCredentials(decoded, plen, &Done, &status, cred);
+        c = (char *) SSP_ValidateNegotiateCredentials(decoded, decodedLen, &Done, &status, cred);
 
         if (status == SSP_ERROR) {
             FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
@@ -239,10 +233,10 @@
             have_serverblob = 0;
             Done = FALSE;
             if (Negotiate_packet_debug_enabled) {
-                decoded = base64_decode(c);
+                decodedLen = base64_decode(decoded, sizeof(decoded), c);
                 debug("sending 'AF' %s to squid with data:\n", cred);
                 if (c != NULL)
-                    hex_dump(decoded, (strlen(c) * 3) / 4);
+                    hex_dump(decoded, decodedLen);
                 else
                     fprintf(stderr, "No data available.\n");
                 printf("AF %s %s\n", c, cred);
@@ -252,9 +246,9 @@
             return 1;
         } else {
             if (Negotiate_packet_debug_enabled) {
-                decoded = base64_decode(c);
+                decodedLen = base64_decode(decoded, sizeof(decoded), c);
                 debug("sending 'TT' to squid with data:\n");
-                hex_dump(decoded, (strlen(c) * 3) / 4);
+                hex_dump(decoded, decodedLen);
                 printf("TT %s\n", c);
             } else
                 SEND2("TT %s", c);

=== 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-30 13:50:39 +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);
-
+        input_token.length = base64_decode((char *) input_token.value, input_token.length, buf+3);
 
         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, base64_encode_len(spnegoTokenLength),
+                              (const char *) spnegoToken, 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-30 13:50:07 +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, base64_encode_len(output_token.length),
+                          (const char *) output_token.value, 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-30 11:31:02 +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);
+        length = base64_decode(token, length, buf+3);
 
         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/SSPI/ntlm_sspi_auth.cc'
--- helpers/ntlm_auth/SSPI/ntlm_sspi_auth.cc	2010-07-06 12:44:06 +0000
+++ helpers/ntlm_auth/SSPI/ntlm_sspi_auth.cc	2011-04-30 11:39:10 +0000
@@ -415,9 +415,10 @@
 {
     ntlmhdr *fast_header;
     char buf[BUFFER_SIZE];
+    char decoded[BUFFER_SIZE];
+    int decodedLen;
     char helper_command[3];
-    char *c, *decoded, *cred;
-    int plen;
+    char *c, *cred;
     int oversized = 0;
     char * ErrorMessage;
     static ntlm_negotiate local_nego;
@@ -454,24 +455,22 @@
         goto try_again;
     }
     if ((strlen(buf) > 3) && NTLM_packet_debug_enabled) {
-        decoded = base64_decode(buf + 3);
+        decodedLen = base64_decode(decoded, sizeof(decoded), buf+3);
         strncpy(helper_command, buf, 2);
         debug("Got '%s' from Squid with data:\n", helper_command);
-        hex_dump(decoded, ((strlen(buf) - 3) * 3) / 4);
+        hex_dump(decoded, decodedLen);
     } else
         debug("Got '%s' from Squid\n", buf);
     if (memcmp(buf, "YR", 2) == 0) {	/* refresh-request */
         /* figure out what we got */
         if (strlen(buf) > 3)
-            decoded = base64_decode(buf + 3);
+            decodedLen = base64_decode(decoded, sizeof(decoded), buf+3);
         else {
             debug("Negotiate packet not supplied - self generated\n");
-            decoded = (char *) &local_nego;
+            memcpy(decoded, local_lego, sizeof(local_nego));
+            decodedLen = sizeof(localnego);
         }
-        /* Note: we don't need to manage memory at this point, since
-         *  base64_decode returns a pointer to static storage.
-         */
-        if (!decoded) {		/* decoding failure, return error */
+        if (decodedLen < sizeof(ntlmhdr)) {		/* decoding failure, return error */
             SEND("NA Packet format error, couldn't base64-decode");
             return 1;
         }
@@ -486,17 +485,13 @@
         switch (fast_header->type) {
         case NTLM_NEGOTIATE:
             /* Obtain challenge against SSPI */
-            if (strlen(buf) > 3)
-                plen = (strlen(buf) - 3) * 3 / 4;		/* we only need it here. Optimization */
-            else
-                plen = sizeof(ntlmhdr) + sizeof uint32_t); /* local_nego only has header and flags set. */
                 debug("attempting SSPI challenge retrieval\n");
-                if ((c = (char *) SSP_MakeChallenge((ntlm_negotiate *) decoded, plen)) != NULL ) {
+                if ((c = (char *) SSP_MakeChallenge((ntlm_negotiate *) decoded, decodedLen)) != NULL ) {
                     if (NTLM_packet_debug_enabled) {
                         printf("TT %s\n",c);
-                        decoded = base64_decode(c);
+                        decodedLen = base64_decode(decoded, sizeof(decoded), c);
                         debug("sending 'TT' to squid with data:\n");
-                        hex_dump(decoded, (strlen(c) * 3) / 4);
+                        hex_dump(decoded, decodedLen);
                         if (NTLM_LocalCall)
                             debug("NTLM Local Call detected\n");
                     } else {
@@ -505,6 +500,7 @@
                     have_challenge = 1;
                 } else
                     helperfail("can't obtain challenge");
+
                     return 1;
                     /* notreached */
                 case NTLM_CHALLENGE:
@@ -527,12 +523,9 @@
             return 1;
         }
         /* figure out what we got */
-        decoded = base64_decode(buf + 3);
-        /* Note: we don't need to manage memory at this point, since
-         *  base64_decode returns a pointer to static storage.
-         */
+        decodedLen = base64_decode(decoded, sizeof(decoded), buf+3);
 
-        if (!decoded) {		/* decoding failure, return error */
+        if (decodedLen < sizeof(ntlmhdr)) {		/* decoding failure, return error */
             SEND("NA Packet format error, couldn't base64-decode");
             return 1;
         }
@@ -556,8 +549,7 @@
             /* notreached */
         case NTLM_AUTHENTICATE:
             /* check against SSPI */
-            plen = (strlen(buf) - 3) * 3 / 4;		/* we only need it here. Optimization */
-            err = ntlm_check_auth((ntlm_authenticate *) decoded, user, domain, plen);
+            err = ntlm_check_auth((ntlm_authenticate *) decoded, user, domain, decodedLen);
             have_challenge = 0;
             if (err != NTLM_ERR_NONE) {
 #if FAIL_DEBUG

=== 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-30 11:16:56 +0000
@@ -150,6 +150,8 @@
 {
     char buf[HELPER_INPUT_BUFFER];
     int buflen = 0;
+    char decodedBuf[HELPER_INPUT_BUFFER];
+    int decodedLen;
     char user[NTLM_MAX_FIELD_LENGTH], domain[NTLM_MAX_FIELD_LENGTH];
     char *p;
     ntlmhdr *packet = NULL;
@@ -173,13 +175,15 @@
         if ((p = strchr(buf, '\n')) != NULL)
             *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);
+        if (buflen > 3) {
+            decodedLen = base64_decode(decodedBuf, sizeof(decodedBuf), buf+3);
+            packet = (ntlmhdr*)decodedBuf;
+        }
         if (buflen > 3 && NTLM_packet_debug_enabled) {
             strncpy(helper_command, buf, 2);
             helper_command[2] = '\0';
             debug("Got '%s' from Squid with data:\n", helper_command);
-            hex_dump((unsigned char*)packet, ((buflen - 3) * 3) / 4);
+            hex_dump((unsigned char *)decodedBuf, decodedLen);
         } else
             debug("Got '%s' from Squid\n", buf);
 
@@ -208,7 +212,7 @@
             if (!packet) {
                 SEND("BH received KK with no data! user=");
             } else if (ntlm_validate_packet(packet, NTLM_AUTHENTICATE) == NTLM_ERR_NONE) {
-                if (ntlm_unpack_auth((ntlm_authenticate *)packet, user, domain, (buflen-3)) == NTLM_ERR_NONE) {
+                if (ntlm_unpack_auth((ntlm_authenticate *)packet, user, domain, decodedLen) == NTLM_ERR_NONE) {
                     lc(user);
                     lc(domain);
                     if (strip_domain_enabled) {

=== 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-30 11:16:35 +0000
@@ -506,9 +506,9 @@
 {
     ntlmhdr *fast_header;
     char buf[NTLM_BLOB_BUFFER_SIZE];
+    char decoded[NTLM_BLOB_BUFFER_SIZE];
     const char *ch;
-    char *ch2, *decoded, *cred = NULL;
-    int plen;
+    char *ch2, *cred = NULL;
 
     if (fgets(buf, NTLM_BLOB_BUFFER_SIZE, stdin) == NULL) {
         fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno,
@@ -525,12 +525,9 @@
 
     if (memcmp(buf, "KK ", 3) == 0) {	/* authenticate-request */
         /* figure out what we got */
-        decoded = base64_decode(buf + 3);
-        /* Note: we don't need to manage memory at this point, since
-         *  base64_decode returns a pointer to static storage.
-         */
+        int decodedLen = base64_decode(decoded, sizeof(decoded), buf+3);
 
-        if (!decoded) {		/* decoding failure, return error */
+        if (decodedLen < sizeof(ntlmhdr)) {	/* decoding failure, return error */
             SEND("NA Packet format error, couldn't base64-decode");
             return;
         }
@@ -553,10 +550,9 @@
             /* notreached */
         case NTLM_AUTHENTICATE:
             /* check against the DC */
-            plen = strlen(buf) * 3 / 4;		/* we only need it here. Optimization */
             signal(SIGALRM, timeout_during_auth);
             alarm(30);
-            cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen);
+            cred = ntlm_check_auth((ntlm_authenticate *) decoded, decodedLen);
             alarm(0);
             signal(SIGALRM, SIG_DFL);
             if (got_timeout != 0) {
@@ -585,7 +581,7 @@
                  * without it.. */
                 if (nb_error != 0) {	/* netbios-level error */
                     send_bh_or_ld("NetBios error!",
-                                  (ntlm_authenticate *) decoded, plen);
+                                  (ntlm_authenticate *) decoded, decodedLen);
                     fprintf(stderr, "NetBios error code %d (%s)\n", nb_error,
                             RFCNB_Error_Strings[abs(nb_error)]);
                     return;
@@ -596,7 +592,7 @@
                     SEND("NA Authentication failed");
                     /*
                      * send_bh_or_ld("SMB success, but no creds. Internal error?",
-                     * (ntlm_authenticate *) decoded, plen);
+                     * (ntlm_authenticate *) decoded, decodedLen);
                      */
                     return;
                 case SMBC_ERRDOS:
@@ -619,7 +615,7 @@
                         return;
                     default:
                         send_bh_or_ld("DOS Error",
-                                      (ntlm_authenticate *) decoded, plen);
+                                      (ntlm_authenticate *) decoded, decodedLen);
                         return;
                     }
                 case SMBC_ERRSRV:	/* server errors */
@@ -634,16 +630,16 @@
                         return;
                     default:
                         send_bh_or_ld("Server Error",
-                                      (ntlm_authenticate *) decoded, plen);
+                                      (ntlm_authenticate *) decoded, decodedLen);
                         return;
                     }
                 case SMBC_ERRHRD:	/* hardware errors don't really matter */
                     send_bh_or_ld("Domain Controller Hardware error",
-                                  (ntlm_authenticate *) decoded, plen);
+                                  (ntlm_authenticate *) decoded, decodedLen);
                     return;
                 case SMBC_ERRCMD:
                     send_bh_or_ld("Domain Controller Command Error",
-                                  (ntlm_authenticate *) decoded, plen);
+                                  (ntlm_authenticate *) decoded, decodedLen);
                     return;
                 }
                 SEND("BH unknown internal error.");

=== modified file 'include/base64.h'
--- include/base64.h	2010-11-02 00:12:43 +0000
+++ include/base64.h	2011-04-30 13:52:07 +0000
@@ -5,10 +5,48 @@
 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 encoded string.
+    /// NULL 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 *encodedData);
+
+    /// 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, unsigned int result_max_size, const char *encoded);
+
+
+    // Encoding functions
+
+    /// Calculate the buffer size required to hold the encoded form of
+    /// a string of length 'decodedLen' including all terminator bytes.
+    extern int base64_encode_len(int decodedLen);
+
+    /// 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, int result_max_size, const char *data, 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, int result_max_size, const char *data, int data_size);
+
+    // Old encoder. Now a wrapper for the new. Takes a binary array of known length.
+    // 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 encoder. 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 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-30 13:53:15 +0000
@@ -1,5 +1,9 @@
 /*
  * $Id$
+ *
+ * AUTHOR: Markus Moeller
+ *
+ * Encoders adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments.
  */
 
 #include "config.h"
@@ -37,19 +41,37 @@
     base64_initialized = 1;
 }
 
-char *
-base64_decode(const char *p)
-{
-    static char result[BASE64_RESULT_SZ];
-    int j;
+int
+base64_decode_len(const char *data)
+{
+    if (!data || !*data)
+        return 0;
+
+    int terminatorLen = 0;
+    int dataLen = strlen(data);
+    int i;
+
+    for (i = dataLen - 1; i >= 0; i--) {
+        if (data[i] == '=')
+            terminatorLen++;
+        if (data[i] != '=')
+            break;
+    }
+    return dataLen / 4 * 3 - terminatorLen;
+}
+
+int
+base64_decode(char *result, unsigned int result_size, const char *p)
+{
+    int j = 0;
     int c;
     long val;
-    if (!p)
-        return NULL;
+    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,85 +80,107 @@
         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 */
-const char *
-base64_encode(const char *decoded_str)
-{
-    static char result[BASE64_RESULT_SZ];
-    int bits = 0;
-    int char_count = 0;
-    int out_cnt = 0;
-    int c;
-
-    if (!decoded_str)
-        return decoded_str;
-
-    if (!base64_initialized)
-        base64_init();
-
-    while ((c = (unsigned char) *decoded_str++) && out_cnt < sizeof(result) - 5) {
-        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];
-            bits = 0;
-            char_count = 0;
-        } else {
-            bits <<= 8;
-        }
-    }
-    if (char_count != 0) {
-        bits <<= 16 - (8 * char_count);
-        result[out_cnt++] = base64_code[bits >> 18];
-        result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
-        if (char_count == 1) {
-            result[out_cnt++] = '=';
-            result[out_cnt++] = '=';
-        } else {
-            result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
-            result[out_cnt++] = '=';
-        }
-    }
-    result[out_cnt] = '\0';	/* terminate */
-    return result;
-}
-
-/* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
-const char *
-base64_encode_bin(const char *data, int len)
-{
-    static char result[BASE64_RESULT_SZ];
-    int bits = 0;
-    int char_count = 0;
-    int out_cnt = 0;
-
-    if (!data)
-        return data;
-
-    if (!base64_initialized)
-        base64_init();
-
-    while (len-- && out_cnt < sizeof(result) - 5) {
+    return j;
+}
+
+int
+base64_encode_len(int len)
+{
+    // NP: some magic numbers + potential nil-terminator
+    return ((len + 2) / 3 * 4) + 1;
+}
+
+const char *
+old_base64_encode(const char *decoded_str)
+{
+    static char result[BASE64_RESULT_SZ];
+    base64_encode_str(result, sizeof(result), decoded_str, strlen(decoded_str));
+    return result;
+}
+
+const char *
+base64_encode_bin(const char *decoded_str, int len)
+{
+    static char result[BASE64_RESULT_SZ];
+    base64_encode_str(result, sizeof(result), decoded_str, len);
+    return result;
+}
+
+int
+base64_encode_str(char *result, int result_max_size, const char *data, int data_size)
+{
+    if (result_max_size < 1)
+        return 0;
+
+    int used = base64_encode(result, result_max_size, data, data_size);
+    /* terminate */
+    if (used >= result_max_size) {
+        result[result_max_size - 1] = '\0';
+        return result_max_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, int result_size, const char *data, int data_size)
+{
+    int bits = 0;
+    int char_count = 0;
+    int out_cnt = 0;
+
+    if (!data || !*data || !result || result_size < 1 || data_size < 1)
+        return 0;
+
+    if (!base64_initialized)
+        base64_init();
+
+    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 {
@@ -145,16 +189,27 @@
     }
     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);
 }

=== modified file 'src/HttpHeader.cc'
--- src/HttpHeader.cc	2011-03-22 12:23:25 +0000
+++ src/HttpHeader.cc	2011-04-30 11:07:04 +0000
@@ -1414,7 +1414,10 @@
     if (!*field)		/* no authorization cookie */
         return NULL;
 
-    return base64_decode(field);
+    static char decodedAuthToken[8192];
+    const int decodedLen = base64_decode(decodedAuthToken, sizeof(decodedAuthToken)-1, field);
+    decodedAuthToken[decodedLen] = '\0';
+    return decodedAuthToken;
 }
 
 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-29 15:02:09 +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-29 15:02:35 +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-30 13:49:06 +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);
-
+    const int bufLen = 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));
+    const int encodedLen = base64_encode_len(bufLen);
+    req->pub_auth = (char *) xmalloc(encodedLen);
+    base64_encode_str(req->pub_auth, encodedLen, buf, bufLen);
+    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));
+    const int decodedLen = base64_decode_len(req->pub_auth);
+    buf = (char*)xmalloc(decodedLen);
+    base64_decode(buf, decodedLen, req->pub_auth);
 
     debug("cmgr: length ok\n");
 
@@ -1136,16 +1139,20 @@
 {
     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);
-
-    str64 = base64_encode(buf);
+    int bufLen = snprintf(buf, sizeof(buf), "%s:%s",
+                          req->user_name ? req->user_name : "",
+                          req->passwd);
+
+    int encodedLen = base64_encode_len(bufLen);
+    if (encodedLen <= 0)
+        return "";
+
+    char *str64 = static_cast<char*>(xmalloc(encodedLen));
+    base64_encode_str(str64, encodedLen, buf, bufLen);
 
     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-30 08:42:27 +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

Reply via email to