The new Kerberos helper provided by Markus for 3.2.
This is updated to build with C++ on the 3.2 code base and use the new
helper naming schema: negotiate_kerberos_auth
Still missing a man(8) page. But thats not part of the upgrade at this
point.
Amos
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: squid3_at_treenet.co.nz-20090925112351-xi01cgu4t4shu2hb
# target_branch: ../trunk
# testament_sha1: 81021f67b5ff7c7f682ab03829e3763f63a65454
# timestamp: 2009-09-25 23:24:07 +1200
# base_revision_id: squid3_at_treenet.co.nz-20090925110937-\
# tlhyg6m27mepg400
#
# Begin patch
=== modified file 'CREDITS'
--- CREDITS 2009-07-11 09:38:29 +0000
+++ CREDITS 2009-09-04 13:07:27 +0000
@@ -398,3 +398,36 @@
squid under the same conditions as the main squid application.
==============================================================================
+
+helprs/negotiate_auth/kerberos/ *
+
+/*
+ * -----------------------------------------------------------------------------
+ *
+ * Author: Markus Moeller (markus_moeller at compuserve.com)
+ *
+ * Copyright (C) 2007 Markus Moeller. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * As a special exemption, M Moeller gives permission to link this program
+ * with MIT, Heimdal or other GSS/Kerberos libraries, and distribute
+ * the resulting executable, without including the source code for
+ * the Libraries in the source distribution.
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+==============================================================================
=== modified file 'bootstrap.sh'
--- bootstrap.sh 2009-08-22 13:10:36 +0000
+++ bootstrap.sh 2009-09-04 12:59:38 +0000
@@ -141,8 +141,7 @@
for dir in \
"" \
- lib/libTrie \
- helpers/negotiate_auth/squid_kerb_auth
+ lib/libTrie
do
if [ -z "$dir" ] || [ -d $dir ]; then
if (
=== modified file 'configure.in'
--- configure.in 2009-09-24 13:41:25 +0000
+++ configure.in 2009-09-25 04:13:50 +0000
@@ -1661,6 +1661,8 @@
helper="`basename $dir`"
if test -f $dir/config.test && sh $dir/config.test "$@"; then
BASIC_AUTH_HELPERS="$BASIC_AUTH_HELPERS $helper"
+ elif test -d $srcdir/helpers/basic_auth/$helper ; then
+ AC_MSG_NOTICE([Basic auth helper $helper ... found but cannot be built])
fi
done
fi
@@ -1707,6 +1709,8 @@
helper="`basename $dir`"
if test -f $dir/config.test && sh $dir/config.test "$@"; then
NTLM_AUTH_HELPERS="$NTLM_AUTH_HELPERS $helper"
+ elif test -d $srcdir/helpers/ntlm_auth/$helper ; then
+ AC_MSG_NOTICE([NTLM auth helper $helper ... found but cannot be built])
fi
done
fi
@@ -1749,6 +1753,8 @@
helper="`basename $dir`"
if test -f $dir/config.test && sh $dir/config.test "$@"; then
NEGOTIATE_AUTH_HELPERS="$NEGOTIATE_AUTH_HELPERS $helper"
+ elif test -d $srcdir/helpers/negotiate_auth/$helper ; then
+ AC_MSG_NOTICE([Negotiate auth helper $helper ... found but cannot be built])
fi
done
fi
@@ -1763,7 +1769,6 @@
AC_MSG_NOTICE([Negotiate auth helpers built: $NEGOTIATE_AUTH_HELPERS])
fi
AC_SUBST(NEGOTIATE_AUTH_HELPERS)
-AC_CONFIG_SUBDIRS(helpers/negotiate_auth/squid_kerb_auth)
dnl Select digest auth scheme helpers to build
if test -n "$AUTH_MODULE_digest"; then
@@ -1792,6 +1797,8 @@
helper="`basename $dir`"
if test -f $dir/config.test && sh $dir/config.test "$@"; then
DIGEST_AUTH_HELPERS="$DIGEST_AUTH_HELPERS $helper"
+ elif test -d $srcdir/helpers/digest_auth/$helper ; then
+ AC_MSG_NOTICE([Digest auth helper $helper ... found but cannot be built])
fi
done
fi
@@ -2043,6 +2050,8 @@
helper="`basename $dir`"
if test -f $dir/config.test && sh $dir/config.test "$@"; then
EXTERNAL_ACL_HELPERS="$EXTERNAL_ACL_HELPERS $helper"
+ elif test -d $srcdir/helpers/external_acl/$helper ; then
+ AC_MSG_NOTICE([External ACL helper $helper ... found but cannot be built])
fi
done
fi
@@ -2084,6 +2093,8 @@
helper="`basename $dir`"
if test -f $dir/config.test && sh $dir/config.test "$@"; then
URL_REWRITE_HELPERS="$URL_REWRITE_HELPERS $helper"
+ elif test -d $srcdir/helpers/url_rewrite/$helper ; then
+ AC_MSG_NOTICE([URL re-write helper $helper ... found but cannot be built])
fi
done
fi
@@ -4113,6 +4124,7 @@
helpers/ntlm_auth/smb_lm/smbval/Makefile \
helpers/ntlm_auth/mswin_sspi/Makefile \
helpers/negotiate_auth/Makefile \
+ helpers/negotiate_auth/kerberos/Makefile \
helpers/negotiate_auth/mswin_sspi/Makefile \
helpers/external_acl/Makefile \
helpers/external_acl/ip_user/Makefile \
=== modified file 'helpers/negotiate_auth/Makefile.am'
--- helpers/negotiate_auth/Makefile.am 2009-01-21 03:47:47 +0000
+++ helpers/negotiate_auth/Makefile.am 2009-09-04 12:59:38 +0000
@@ -1,7 +1,3 @@
-# Makefile for negotiate authentication helpers in the Squid Object Cache server
-#
-# $Id$
-#
-DIST_SUBDIRS = mswin_sspi squid_kerb_auth
+DIST_SUBDIRS = mswin_sspi kerberos
SUBDIRS = @NEGOTIATE_AUTH_HELPERS@
=== renamed directory 'helpers/negotiate_auth/squid_kerb_auth' => 'helpers/negotiate_auth/kerberos'
=== modified file 'helpers/negotiate_auth/kerberos/Makefile.am'
--- helpers/negotiate_auth/squid_kerb_auth/Makefile.am 2009-06-06 23:51:42 +0000
+++ helpers/negotiate_auth/kerberos/Makefile.am 2009-09-25 11:23:51 +0000
@@ -1,41 +1,29 @@
-EXTRA_DIST = configure README NEWS ChangeLog AUTHORS INSTALL
+include $(top_srcdir)/src/Common.am
+
+EXTRA_DIST = README COPYING config.test
SUBDIRS =
-libexec_PROGRAMS = squid_kerb_auth squid_kerb_auth_test negotiate_kerb_auth negotiate_kerb_auth_test
-
-SPNEGO_SOURCE= \
- spnegohelp/derparse.c \
- spnegohelp/derparse.h \
- spnegohelp/spnego.c \
- spnegohelp/spnego.h \
- spnegohelp/spnegohelp.c \
- spnegohelp/spnegohelp.h \
- spnegohelp/spnegoparse.c \
- spnegohelp/spnegoparse.h
-
-EXTRA_DIST += $(SPNEGO_SOURCE)
+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
+SPNEGO = \
+ spnegohelp/derparse.cc spnegohelp/derparse.h \
+ spnegohelp/spnego.cc spnegohelp/spnego.h \
+ spnegohelp/spnegohelp.cc spnegohelp/spnegohelp.h \
+ spnegohelp/spnegoparse.cc spnegohelp/spnegoparse.h
if HAVE_SPNEGO
-squid_kerb_auth_SOURCES = squid_kerb_auth.c base64.c base64.h squid_compat.h
-squid_kerb_auth_test_SOURCES = squid_kerb_auth_test.c base64.c base64.h squid_compat.h
+negotiate_kerberos_auth_SOURCES = $(SOURCE)
+AM_CPPFLAGS = $(INCLUDES) -I$(srcdir)
else
-squid_kerb_auth_SOURCES = squid_kerb_auth.c base64.c base64.h $(SPNEGO_SOURCE) squid_compat.h
-INCLUDES = -Ispnegohelp
-squid_kerb_auth_test_SOURCES = squid_kerb_auth_test.c base64.c base64.h squid_compat.h
+negotiate_kerberos_auth_SOURCES = $(SOURCE) $(SPNEGO)
+AM_CPPFLAGS = $(INCLUDES) -I$(srcdir)/spnegohelp -I$(srcdir)
endif
-
-
-squid_kerb_auth_LDFLAGS =
-squid_kerb_auth_LDADD =
-squid_kerb_auth_test_LDFLAGS =
-squid_kerb_auth_test_LDADD =
-negotiate_kerb_auth_SOURCES =
-negotiate_kerb_auth_test_SOURCES =
-
-negotiate_kerb_auth: squid_kerb_auth
- cp squid_kerb_auth negotiate_kerb_auth
-
-negotiate_kerb_auth_test: squid_kerb_auth_test
- cp squid_kerb_auth_test negotiate_kerb_auth_test
-
-
+negotiate_kerberos_auth_test_SOURCES = $(SOURCE_test)
+
+
+negotiate_kerberos_auth_LDFLAGS =
+negotiate_kerberos_auth_LDADD = $(COMPAT_LIB) $(XTRA_LIBS) @KRB5LIBS@
+negotiate_kerberos_auth_test_LDFLAGS =
+negotiate_kerberos_auth_test_LDADD = $(COMPAT_LIB) $(XTRA_LIBS) @KRB5LIBS@
=== renamed file 'helpers/negotiate_auth/squid_kerb_auth/base64.c' => 'helpers/negotiate_auth/kerberos/base64.cc'
--- helpers/negotiate_auth/squid_kerb_auth/base64.c 2009-08-23 09:30:49 +0000
+++ helpers/negotiate_auth/kerberos/base64.cc 2009-09-04 13:07:52 +0000
@@ -13,7 +13,8 @@
static int base64_initialized = 0;
#define BASE64_VALUE_SZ 256
int base64_value[BASE64_VALUE_SZ];
-const char base64_code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+const char base64_code[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void
@@ -22,131 +23,138 @@
int i;
for (i = 0; i < BASE64_VALUE_SZ; i++)
- base64_value[i] = -1;
+ base64_value[i] = -1;
for (i = 0; i < 64; i++)
- base64_value[(int) base64_code[i]] = i;
+ base64_value[(int) base64_code[i]] = i;
base64_value['='] = 0;
base64_initialized = 1;
}
-void ska_base64_decode(char* result, const char *data, int result_size)
+void
+ska_base64_decode(char *result, const char *data, int result_size)
{
int j;
int c;
long val;
if (!data)
- return;
+ return;
if (!base64_initialized)
- ska_base64_init();
+ 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;
+ 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)
+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;
+ return;
if (!base64_initialized)
- ska_base64_init();
+ 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;
- }
+ 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++] = '=';
- }
+ 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:
+ end:
if (out_cnt >= result_size) {
- result[result_size-1] = '\0'; /* terminate */
+ result[result_size - 1] = '\0'; /* terminate */
} else {
- result[out_cnt] = '\0'; /* terminate */
+ result[out_cnt] = '\0'; /* terminate */
}
return;
}
-int ska_base64_encode_len(int len)
+int
+ska_base64_encode_len(int len)
{
- return ((len+2)/3*4)+1;
+ return ((len + 2) / 3 * 4) + 1;
}
-int ska_base64_decode_len(const char *data)
+int
+ska_base64_decode_len(const char *data)
{
- int i,j;
+ int i, j;
- j=0;
- for (i=strlen(data)-1; i>=0; i--) {
- if (data[i] == '=') j++;
- if (data[i] != '=') break;
+ j = 0;
+ for (i = strlen(data) - 1; i >= 0; i--) {
+ if (data[i] == '=')
+ j++;
+ if (data[i] != '=')
+ break;
}
- return strlen(data)/4*3-j;
+ return strlen(data) / 4 * 3 - j;
}
=== modified file 'helpers/negotiate_auth/kerberos/base64.h'
--- helpers/negotiate_auth/squid_kerb_auth/base64.h 2008-10-03 02:25:50 +0000
+++ helpers/negotiate_auth/kerberos/base64.h 2009-09-04 12:59:38 +0000
@@ -2,8 +2,9 @@
* 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);
+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);
=== added file 'helpers/negotiate_auth/kerberos/config.test'
--- helpers/negotiate_auth/kerberos/config.test 1970-01-01 00:00:00 +0000
+++ helpers/negotiate_auth/kerberos/config.test 2009-09-12 06:48:39 +0000
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Don't build without gssapi.h
+if test -f /usr/include/gssapi/gssapi.h || test -f /usr/include/gssapi.h ; then
+ exit 0
+fi
+exit 1
=== renamed file 'helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c' => 'helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc'
--- helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c 2009-08-23 09:30:49 +0000
+++ helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 2009-09-13 10:06:34 +0000
@@ -29,12 +29,14 @@
/*
* Hosted at http://sourceforge.net/projects/squidkerbauth
*/
-#include "ska_config.h"
+#include "config.h"
+
+#if HAVE_GSSAPI
#if HAVE_STRING_H
#include <string.h>
#endif
-#if HAVE_STDIO_H
+#if HAVE_STDOI_H
#include <stdio.h>
#endif
#if HAVE_STDLIB_H
@@ -53,48 +55,56 @@
#include <sys/time.h>
#endif
-
-#if !defined(HAVE_DECL_XGETADDRINFO) || !HAVE_DECL_XGETADDRINFO
-#define xgetaddrinfo getaddrinfo
-#endif
-#if !defined(HAVE_DECL_XFREEADDRINFO) || !HAVE_DECL_XFREEADDRINFO
-#define xfreeaddrinfo freeaddrinfo
-#endif
-#if !defined(HAVE_DECL_XGAI_STRERROR) || !HAVE_DECL_XGAI_STRERROR
-#define xgai_strerror gai_strerror
-#endif
-#if !defined(HAVE_DECL_XGETNAMEINFO) || !HAVE_DECL_XGETNAMEINFO
-#define xgetnameinfo getnameinfo
-#endif
-#if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC
-#define xmalloc malloc
-#endif
-#if !defined(HAVE_DECL_XSTRDUP) || !HAVE_DECL_XSTRDUP
-#define xstrdup strdup
-#endif
-#if !defined(HAVE_DECL_XFREE) || !HAVE_DECL_XFREE
-#define xfree free
-#endif
-
+#include "util.h"
#include "base64.h"
-#ifndef HAVE_SPNEGO
-#include "spnegohelp/spnegohelp.h"
-#endif
-
-#define PROGRAM "squid_kerb_auth"
-
+#include "getaddrinfo.h"
+#include "getnameinfo.h"
+#if !HAVE_SPNEGO
+#include "spnegohelp.h"
+#endif
+
+#if HAVE_HEIMDAL_KERBEROS
+#if HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
+#endif /* HAVE_GSSAPI_GSSAPI_H */
+#else /* HAVE_HEIMDAL_KERBEROS */
+#if HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
+#endif /* HAVE_GSSAPI_GSSAPI_H */
+#if HAVE_GSSAPI_GSSAPI_KRB5_H
+#include <gssapi/gssapi_krb5.h>
+#endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */
+#if HAVE_GSSAPI_GSSAPI_GENERIC_H
+#include <gssapi/gssapi_generic.h>
+#endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */
+#endif /* HAVE_HEIMDAL_KERBEROS */
+#ifndef gss_nt_service_name
+#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
+#endif
+
+#define PROGRAM "negotiate_kerberos_auth"
#ifndef MAX_AUTHTOKEN_LEN
#define MAX_AUTHTOKEN_LEN 65535
#endif
+#ifndef SQUID_KERB_AUTH_VERSION
+#define SQUID_KERB_AUTH_VERSION "3.0.1sq"
+#endif
-int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char* function, int debug, int log);
+int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
+ const char *function, int debug, int log);
char *gethost_name(void);
static const char *LogTime(void);
-static const unsigned char ntlmProtocol [] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0};
+static const unsigned char ntlmProtocol[] =
+ { 'N', 'T', 'L', 'M', 'S', 'S', 'P', 0 };
-static const char *LogTime()
+static const char *
+LogTime()
{
struct tm *tm;
struct timeval now;
@@ -103,489 +113,571 @@
gettimeofday(&now, NULL);
if (now.tv_sec != last_t) {
- tm = localtime((time_t *)&now.tv_sec);
- strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
- last_t = now.tv_sec;
+ tm = localtime((time_t *) & now.tv_sec);
+ strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
+ last_t = now.tv_sec;
}
return buf;
}
-char *gethost_name(void)
+char *
+gethost_name(void)
{
- char hostname[sysconf(_SC_HOST_NAME_MAX)];
- struct addrinfo *hres=NULL, *hres_list;
- int rc,count;
+ char hostname[sysconf(_SC_HOST_NAME_MAX)];
+ struct addrinfo *hres = NULL, *hres_list;
+ int rc, count;
- rc = gethostname(hostname,sysconf(_SC_HOST_NAME_MAX));
+ rc = gethostname(hostname, sysconf(_SC_HOST_NAME_MAX));
if (rc) {
- fprintf(stderr, "%s| %s: error while resolving hostname '%s'\n", LogTime(), PROGRAM, hostname);
- return NULL;
+ fprintf(stderr, "%s| %s: error while resolving hostname '%s'\n",
+ LogTime(), PROGRAM, hostname);
+ return NULL;
}
- rc = xgetaddrinfo(hostname,NULL,NULL,&hres);
+ rc = xgetaddrinfo(hostname, NULL, NULL, &hres);
if (rc != 0) {
- fprintf(stderr, "%s| %s: error while resolving hostname with getaddrinfo: %s\n", LogTime(), PROGRAM, xgai_strerror(rc));
- return NULL;
+ fprintf(stderr,
+ "%s| %s: error while resolving hostname with getaddrinfo: %s\n",
+ LogTime(), PROGRAM, xgai_strerror(rc));
+ return NULL;
}
- hres_list=hres;
- count=0;
+ hres_list = hres;
+ count = 0;
while (hres_list) {
- count++;
- hres_list=hres_list->ai_next;
+ count++;
+ hres_list = hres_list->ai_next;
}
- rc = xgetnameinfo (hres->ai_addr, hres->ai_addrlen,hostname, sizeof (hostname), NULL, 0, 0);
+ rc = xgetnameinfo(hres->ai_addr, hres->ai_addrlen, hostname,
+ sizeof(hostname), NULL, 0, 0);
if (rc != 0) {
- fprintf(stderr, "%s| %s: error while resolving ip address with getnameinfo: %s\n", LogTime(), PROGRAM, xgai_strerror(rc));
- xfreeaddrinfo(hres);
- return NULL ;
+ fprintf(stderr,
+ "%s| %s: error while resolving ip address with getnameinfo: %s\n",
+ LogTime(), PROGRAM, xgai_strerror(rc));
+ xfreeaddrinfo(hres);
+ return NULL;
}
xfreeaddrinfo(hres);
- hostname[sysconf(_SC_HOST_NAME_MAX)-1]='\0';
- return(xstrdup(hostname));
+ hostname[sysconf(_SC_HOST_NAME_MAX) - 1] = '\0';
+ return (xstrdup(hostname));
}
-int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char* function, int debug, int log)
+int
+check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
+ const char *function, int debug, int log)
{
if (GSS_ERROR(major_status)) {
- OM_uint32 maj_stat,min_stat;
- OM_uint32 msg_ctx = 0;
- gss_buffer_desc status_string;
- char buf[1024];
- size_t len;
+ OM_uint32 maj_stat, min_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ char buf[1024];
+ size_t len;
- len = 0;
- msg_ctx = 0;
- while (!msg_ctx) {
- /* convert major status code (GSS-API error) to text */
- maj_stat = gss_display_status(&min_stat, major_status,
- GSS_C_GSS_CODE,
- GSS_C_NULL_OID,
- &msg_ctx, &status_string);
- if (maj_stat == GSS_S_COMPLETE) {
- if (sizeof(buf) > len + status_string.length + 1) {
- sprintf(buf+len, "%s", (char*) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- break;
- }
- gss_release_buffer(&min_stat, &status_string);
- }
- if (sizeof(buf) > len + 2) {
- sprintf(buf+len, "%s", ". ");
- len += 2;
- }
- msg_ctx = 0;
- while (!msg_ctx) {
- /* convert minor status code (underlying routine error) to text */
- maj_stat = gss_display_status(&min_stat, minor_status,
- GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
- &msg_ctx, &status_string);
- if (maj_stat == GSS_S_COMPLETE) {
- if (sizeof(buf) > len + status_string.length ) {
- sprintf(buf+len, "%s", (char*) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- break;
- }
- gss_release_buffer(&min_stat, &status_string);
- }
- if (debug)
- fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM, function, buf);
- fprintf(stdout, "BH %s failed: %s\n",function, buf);
- if (log)
- fprintf(stderr, "%s| %s: User not authenticated\n", LogTime(), PROGRAM);
- return(1);
+ len = 0;
+ msg_ctx = 0;
+ while (!msg_ctx) {
+ /* convert major status code (GSS-API error) to text */
+ maj_stat = gss_display_status(&min_stat, major_status,
+ GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
+ if (maj_stat == GSS_S_COMPLETE) {
+ if (sizeof(buf) > len + status_string.length + 1) {
+ sprintf(buf + len, "%s", (char *) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ if (sizeof(buf) > len + 2) {
+ sprintf(buf + len, "%s", ". ");
+ len += 2;
+ }
+ msg_ctx = 0;
+ while (!msg_ctx) {
+ /* convert minor status code (underlying routine error) to text */
+ maj_stat = gss_display_status(&min_stat, minor_status,
+ GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
+ if (maj_stat == GSS_S_COMPLETE) {
+ if (sizeof(buf) > len + status_string.length) {
+ sprintf(buf + len, "%s", (char *) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ if (debug)
+ fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM,
+ function, buf);
+ fprintf(stdout, "BH %s failed: %s\n", function, buf);
+ if (log)
+ fprintf(stderr, "%s| %s: User not authenticated\n", LogTime(),
+ PROGRAM);
+ return (1);
}
- return(0);
+ return (0);
}
-int main(int argc, char * const argv[])
+int
+main(int argc, char *const argv[])
{
char buf[MAX_AUTHTOKEN_LEN];
- char *c;
- char *user=NULL;
- int length=0;
- static int err=0;
- int opt, debug=0, log=0;
-#ifndef HAVE_SPNEGO
+ char *c, *p;
+ char *user = NULL;
+ int length = 0;
+ static int err = 0;
+ int opt, debug = 0, log = 0, norealm = 0;
+#if !HAVE_SPNEGO
int rc;
#endif
- OM_uint32 ret_flags=0, spnego_flag=0;
- char *service_name=(char *)"HTTP",*host_name=NULL;
+ OM_uint32 ret_flags = 0, spnego_flag = 0;
+ char *service_name = (char *) "HTTP", *host_name = NULL;
char *token = NULL;
char *service_principal = NULL;
OM_uint32 major_status, minor_status;
- gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
- gss_name_t client_name = GSS_C_NO_NAME;
- gss_name_t server_name = GSS_C_NO_NAME;
- gss_cred_id_t server_creds = GSS_C_NO_CREDENTIAL;
- gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
- const unsigned char *kerberosToken = NULL;
-#ifndef HAVE_SPNEGO
- size_t kerberosTokenLength = 0;
+ gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
+ gss_name_t client_name = GSS_C_NO_NAME;
+ gss_name_t server_name = GSS_C_NO_NAME;
+ gss_cred_id_t server_creds = GSS_C_NO_CREDENTIAL;
+ gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ const unsigned char *kerberosToken = NULL;
+#if !HAVE_SPNEGO
+ size_t kerberosTokenLength = 0;
#endif
- const unsigned char *spnegoToken = NULL ;
- size_t spnegoTokenLength = 0;
-
- setbuf(stdout,NULL);
- setbuf(stdin,NULL);
-
- while (-1 != (opt = getopt(argc, argv, "dis:h"))) {
- switch (opt) {
- case 'd':
- debug = 1;
- break;
- case 'i':
- log = 1;
- break;
- case 's':
- service_principal = xstrdup(optarg);
- break;
- case 'h':
- fprintf(stderr, "Usage: \n");
- fprintf(stderr, "squid_kerb_auth [-d] [-i] [-s SPN] [-h]\n");
- fprintf(stderr, "-d full debug\n");
- fprintf(stderr, "-i informational messages\n");
- fprintf(stderr, "-s service principal name\n");
- fprintf(stderr, "-h help\n");
- fprintf(stderr, "The SPN can be set to GSS_C_NO_NAME to allow any entry from keytab\n");
- fprintf(stderr, "default SPN is HTTP/fqdn_at_DEFAULT_REALM\n");
- exit(0);
- default:
- fprintf(stderr, "%s| %s: unknown option: -%c.\n", LogTime(), PROGRAM, opt);
- }
+ const unsigned char *spnegoToken = NULL;
+ size_t spnegoTokenLength = 0;
+
+ setbuf(stdout, NULL);
+ setbuf(stdin, NULL);
+
+ while (-1 != (opt = getopt(argc, argv, "dirs:h"))) {
+ switch (opt) {
+ case 'd':
+ debug = 1;
+ break;
+ case 'i':
+ log = 1;
+ break;
+ case 'r':
+ norealm = 1;
+ break;
+ case 's':
+ service_principal = xstrdup(optarg);
+ break;
+ case 'h':
+ fprintf(stderr, "Usage: \n");
+ fprintf(stderr, "squid_kerb_auth [-d] [-i] [-s SPN] [-h]\n");
+ fprintf(stderr, "-d full debug\n");
+ fprintf(stderr, "-i informational messages\n");
+ fprintf(stderr, "-r remove realm from username\n");
+ fprintf(stderr, "-s service principal name\n");
+ fprintf(stderr, "-h help\n");
+ fprintf(stderr,
+ "The SPN can be set to GSS_C_NO_NAME to allow any entry from keytab\n");
+ fprintf(stderr, "default SPN is HTTP/fqdn_at_DEFAULT_REALM\n");
+ exit(0);
+ default:
+ fprintf(stderr, "%s| %s: unknown option: -%c.\n", LogTime(),
+ PROGRAM, opt);
+ }
}
if (debug)
- fprintf(stderr, "%s| %s: Starting version %s\n", LogTime(), PROGRAM, VERSION);
- if (service_principal && strcasecmp(service_principal,"GSS_C_NO_NAME") ) {
- service.value = service_principal;
- service.length = strlen((char *)service.value);
+ fprintf(stderr, "%s| %s: Starting version %s\n", LogTime(), PROGRAM,
+ SQUID_KERB_AUTH_VERSION);
+ if (service_principal && strcasecmp(service_principal, "GSS_C_NO_NAME")) {
+ service.value = service_principal;
+ service.length = strlen((char *) service.value);
} else {
- host_name=gethost_name();
- if ( !host_name ) {
- fprintf(stderr, "%s| %s: Local hostname could not be determined. Please specify the service principal\n", LogTime(), PROGRAM);
- fprintf(stdout, "BH hostname error\n");
- exit(-1);
- }
- service.value = xmalloc(strlen(service_name)+strlen(host_name)+2);
- snprintf(service.value,strlen(service_name)+strlen(host_name)+2,"%s@%s",service_name,host_name);
- service.length = strlen((char *)service.value);
- }
-
- while (1) {
- if (fgets(buf, sizeof(buf)-1, stdin) == NULL) {
- if (ferror(stdin)) {
- if (debug)
- fprintf(stderr, "%s| %s: fgets() failed! dying..... errno=%d (%s)\n", LogTime(), PROGRAM, ferror(stdin),
- strerror(ferror(stdin)));
-
- fprintf(stdout, "BH input error\n");
- exit(1); /* BIIG buffer */
- }
+ host_name = gethost_name();
+ if (!host_name) {
+ fprintf(stderr,
+ "%s| %s: Local hostname could not be determined. Please specify the service principal\n",
+ LogTime(), PROGRAM);
+ fprintf(stdout, "BH hostname error\n");
+ exit(-1);
+ }
+ service.value = xmalloc(strlen(service_name) + strlen(host_name) + 2);
+ snprintf((char*)service.value, strlen(service_name) + strlen(host_name) + 2,
+ "%s@%s", service_name, host_name);
+ service.length = strlen((char *) service.value);
+ }
+
+ while (1) {
+ if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) {
+ if (ferror(stdin)) {
+ if (debug)
+ fprintf(stderr,
+ "%s| %s: fgets() failed! dying..... errno=%d (%s)\n",
+ LogTime(), PROGRAM, ferror(stdin),
+ strerror(ferror(stdin)));
+
+ fprintf(stdout, "BH input error\n");
+ exit(1); /* BIIG buffer */
+ }
+ fprintf(stdout, "BH input error\n");
+ exit(0);
+ }
+
+ c = (char*)memchr(buf, '\n', sizeof(buf) - 1);
+ if (c) {
+ *c = '\0';
+ length = c - buf;
+ } else {
+ err = 1;
+ }
+ if (err) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Oversized message\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Oversized message\n");
+ err = 0;
+ continue;
+ }
+
+ if (debug)
+ fprintf(stderr, "%s| %s: Got '%s' from squid (length: %d).\n",
+ LogTime(), PROGRAM, buf, length);
+
+ if (buf[0] == '\0') {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid request\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Invalid request\n");
+ continue;
+ }
+
+ if (strlen(buf) < 2) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(),
+ PROGRAM, buf);
+ fprintf(stdout, "BH Invalid request\n");
+ continue;
+ }
+
+ if (!strncmp(buf, "QQ", 2)) {
+ gss_release_buffer(&minor_status, &input_token);
+ gss_release_buffer(&minor_status, &output_token);
+ gss_release_buffer(&minor_status, &service);
+ gss_release_cred(&minor_status, &server_creds);
+ if (server_name)
+ gss_release_name(&minor_status, &server_name);
+ if (client_name)
+ gss_release_name(&minor_status, &client_name);
+ if (gss_context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&minor_status, &gss_context, NULL);
+ if (kerberosToken) {
+ /* Allocated by parseNegTokenInit, but no matching free function exists.. */
+ if (!spnego_flag)
+ xfree((char *) kerberosToken);
+ kerberosToken = NULL;
+ }
+ if (spnego_flag) {
+ /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
+ if (spnegoToken)
+ xfree((char *) spnegoToken);
+ spnegoToken = NULL;
+ }
+ if (token) {
+ xfree(token);
+ token = NULL;
+ }
+ if (host_name) {
+ xfree(host_name);
+ host_name = NULL;
+ }
+ fprintf(stdout, "BH quit command\n");
+ exit(0);
+ }
+
+ if (strncmp(buf, "YR", 2) && strncmp(buf, "KK", 2)) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(),
+ PROGRAM, buf);
+ fprintf(stdout, "BH Invalid request\n");
+ continue;
+ }
+ if (!strncmp(buf, "YR", 2)) {
+ if (gss_context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&minor_status, &gss_context, NULL);
+ gss_context = GSS_C_NO_CONTEXT;
+ }
+
+ if (strlen(buf) <= 3) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid negotiate request [%s]\n",
+ LogTime(), PROGRAM, buf);
+ fprintf(stdout, "BH Invalid negotiate request\n");
+ continue;
+ }
+
+ input_token.length = ska_base64_decode_len(buf + 3);
+ if (debug)
+ fprintf(stderr, "%s| %s: 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);
+
+
+#if !HAVE_SPNEGO
+ if ((rc = parseNegTokenInit(input_token.value,
+ input_token.length,
+ &kerberosToken, &kerberosTokenLength)) != 0) {
+ if (debug)
+ fprintf(stderr, "%s| %s: parseNegTokenInit failed with rc=%d\n",
+ LogTime(), PROGRAM, rc);
+
+ /* if between 100 and 200 it might be a GSSAPI token and not a SPNEGO token */
+ if (rc < 100 || rc > 199) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid GSS-SPNEGO query [%s]\n",
+ LogTime(), PROGRAM, buf);
+ fprintf(stdout, "BH Invalid GSS-SPNEGO query\n");
+ goto cleanup;
+ }
+ if ((input_token.length >= sizeof ntlmProtocol + 1) &&
+ (!memcmp(input_token.value, ntlmProtocol,
+ sizeof ntlmProtocol))) {
+ if (debug)
+ fprintf(stderr, "%s| %s: received type %d NTLM token\n",
+ LogTime(), PROGRAM,
+ (int) *((unsigned char *) input_token.value +
+ sizeof ntlmProtocol));
+ fprintf(stdout, "BH received type %d NTLM token\n",
+ (int) *((unsigned char *) input_token.value +
+ sizeof ntlmProtocol));
+ goto cleanup;
+ }
+ if (debug)
+ fprintf(stderr, "%s| %s: Token is possibly a GSSAPI token\n",
+ LogTime(), PROGRAM);
+ spnego_flag = 0;
+ } else {
+ gss_release_buffer(&minor_status, &input_token);
+ input_token.length = kerberosTokenLength;
+ input_token.value = (void *) kerberosToken;
+ spnego_flag = 1;
+ }
+#else
+ if ((input_token.length >= sizeof ntlmProtocol + 1) &&
+ (!memcmp(input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
+ if (debug)
+ fprintf(stderr, "%s| %s: received type %d NTLM token\n",
+ LogTime(), PROGRAM,
+ (int) *((unsigned char *) input_token.value +
+ sizeof ntlmProtocol));
+ fprintf(stdout, "BH received type %d NTLM token\n",
+ (int) *((unsigned char *) input_token.value +
+ sizeof ntlmProtocol));
+ goto cleanup;
+ }
+#endif
+
+ if (service_principal) {
+ if (strcasecmp(service_principal, "GSS_C_NO_NAME")) {
+ major_status = gss_import_name(&minor_status, &service,
+ (gss_OID) GSS_C_NULL_OID, &server_name);
+
+ } else {
+ server_name = GSS_C_NO_NAME;
+ major_status = GSS_S_COMPLETE;
+ }
+ } else {
+ major_status = gss_import_name(&minor_status, &service,
+ gss_nt_service_name, &server_name);
+ }
+
+ if (check_gss_err(major_status, minor_status, "gss_import_name()",
+ debug, log))
+ goto cleanup;
+
+ major_status =
+ gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET, GSS_C_ACCEPT, &server_creds, NULL, NULL);
+ if (check_gss_err(major_status, minor_status, "gss_acquire_cred()",
+ debug, log))
+ goto cleanup;
+
+ major_status = gss_accept_sec_context(&minor_status,
+ &gss_context,
+ server_creds,
+ &input_token,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client_name, NULL, &output_token, &ret_flags, NULL, NULL);
+
+
+ if (output_token.length) {
+#if !HAVE_SPNEGO
+ if (spnego_flag) {
+ if ((rc = makeNegTokenTarg(output_token.value,
+ output_token.length,
+ &spnegoToken, &spnegoTokenLength)) != 0) {
+ if (debug)
+ fprintf(stderr,
+ "%s| %s: makeNegTokenTarg failed with rc=%d\n",
+ LogTime(), PROGRAM, rc);
+ fprintf(stdout, "BH makeNegTokenTarg failed with rc=%d\n",
+ rc);
+ goto cleanup;
+ }
+ } else {
+ spnegoToken = output_token.value;
+ spnegoTokenLength = output_token.length;
+ }
+#else
+ spnegoToken = (unsigned char *)output_token.value;
+ spnegoTokenLength = output_token.length;
+#endif
+ token = (char*)xmalloc(ska_base64_encode_len(spnegoTokenLength));
+ if (token == NULL) {
+ if (debug)
+ fprintf(stderr, "%s| %s: 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);
+
+ if (check_gss_err(major_status, minor_status,
+ "gss_accept_sec_context()", debug, log))
+ goto cleanup;
+ if (major_status & GSS_S_CONTINUE_NEEDED) {
+ if (debug)
+ fprintf(stderr, "%s| %s: continuation needed\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "TT %s\n", token);
+ goto cleanup;
+ }
+ gss_release_buffer(&minor_status, &output_token);
+ major_status =
+ gss_display_name(&minor_status, client_name, &output_token,
+ NULL);
+
+ if (check_gss_err(major_status, minor_status, "gss_display_name()",
+ debug, log))
+ goto cleanup;
+ user = (char*)xmalloc(output_token.length + 1);
+ if (user == NULL) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Not enough memory\n");
+ goto cleanup;
+ }
+ memcpy(user, output_token.value, output_token.length);
+ user[output_token.length] = '\0';
+ if (norealm && (p = strchr(user, '@')) != NULL) {
+ *p = '\0';
+ }
+ fprintf(stdout, "AF %s %s\n", token, user);
+ if (debug)
+ fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM, token,
+ user);
+ if (log)
+ fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(),
+ PROGRAM, user);
+ goto cleanup;
+ } else {
+ if (check_gss_err(major_status, minor_status,
+ "gss_accept_sec_context()", debug, log))
+ goto cleanup;
+ if (major_status & GSS_S_CONTINUE_NEEDED) {
+ if (debug)
+ fprintf(stderr, "%s| %s: continuation needed\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "NA %s\n", token);
+ goto cleanup;
+ }
+ gss_release_buffer(&minor_status, &output_token);
+ major_status =
+ gss_display_name(&minor_status, client_name, &output_token,
+ NULL);
+
+ if (check_gss_err(major_status, minor_status, "gss_display_name()",
+ debug, log))
+ goto cleanup;
+ /*
+ * Return dummy token AA. May need an extra return tag then AF
+ */
+ user = (char*)xmalloc(output_token.length + 1);
+ if (user == NULL) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Not enough memory\n");
+ goto cleanup;
+ }
+ memcpy(user, output_token.value, output_token.length);
+ user[output_token.length] = '\0';
+ if (norealm && (p = strchr(user, '@')) != NULL) {
+ *p = '\0';
+ }
+ fprintf(stdout, "AF %s %s\n", "AA==", user);
+ if (debug)
+ fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM,
+ "AA==", user);
+ if (log)
+ fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(),
+ PROGRAM, user);
+
+ }
+ cleanup:
+ gss_release_buffer(&minor_status, &input_token);
+ gss_release_buffer(&minor_status, &output_token);
+ gss_release_cred(&minor_status, &server_creds);
+ if (server_name)
+ gss_release_name(&minor_status, &server_name);
+ if (client_name)
+ gss_release_name(&minor_status, &client_name);
+ if (kerberosToken) {
+ /* Allocated by parseNegTokenInit, but no matching free function exists.. */
+ if (!spnego_flag)
+ xfree((char *) kerberosToken);
+ kerberosToken = NULL;
+ }
+ if (spnego_flag) {
+ /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
+ if (spnegoToken)
+ xfree((char *) spnegoToken);
+ spnegoToken = NULL;
+ }
+ if (token) {
+ xfree(token);
+ token = NULL;
+ }
+ if (user) {
+ xfree(user);
+ user = NULL;
+ }
+ continue;
+ }
+}
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef MAX_AUTHTOKEN_LEN
+#define MAX_AUTHTOKEN_LEN 65535
+#endif
+int
+main(int argc, char *const argv[])
+{
+ setbuf(stdout, NULL);
+ setbuf(stdin, NULL);
+ char buf[MAX_AUTHTOKEN_LEN];
+ while (1) {
+ if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) {
fprintf(stdout, "BH input error\n");
exit(0);
}
-
- c=memchr(buf,'\n',sizeof(buf)-1);
- if (c) {
- *c = '\0';
- length = c-buf;
- } else {
- err = 1;
- }
- if (err) {
- if (debug)
- fprintf(stderr, "%s| %s: Oversized message\n", LogTime(), PROGRAM);
- fprintf(stdout, "BH Oversized message\n");
- err = 0;
- continue;
- }
-
- if (debug)
- fprintf(stderr, "%s| %s: Got '%s' from squid (length: %d).\n", LogTime(), PROGRAM, buf,length);
-
- if (buf[0] == '\0') {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid request\n", LogTime(), PROGRAM);
- fprintf(stdout, "BH Invalid request\n");
- continue;
- }
-
- if (strlen(buf) < 2) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(), PROGRAM, buf);
- fprintf(stdout, "BH Invalid request\n");
- continue;
- }
-
- if ( !strncmp(buf, "QQ", 2) ) {
- gss_release_buffer(&minor_status, &input_token);
- gss_release_buffer(&minor_status, &output_token);
- gss_release_buffer(&minor_status, &service);
- gss_release_cred(&minor_status, &server_creds);
- if (server_name)
- gss_release_name(&minor_status, &server_name);
- if (client_name)
- gss_release_name(&minor_status, &client_name);
- if (gss_context != GSS_C_NO_CONTEXT )
- gss_delete_sec_context(&minor_status, &gss_context, NULL);
- if (kerberosToken) {
- /* Allocated by parseNegTokenInit, but no matching free function exists.. */
- if (!spnego_flag)
- xfree((char *)kerberosToken);
- kerberosToken=NULL;
- }
- if (spnego_flag) {
- /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
- if (spnegoToken)
- xfree((char *)spnegoToken);
- spnegoToken=NULL;
- }
- if (token) {
- xfree(token);
- token=NULL;
- }
- if (host_name) {
- xfree(host_name);
- host_name=NULL;
- }
- fprintf(stdout, "BH quit command\n");
- exit(0);
- }
-
- if ( strncmp(buf, "YR", 2) && strncmp(buf, "KK", 2) ) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(), PROGRAM, buf);
- fprintf(stdout, "BH Invalid request\n");
- continue;
- }
- if ( !strncmp(buf, "YR", 2) ) {
- if (gss_context != GSS_C_NO_CONTEXT )
- gss_delete_sec_context(&minor_status, &gss_context, NULL);
- gss_context = GSS_C_NO_CONTEXT;
- }
-
- if (strlen(buf) <= 3) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid negotiate request [%s]\n", LogTime(), PROGRAM, buf);
- fprintf(stdout, "BH Invalid negotiate request\n");
- continue;
- }
-
- input_token.length = ska_base64_decode_len(buf+3);
- if (debug)
- fprintf(stderr, "%s| %s: Decode '%s' (decoded length: %d).\n", LogTime(), PROGRAM, buf+3,(int)input_token.length);
- input_token.value = xmalloc(input_token.length);
-
- ska_base64_decode(input_token.value,buf+3,input_token.length);
-
-
-#ifndef HAVE_SPNEGO
- if (( rc=parseNegTokenInit (input_token.value,
- input_token.length,
- &kerberosToken,
- &kerberosTokenLength))!=0 ) {
- if (debug)
- fprintf(stderr, "%s| %s: parseNegTokenInit failed with rc=%d\n", LogTime(), PROGRAM, rc);
-
- /* if between 100 and 200 it might be a GSSAPI token and not a SPNEGO token */
- if ( rc < 100 || rc > 199 ) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid GSS-SPNEGO query [%s]\n", LogTime(), PROGRAM, buf);
- fprintf(stdout, "BH Invalid GSS-SPNEGO query\n");
- goto cleanup;
- }
- if ((input_token.length >= sizeof ntlmProtocol + 1) &&
- (!memcmp (input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
- if (debug)
- fprintf(stderr, "%s| %s: received type %d NTLM token\n", LogTime(), PROGRAM, (int) *((unsigned char *)input_token.value + sizeof ntlmProtocol));
- fprintf(stdout, "BH received type %d NTLM token\n",(int) *((unsigned char *)input_token.value + sizeof ntlmProtocol));
- goto cleanup;
- }
- if (debug)
- fprintf(stderr, "%s| %s: Token is possibly a GSSAPI token\n", LogTime(), PROGRAM);
- spnego_flag=0;
- } else {
- gss_release_buffer(&minor_status, &input_token);
- input_token.length=kerberosTokenLength;
- input_token.value=(void *)kerberosToken;
- spnego_flag=1;
- }
-#else
- if ((input_token.length >= sizeof ntlmProtocol + 1) &&
- (!memcmp (input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
- if (debug)
- fprintf(stderr, "%s| %s: received type %d NTLM token\n", LogTime(), PROGRAM, (int) *((unsigned char *)input_token.value + sizeof ntlmProtocol));
- fprintf(stdout, "BH received type %d NTLM token\n",(int) *((unsigned char *)input_token.value + sizeof ntlmProtocol));
- goto cleanup;
- }
-#endif
-
- if ( service_principal ) {
- if ( strcasecmp(service_principal,"GSS_C_NO_NAME") ) {
- major_status = gss_import_name(&minor_status, &service,
- (gss_OID) GSS_C_NULL_OID, &server_name);
-
- } else {
- server_name = GSS_C_NO_NAME;
- major_status = GSS_S_COMPLETE;
- }
- } else {
- major_status = gss_import_name(&minor_status, &service,
- gss_nt_service_name, &server_name);
- }
-
- if ( check_gss_err(major_status,minor_status,"gss_import_name()",debug,log) )
- goto cleanup;
-
- major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
- GSS_C_NO_OID_SET, GSS_C_ACCEPT, &server_creds,
- NULL, NULL);
- if (check_gss_err(major_status,minor_status,"gss_acquire_cred()",debug,log) )
- goto cleanup;
-
- major_status = gss_accept_sec_context(&minor_status,
- &gss_context,
- server_creds,
- &input_token,
- GSS_C_NO_CHANNEL_BINDINGS,
- &client_name,
- NULL,
- &output_token,
- &ret_flags,
- NULL,
- NULL);
-
-
- if (output_token.length) {
-#ifndef HAVE_SPNEGO
- if (spnego_flag) {
- if ((rc=makeNegTokenTarg (output_token.value,
- output_token.length,
- &spnegoToken,
- &spnegoTokenLength))!=0 ) {
- if (debug)
- fprintf(stderr, "%s| %s: makeNegTokenTarg failed with rc=%d\n", LogTime(), PROGRAM, rc);
- fprintf(stdout, "BH makeNegTokenTarg failed with rc=%d\n",rc);
- goto cleanup;
- }
- } else {
- spnegoToken = output_token.value;
- spnegoTokenLength = output_token.length;
- }
-#else
- spnegoToken = output_token.value;
- spnegoTokenLength = output_token.length;
-#endif
- token = xmalloc(ska_base64_encode_len(spnegoTokenLength));
- if (token == NULL) {
- if (debug)
- fprintf(stderr, "%s| %s: 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);
-
- if (check_gss_err(major_status,minor_status,"gss_accept_sec_context()",debug,log) )
- goto cleanup;
- if (major_status & GSS_S_CONTINUE_NEEDED) {
- if (debug)
- fprintf(stderr, "%s| %s: continuation needed\n", LogTime(), PROGRAM);
- fprintf(stdout, "TT %s\n",token);
- goto cleanup;
- }
- gss_release_buffer(&minor_status, &output_token);
- major_status = gss_display_name(&minor_status, client_name, &output_token,
- NULL);
-
- if (check_gss_err(major_status,minor_status,"gss_display_name()",debug,log) )
- goto cleanup;
- user=xmalloc(output_token.length+1);
- if (user == NULL) {
- if (debug)
- fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(), PROGRAM);
- fprintf(stdout, "BH Not enough memory\n");
- goto cleanup;
- }
- memcpy(user,output_token.value,output_token.length);
- user[output_token.length]='\0';
- fprintf(stdout, "AF %s %s\n",token,user);
- if (debug)
- fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM, token,user);
- if (log)
- fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(), PROGRAM, user);
- goto cleanup;
- } else {
- if (check_gss_err(major_status,minor_status,"gss_accept_sec_context()",debug,log) )
- goto cleanup;
- if (major_status & GSS_S_CONTINUE_NEEDED) {
- if (debug)
- fprintf(stderr, "%s| %s: continuation needed\n", LogTime(), PROGRAM);
- fprintf(stdout, "NA %s\n",token);
- goto cleanup;
- }
- gss_release_buffer(&minor_status, &output_token);
- major_status = gss_display_name(&minor_status, client_name, &output_token,
- NULL);
-
- if (check_gss_err(major_status,minor_status,"gss_display_name()",debug,log) )
- goto cleanup;
- /*
- * Return dummy token AA. May need an extra return tag then AF
- */
- user=xmalloc(output_token.length+1);
- if (user == NULL) {
- if (debug)
- fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(), PROGRAM);
- fprintf(stdout, "BH Not enough memory\n");
- goto cleanup;
- }
- memcpy(user,output_token.value,output_token.length);
- user[output_token.length]='\0';
- fprintf(stdout, "AF %s %s\n","AA==",user);
- if (debug)
- fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM, "AA==", user);
- if (log)
- fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(), PROGRAM, user);
-
-cleanup:
- gss_release_buffer(&minor_status, &input_token);
- gss_release_buffer(&minor_status, &output_token);
- gss_release_cred(&minor_status, &server_creds);
- if (server_name)
- gss_release_name(&minor_status, &server_name);
- if (client_name)
- gss_release_name(&minor_status, &client_name);
- if (kerberosToken) {
- /* Allocated by parseNegTokenInit, but no matching free function exists.. */
- if (!spnego_flag)
- xfree((char *)kerberosToken);
- kerberosToken=NULL;
- }
- if (spnego_flag) {
- /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
- if (spnegoToken)
- xfree((char *)spnegoToken);
- spnegoToken=NULL;
- }
- if (token) {
- xfree(token);
- token=NULL;
- }
- if (user) {
- xfree(user);
- user=NULL;
- }
- continue;
- }
+ fprintf(stdout, "BH Kerberos authentication not supported\n");
}
}
+#endif /* HAVE_GSSAPI */
=== renamed file 'helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth_test.c' => 'helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc'
--- helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth_test.c 2008-11-30 05:29:55 +0000
+++ helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc 2009-09-12 08:16:48 +0000
@@ -25,7 +25,9 @@
* Hosted at http://sourceforge.net/projects/squidkerbauth
*/
-#include "ska_config.h"
+#include "config.h"
+
+#if HAVE_GSSAPI
#if HAVE_STRING_H
#include <string.h>
@@ -52,25 +54,41 @@
#include <errno.h>
#endif
-
-#if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC
-#define xmalloc malloc
-#endif
-#if !defined(HAVE_DECL_XSTRDUP) || !HAVE_DECL_XSTRDUP
-#define xstrdup strdup
-#endif
-
#include "base64.h"
+#include "util.h"
+
+#if HAVE_HEIMDAL_KERBEROS
+#if HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
+#endif /* HAVE_GSSAPI_GSSAPI_H */
+#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
+#else /* HAVE_HEIMDAL_KERBEROS */
+#if HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
+#endif /* HAVE_GSSAPI_GSSAPI_H */
+#if HAVE_GSSAPI_GSSAPI_KRB5_H
+#include <gssapi/gssapi_krb5.h>
+#endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */
+#if HAVE_GSSAPI_GSSAPI_GENERIC_H
+#include <gssapi/gssapi_generic.h>
+#endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */
+#endif /* HAVE_HEIMDAL_KERBEROS */
static const char *LogTime(void);
-int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char* function);
+int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
+ const char *function);
const char *squid_kerb_proxy_auth(char *proxy);
-#define PROGRAM "squid_kerb_auth_test"
+#define PROGRAM "negotiate_kerberos_auth_test"
-static const char *LogTime()
+static const char *
+LogTime()
{
struct tm *tm;
struct timeval now;
@@ -79,132 +97,127 @@
gettimeofday(&now, NULL);
if (now.tv_sec != last_t) {
- // FreeBSD defines tv_sec as long in non-ARM systems with a TODO note
- time_t tmp = now.tv_sec;
- tm = localtime(&tmp);
- strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
- last_t = now.tv_sec;
+ tm = localtime(&now.tv_sec);
+ strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
+ last_t = now.tv_sec;
}
return buf;
}
#ifdef HAVE_SPNEGO
#ifndef gss_mech_spnego
-static gss_OID_desc _gss_mech_spnego = {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
+static gss_OID_desc _gss_mech_spnego =
+ { 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
gss_OID gss_mech_spnego = &_gss_mech_spnego;
#endif
#endif
-int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char* function)
+int
+check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
+ const char *function)
{
if (GSS_ERROR(major_status)) {
- OM_uint32 maj_stat,min_stat;
- OM_uint32 msg_ctx = 0;
- gss_buffer_desc status_string;
- char buf[1024];
- size_t len;
+ OM_uint32 maj_stat, min_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ char buf[1024];
+ size_t len;
- len = 0;
- msg_ctx = 0;
- while (!msg_ctx) {
- /* convert major status code (GSS-API error) to text */
- maj_stat = gss_display_status(&min_stat, major_status,
- GSS_C_GSS_CODE,
- GSS_C_NULL_OID,
- &msg_ctx, &status_string);
- if (maj_stat == GSS_S_COMPLETE) {
- if (sizeof(buf) > len + status_string.length + 1) {
- sprintf(buf+len, "%s", (char*) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- break;
- }
- gss_release_buffer(&min_stat, &status_string);
- }
- if (sizeof(buf) > len + 2) {
- sprintf(buf+len, "%s", ". ");
- len += 2;
- }
- msg_ctx = 0;
- while (!msg_ctx) {
- /* convert minor status code (underlying routine error) to text */
- maj_stat = gss_display_status(&min_stat, minor_status,
- GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
- &msg_ctx, &status_string);
- if (maj_stat == GSS_S_COMPLETE) {
- if (sizeof(buf) > len + status_string.length ) {
- sprintf(buf+len, "%s", (char*) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- break;
- }
- gss_release_buffer(&min_stat, &status_string);
- }
- fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM, function, buf);
- return(1);
+ len = 0;
+ msg_ctx = 0;
+ while (!msg_ctx) {
+ /* convert major status code (GSS-API error) to text */
+ maj_stat = gss_display_status(&min_stat, major_status,
+ GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
+ if (maj_stat == GSS_S_COMPLETE) {
+ if (sizeof(buf) > len + status_string.length + 1) {
+ sprintf(buf + len, "%s", (char *) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ if (sizeof(buf) > len + 2) {
+ sprintf(buf + len, "%s", ". ");
+ len += 2;
+ }
+ msg_ctx = 0;
+ while (!msg_ctx) {
+ /* convert minor status code (underlying routine error) to text */
+ maj_stat = gss_display_status(&min_stat, minor_status,
+ GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
+ if (maj_stat == GSS_S_COMPLETE) {
+ if (sizeof(buf) > len + status_string.length) {
+ sprintf(buf + len, "%s", (char *) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM, function,
+ buf);
+ return (1);
}
- return(0);
+ return (0);
}
-const char *squid_kerb_proxy_auth(char *proxy)
+const char *
+squid_kerb_proxy_auth(char *proxy)
{
OM_uint32 major_status, minor_status;
- gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
- gss_name_t server_name = GSS_C_NO_NAME;
- gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
- char *token = NULL;
-
- setbuf(stdout,NULL);
- setbuf(stdin,NULL);
-
- if (!proxy ) {
- fprintf(stderr, "%s| %s: Error: No proxy server name\n", LogTime(), PROGRAM);
- return NULL;
+ gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
+ gss_name_t server_name = GSS_C_NO_NAME;
+ gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ char *token = NULL;
+
+ setbuf(stdout, NULL);
+ setbuf(stdin, NULL);
+
+ if (!proxy) {
+ fprintf(stderr, "%s| %s: Error: No proxy server name\n", LogTime(),
+ PROGRAM);
+ return NULL;
}
- service.value = xmalloc(strlen("HTTP")+strlen(proxy)+2);
- snprintf(service.value,strlen("HTTP")+strlen(proxy)+2,"%s@%s","HTTP",proxy);
- service.length = strlen((char *)service.value);
+ service.value = xmalloc(strlen("HTTP") + strlen(proxy) + 2);
+ snprintf((char*)service.value, strlen("HTTP") + strlen(proxy) + 2, "%s@%s", "HTTP", proxy);
+ service.length = strlen((char *) service.value);
major_status = gss_import_name(&minor_status, &service,
- gss_nt_service_name, &server_name);
+ gss_nt_service_name, &server_name);
- if (check_gss_err(major_status,minor_status,"gss_import_name()") )
- goto cleanup;
+ if (check_gss_err(major_status, minor_status, "gss_import_name()"))
+ goto cleanup;
major_status = gss_init_sec_context(&minor_status,
- GSS_C_NO_CREDENTIAL,
- &gss_context,
- server_name,
+ GSS_C_NO_CREDENTIAL, &gss_context, server_name,
#ifdef HAVE_SPNEGO
- gss_mech_spnego,
+ gss_mech_spnego,
#else
- 0,
+ 0,
#endif
- 0,
- 0,
- GSS_C_NO_CHANNEL_BINDINGS,
- &input_token,
- NULL,
- &output_token,
- NULL,
- NULL);
+ 0,
+ 0,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &input_token, NULL, &output_token, NULL, NULL);
- if (check_gss_err(major_status,minor_status,"gss_init_sec_context()") )
- goto cleanup;
+ if (check_gss_err(major_status, minor_status, "gss_init_sec_context()"))
+ goto cleanup;
if (output_token.length) {
- token=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(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);
}
-cleanup:
+ cleanup:
gss_delete_sec_context(&minor_status, &gss_context, NULL);
gss_release_buffer(&minor_status, &service);
gss_release_buffer(&minor_status, &input_token);
@@ -214,18 +227,38 @@
return token;
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
const char *Token;
+ int count;
- if (argc < 1) {
- fprintf(stderr, "%s| %s: Error: No proxy server name given\n", LogTime(), PROGRAM);
- exit(99);
- }
- Token = (const char *)squid_kerb_proxy_auth(argv[1]);
- fprintf(stdout,"Token: %s\n",Token?Token:"NULL");
+ if (argc < 2) {
+ fprintf(stderr, "%s| %s: Error: No proxy server name given\n",
+ LogTime(), PROGRAM);
+ exit(99);
+ }
+ if (argc == 3) {
+ count = atoi(argv[2]);
+ while (count > 0) {
+ Token = (const char *) squid_kerb_proxy_auth(argv[1]);
+ fprintf(stdout, "YR %s\n", Token ? Token : "NULL");
+ count--;
+ }
+ fprintf(stdout, "QQ\n");
+ } else {
+ Token = (const char *) squid_kerb_proxy_auth(argv[1]);
+ fprintf(stdout, "Token: %s\n", Token ? Token : "NULL");
+ }
exit(0);
}
-
+#else
+#include <stdlib.h>
+int
+main(int argc, char *argv[])
+{
+ exit(-1);
+}
+#endif /* HAVE_GSSAPI */
=== renamed file 'helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c' => 'helpers/negotiate_auth/kerberos/spnegohelp/derparse.cc'
--- helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c 2008-10-10 08:02:53 +0000
+++ helpers/negotiate_auth/kerberos/spnegohelp/derparse.cc 2009-09-11 07:19:29 +0000
@@ -22,6 +22,7 @@
//
/////////////////////////////////////////////////////////////
+#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
@@ -32,11 +33,11 @@
// The GSS Mechanism OID enumeration values (SPNEGO_MECH_OID) control which offset in
// the array below, that a mechanism can be found.
//
-MECH_OID g_stcMechOIDList [] = {
- { (unsigned char*) "\x06\x09\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5_Legacy }, // 1.2.840.48018.1.2.2
- { (unsigned char*) "\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5 }, // 1.2.840.113554.1.2.2
- { (unsigned char*) "\x06\x06\x2b\x06\x01\x05\x05\x02", 8, 6, spnego_mech_oid_Spnego }, // 1.3.6.1.1.5.5.2
- { (unsigned char*) "", 0, 0, spnego_mech_oid_NotUsed } // Placeholder
+MECH_OID g_stcMechOIDList[] = {
+ {(unsigned char *) "\x06\x09\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5_Legacy}, // 1.2.840.48018.1.2.2
+ {(unsigned char *) "\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5}, // 1.2.840.113554.1.2.2
+ {(unsigned char *) "\x06\x06\x2b\x06\x01\x05\x05\x02", 8, 6, spnego_mech_oid_Spnego}, // 1.3.6.1.1.5.5.2
+ {(unsigned char *) "", 0, 0, spnego_mech_oid_NotUsed} // Placeholder
};
/////////////////////////////////////////////////////////////////////////////
@@ -62,93 +63,101 @@
//
////////////////////////////////////////////////////////////////////////////
-int ASNDerGetLength( unsigned char* pbLengthData, long nBoundaryLength, long* pnLength,
- long* pnNumLengthBytes )
+int
+ASNDerGetLength(unsigned char *pbLengthData, long nBoundaryLength,
+ long *pnLength, long *pnNumLengthBytes)
{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
- int nNumLengthBytes = 0;
+ int nReturn = SPNEGO_E_INVALID_LENGTH;
+ int nNumLengthBytes = 0;
// First check if the extended length bit is set
- if ( *pbLengthData & LEN_XTND ) {
- // Lower 7 bits contain the number of trailing bytes that describe the length
- nNumLengthBytes = *pbLengthData & LEN_MASK;
-
- // Check that the number of bytes we are about to read is within our boundary
- // constraints
-
- if ( nNumLengthBytes <= nBoundaryLength - 1 ) {
-
- // For now, our handler won't deal with lengths greater than 4 bytes
- if ( nNumLengthBytes >= 1 && nNumLengthBytes <= 4 ) {
- // 0 out the initial length
- *pnLength = 0L;
-
- // Bump by 1 byte
- pbLengthData++;
+ if (*pbLengthData & LEN_XTND) {
+ // Lower 7 bits contain the number of trailing bytes that describe the length
+ nNumLengthBytes = *pbLengthData & LEN_MASK;
+
+ // Check that the number of bytes we are about to read is within our boundary
+ // constraints
+
+ if (nNumLengthBytes <= nBoundaryLength - 1) {
+
+ // For now, our handler won't deal with lengths greater than 4 bytes
+ if (nNumLengthBytes >= 1 && nNumLengthBytes <= 4) {
+ // 0 out the initial length
+ *pnLength = 0L;
+
+ // Bump by 1 byte
+ pbLengthData++;
#if defined(__LITTLE_ENDIAN__) || !defined(WORDS_BIGENDIAN)
- // There may be a cleaner way to do this, but for now, this seems to be
- // an easy way to do the transformation
- switch ( nNumLengthBytes ) {
- case 1: {
- *( ( (unsigned char*) pnLength ) ) = *pbLengthData;
- break;
- }
-
- case 2: {
- *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 1);
- *( ( (unsigned char*) pnLength ) + 1 ) = *(pbLengthData);
-
- break;
- }
-
- case 3: {
- *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 2);
- *( ( (unsigned char*) pnLength ) + 2 ) = *(pbLengthData + 1);
- *( ( (unsigned char*) pnLength ) + 3 ) = *(pbLengthData);
- break;
- }
-
- case 4: {
- *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 3);
- *( ( (unsigned char*) pnLength ) + 1 ) = *(pbLengthData + 2);
- *( ( (unsigned char*) pnLength ) + 2 ) = *(pbLengthData + 1);
- *( ( (unsigned char*) pnLength ) + 3 ) = *(pbLengthData);
- break;
- }
-
- } // SWITCH ( nNumLengthBytes )
+ // There may be a cleaner way to do this, but for now, this seems to be
+ // an easy way to do the transformation
+ switch (nNumLengthBytes) {
+ case 1:
+ {
+ *(((unsigned char *) pnLength)) = *pbLengthData;
+ break;
+ }
+
+ case 2:
+ {
+ *(((unsigned char *) pnLength)) = *(pbLengthData + 1);
+ *(((unsigned char *) pnLength) + 1) = *(pbLengthData);
+
+ break;
+ }
+
+ case 3:
+ {
+ *(((unsigned char *) pnLength)) = *(pbLengthData + 2);
+ *(((unsigned char *) pnLength) + 2) =
+ *(pbLengthData + 1);
+ *(((unsigned char *) pnLength) + 3) = *(pbLengthData);
+ break;
+ }
+
+ case 4:
+ {
+ *(((unsigned char *) pnLength)) = *(pbLengthData + 3);
+ *(((unsigned char *) pnLength) + 1) =
+ *(pbLengthData + 2);
+ *(((unsigned char *) pnLength) + 2) =
+ *(pbLengthData + 1);
+ *(((unsigned char *) pnLength) + 3) = *(pbLengthData);
+ break;
+ }
+
+ } // SWITCH ( nNumLengthBytes )
#else
- // We are Big-Endian, so the length can be copied in from the source
- // as is. Ensure that we adjust for the number of bytes we actually
- // copy.
+ // We are Big-Endian, so the length can be copied in from the source
+ // as is. Ensure that we adjust for the number of bytes we actually
+ // copy.
- memcpy( ( (unsigned char *) pnLength ) + ( 4 - nNumLengthBytes ),
- pbLengthData, nNumLengthBytes );
+ memcpy(((unsigned char *) pnLength) + (4 - nNumLengthBytes),
+ pbLengthData, nNumLengthBytes);
#endif
- // Account for the initial length byte
- *pnNumLengthBytes = nNumLengthBytes + 1;
- nReturn = SPNEGO_E_SUCCESS;
-
- } // IF Valid Length
-
- } // IF num bytes to read is within the boundary length
-
- } // IF xtended length
+ // Account for the initial length byte
+ *pnNumLengthBytes = nNumLengthBytes + 1;
+ nReturn = SPNEGO_E_SUCCESS;
+
+ } // IF Valid Length
+
+ } // IF num bytes to read is within the boundary length
+
+ } // IF xtended length
else {
- // Extended bit is not set, so the length is in the value and the one
- // byte describes the length
- *pnLength = *pbLengthData & LEN_MASK;
- *pnNumLengthBytes = 1;
- nReturn = SPNEGO_E_SUCCESS;
+ // Extended bit is not set, so the length is in the value and the one
+ // byte describes the length
+ *pnLength = *pbLengthData & LEN_MASK;
+ *pnNumLengthBytes = 1;
+ nReturn = SPNEGO_E_SUCCESS;
}
- LOG(("ASNDerGetLength returned %d\n",nReturn));
+ LOG(("ASNDerGetLength returned %d\n", nReturn));
return nReturn;
}
@@ -164,7 +173,7 @@
// [in] nLengthWithToken - Expected token length (with data)
// [in] nBoundaryLength - Length that value must not exceed.
// [out] pnLength - Filled out with data length
-// [out] pnTokenLength - Filled out with number of bytes
+// [out] pnTokenLength - Filled out with number of bytes
// consumed by token identifier and length.
//
// Returns:
@@ -179,59 +188,60 @@
//
////////////////////////////////////////////////////////////////////////////
-int ASNDerCheckToken( unsigned char* pbTokenData, unsigned char nToken,
- long nLengthWithToken, long nBoundaryLength,
- long* pnLength, long* pnTokenLength )
+int
+ASNDerCheckToken(unsigned char *pbTokenData, unsigned char nToken,
+ long nLengthWithToken, long nBoundaryLength,
+ long *pnLength, long *pnTokenLength)
{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
- long nNumLengthBytes = 0L;
+ int nReturn = SPNEGO_E_INVALID_LENGTH;
+ long nNumLengthBytes = 0L;
// Make sure that we've at least got 2 bytes of room to work with
- if ( nBoundaryLength >= 2 ) {
- // The first byte of the token data MUST match the specified token
- if ( *pbTokenData == nToken ) {
- // Next byte indicates the length
- pbTokenData++;
-
- // Get the length described by the token
- if ( ( nReturn = ASNDerGetLength( pbTokenData, nBoundaryLength, pnLength,
- &nNumLengthBytes ) ) == SPNEGO_E_SUCCESS ) {
- // Verify that the length is LESS THAN the boundary length
- // (this should prevent us walking out of our buffer)
- if ( ( nBoundaryLength - ( nNumLengthBytes + 1 ) < *pnLength ) ) {
-
- nReturn = SPNEGO_E_INVALID_LENGTH;
-
- }
-
- // If we were passed a length to check, do so now
- if ( nLengthWithToken > 0L ) {
-
- // Check that the expected length matches
- if ( ( nLengthWithToken - ( nNumLengthBytes + 1 ) ) != *pnLength ) {
-
- nReturn = SPNEGO_E_INVALID_LENGTH;
-
- }
-
- } // IF need to validate length
-
- if ( SPNEGO_E_SUCCESS == nReturn ) {
- *pnTokenLength = nNumLengthBytes + 1;
- }
-
- } // IF ASNDerGetLength
-
- } // IF token matches
- else {
- nReturn = SPNEGO_E_TOKEN_NOT_FOUND;
- }
-
- } // IF Boundary Length is at least 2 bytes
-
- LOG(("ASNDerCheckToken returned %d\n",nReturn));
+ if (nBoundaryLength >= 2) {
+ // The first byte of the token data MUST match the specified token
+ if (*pbTokenData == nToken) {
+ // Next byte indicates the length
+ pbTokenData++;
+
+ // Get the length described by the token
+ if ((nReturn =
+ ASNDerGetLength(pbTokenData, nBoundaryLength, pnLength,
+ &nNumLengthBytes)) == SPNEGO_E_SUCCESS) {
+ // Verify that the length is LESS THAN the boundary length
+ // (this should prevent us walking out of our buffer)
+ if ((nBoundaryLength - (nNumLengthBytes + 1) < *pnLength)) {
+
+ nReturn = SPNEGO_E_INVALID_LENGTH;
+
+ }
+ // If we were passed a length to check, do so now
+ if (nLengthWithToken > 0L) {
+
+ // Check that the expected length matches
+ if ((nLengthWithToken - (nNumLengthBytes + 1)) != *pnLength) {
+
+ nReturn = SPNEGO_E_INVALID_LENGTH;
+
+ }
+
+ } // IF need to validate length
+
+ if (SPNEGO_E_SUCCESS == nReturn) {
+ *pnTokenLength = nNumLengthBytes + 1;
+ }
+
+ } // IF ASNDerGetLength
+
+ } // IF token matches
+ else {
+ nReturn = SPNEGO_E_TOKEN_NOT_FOUND;
+ }
+
+ } // IF Boundary Length is at least 2 bytes
+
+ LOG(("ASNDerCheckToken returned %d\n", nReturn));
return nReturn;
}
@@ -256,34 +266,36 @@
//
////////////////////////////////////////////////////////////////////////////
-int ASNDerCheckOID( unsigned char* pbTokenData, SPNEGO_MECH_OID nMechOID, long nBoundaryLength,
- long* pnTokenLength )
+int
+ASNDerCheckOID(unsigned char *pbTokenData, SPNEGO_MECH_OID nMechOID,
+ long nBoundaryLength, long *pnTokenLength)
{
- int nReturn = 0L;
- long nLength = 0L;
+ int nReturn = 0L;
+ long nLength = 0L;
// Verify that we have an OID token
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, OID, 0L, nBoundaryLength,
- &nLength, pnTokenLength ) ) == SPNEGO_E_SUCCESS ) {
- // Add the data length to the Token Length
- *pnTokenLength += nLength;
-
- // Token Lengths plus the actual length must match the length in our OID list element.
- // If it doesn't, we're done
- if ( *pnTokenLength == g_stcMechOIDList[nMechOID].iLen ) {
- // Memcompare the token and the expected field
- if ( memcmp( pbTokenData, g_stcMechOIDList[nMechOID].ucOid, *pnTokenLength ) != 0 ) {
- LOG(("ASNDerCheckOID memcmp failed\n"));
- nReturn = SPNEGO_E_UNEXPECTED_OID;
- }
- } else {
- LOG(("ASNDerCheckOID token length failed\n"));
- nReturn = SPNEGO_E_UNEXPECTED_OID;
- }
-
- } // IF OID Token CHecks
-
- LOG(("ASNDerCheckOID returned %d\n",nReturn));
+ if ((nReturn = ASNDerCheckToken(pbTokenData, OID, 0L, nBoundaryLength,
+ &nLength, pnTokenLength)) == SPNEGO_E_SUCCESS) {
+ // Add the data length to the Token Length
+ *pnTokenLength += nLength;
+
+ // Token Lengths plus the actual length must match the length in our OID list element.
+ // If it doesn't, we're done
+ if (*pnTokenLength == g_stcMechOIDList[nMechOID].iLen) {
+ // Memcompare the token and the expected field
+ if (memcmp(pbTokenData, g_stcMechOIDList[nMechOID].ucOid,
+ *pnTokenLength) != 0) {
+ LOG(("ASNDerCheckOID memcmp failed\n"));
+ nReturn = SPNEGO_E_UNEXPECTED_OID;
+ }
+ } else {
+ LOG(("ASNDerCheckOID token length failed\n"));
+ nReturn = SPNEGO_E_UNEXPECTED_OID;
+ }
+
+ } // IF OID Token CHecks
+
+ LOG(("ASNDerCheckOID returned %d\n", nReturn));
return nReturn;
}
@@ -305,28 +317,29 @@
//
////////////////////////////////////////////////////////////////////////////
-int ASNDerCalcNumLengthBytes( long nLength )
+int
+ASNDerCalcNumLengthBytes(long nLength)
{
- if ( nLength <= 0x7F ) {
- // A single byte will be sufficient for describing this length.
- // The byte will simply contain the length
- return 1;
- } else if ( nLength <= 0xFF ) {
- // Two bytes are necessary, one to say how many following bytes
- // describe the length, and one to give the length
- return 2;
- } else if ( nLength <= 0xFFFF ) {
- // Three bytes are necessary, one to say how many following bytes
- // describe the length, and two to give the length
- return 3;
- } else if ( nLength <= 0xFFFFFF ) {
- // Four bytes are necessary, one to say how many following bytes
- // describe the length, and three to give the length
- return 4;
+ if (nLength <= 0x7F) {
+ // A single byte will be sufficient for describing this length.
+ // The byte will simply contain the length
+ return 1;
+ } else if (nLength <= 0xFF) {
+ // Two bytes are necessary, one to say how many following bytes
+ // describe the length, and one to give the length
+ return 2;
+ } else if (nLength <= 0xFFFF) {
+ // Three bytes are necessary, one to say how many following bytes
+ // describe the length, and two to give the length
+ return 3;
+ } else if (nLength <= 0xFFFFFF) {
+ // Four bytes are necessary, one to say how many following bytes
+ // describe the length, and three to give the length
+ return 4;
} else {
- // Five bytes are necessary, one to say how many following bytes
- // describe the length, and four to give the length
- return 5;
+ // Five bytes are necessary, one to say how many following bytes
+ // describe the length, and four to give the length
+ return 5;
}
}
@@ -350,11 +363,12 @@
//
////////////////////////////////////////////////////////////////////////////
-long ASNDerCalcTokenLength( long nLength, long nDataLength )
+long
+ASNDerCalcTokenLength(long nLength, long nDataLength)
{
// Add a byte to the length size to account for a single byte to
// hold the token type.
- long nTotalLength = ASNDerCalcNumLengthBytes( nLength ) + 1;
+ long nTotalLength = ASNDerCalcNumLengthBytes(nLength) + 1;
return nTotalLength + nDataLength;
}
@@ -379,19 +393,19 @@
//
////////////////////////////////////////////////////////////////////////////
-long ASNDerCalcElementLength( long nDataLength, long* pnInternalLength )
+long
+ASNDerCalcElementLength(long nDataLength, long *pnInternalLength)
{
// First the type token and the actual data
- long nTotalLength = ASNDerCalcTokenLength( nDataLength, nDataLength );
+ long nTotalLength = ASNDerCalcTokenLength(nDataLength, nDataLength);
// Internal length is the length without the element sequence token
- if ( NULL != pnInternalLength ) {
- *pnInternalLength = nTotalLength;
+ if (NULL != pnInternalLength) {
+ *pnInternalLength = nTotalLength;
}
-
// Next add in the element's sequence token (remember that its
// length is the total length of the type token and data)
- nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
+ nTotalLength += ASNDerCalcTokenLength(nTotalLength, 0L);
return nTotalLength;
}
@@ -417,21 +431,21 @@
//
////////////////////////////////////////////////////////////////////////////
-long ASNDerCalcMechListLength( SPNEGO_MECH_OID mechoid, long* pnInternalLength )
+long
+ASNDerCalcMechListLength(SPNEGO_MECH_OID mechoid, long *pnInternalLength)
{
// First the OID
- long nTotalLength = g_stcMechOIDList[mechoid].iLen;
+ long nTotalLength = g_stcMechOIDList[mechoid].iLen;
// Next add in a sequence token
- nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
+ nTotalLength += ASNDerCalcTokenLength(nTotalLength, 0L);
// Internal length is the length without the element sequence token
- if ( NULL != pnInternalLength ) {
- *pnInternalLength = nTotalLength;
+ if (NULL != pnInternalLength) {
+ *pnInternalLength = nTotalLength;
}
-
// Finally add in the element's sequence token
- nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
+ nTotalLength += ASNDerCalcTokenLength(nTotalLength, 0L);
return nTotalLength;
}
@@ -454,71 +468,77 @@
//
////////////////////////////////////////////////////////////////////////////
-int ASNDerWriteLength( unsigned char* pbData, long nLength )
+int
+ASNDerWriteLength(unsigned char *pbData, long nLength)
{
- int nNumBytesRequired = ASNDerCalcNumLengthBytes( nLength );
- int nNumLengthBytes = nNumBytesRequired - 1;
-
-
- if ( nNumBytesRequired > 1 ) {
-
- // Write out the number of bytes following which will be used
- *pbData = (unsigned char ) ( LEN_XTND | nNumLengthBytes );
-
- // Point to where we'll actually write the length
- pbData++;
+ int nNumBytesRequired = ASNDerCalcNumLengthBytes(nLength);
+ int nNumLengthBytes = nNumBytesRequired - 1;
+
+
+ if (nNumBytesRequired > 1) {
+
+ // Write out the number of bytes following which will be used
+ *pbData = (unsigned char) (LEN_XTND | nNumLengthBytes);
+
+ // Point to where we'll actually write the length
+ pbData++;
#if defined(__LITTLE_ENDIAN__) || !defined(WORDS_BIGENDIAN)
- // There may be a cleaner way to do this, but for now, this seems to be
- // an easy way to do the transformation
- switch ( nNumLengthBytes ) {
- case 1: {
- // Cast the length to a single byte, since we know that it
- // is 0x7F or less (or we wouldn't only need a single byte).
-
- *pbData = (unsigned char) nLength;
- break;
- }
-
- case 2: {
- *pbData = *( ( (unsigned char*) &nLength ) + 1 );
- *( pbData + 1) = *( ( (unsigned char*) &nLength ) );
- break;
- }
-
- case 3: {
- *pbData = *( ( (unsigned char*) &nLength ) + 3 );
- *( pbData + 1) = *( ( (unsigned char*) &nLength ) + 2 );
- *( pbData + 2) = *( ( (unsigned char*) &nLength ) );
- break;
- }
-
- case 4: {
- *pbData = *( ( (unsigned char*) &nLength ) + 3 );
- *( pbData + 1) = *( ( (unsigned char*) &nLength ) + 2 );
- *( pbData + 2) = *( ( (unsigned char*) &nLength ) + 1 );
- *( pbData + 3) = *( ( (unsigned char*) &nLength ) );
- break;
- }
-
- } // SWITCH ( nNumLengthBytes )
+ // There may be a cleaner way to do this, but for now, this seems to be
+ // an easy way to do the transformation
+ switch (nNumLengthBytes) {
+ case 1:
+ {
+ // Cast the length to a single byte, since we know that it
+ // is 0x7F or less (or we wouldn't only need a single byte).
+
+ *pbData = (unsigned char) nLength;
+ break;
+ }
+
+ case 2:
+ {
+ *pbData = *(((unsigned char *) &nLength) + 1);
+ *(pbData + 1) = *(((unsigned char *) &nLength));
+ break;
+ }
+
+ case 3:
+ {
+ *pbData = *(((unsigned char *) &nLength) + 3);
+ *(pbData + 1) = *(((unsigned char *) &nLength) + 2);
+ *(pbData + 2) = *(((unsigned char *) &nLength));
+ break;
+ }
+
+ case 4:
+ {
+ *pbData = *(((unsigned char *) &nLength) + 3);
+ *(pbData + 1) = *(((unsigned char *) &nLength) + 2);
+ *(pbData + 2) = *(((unsigned char *) &nLength) + 1);
+ *(pbData + 3) = *(((unsigned char *) &nLength));
+ break;
+ }
+
+ } // SWITCH ( nNumLengthBytes )
#else
- // We are Big-Endian, so the length can be copied in from the source
- // as is. Ensure that we adjust for the number of bytes we actually
- // copy.
+ // We are Big-Endian, so the length can be copied in from the source
+ // as is. Ensure that we adjust for the number of bytes we actually
+ // copy.
- memcpy( pbData,
- ( (unsigned char *) &nLength ) + ( 4 - nNumLengthBytes ), nNumLengthBytes );
+ memcpy(pbData,
+ ((unsigned char *) &nLength) + (4 - nNumLengthBytes),
+ nNumLengthBytes);
#endif
- } // IF > 1 byte for length
+ } // IF > 1 byte for length
else {
- // Cast the length to a single byte, since we know that it
- // is 0x7F or less (or we wouldn't only need a single byte).
+ // Cast the length to a single byte, since we know that it
+ // is 0x7F or less (or we wouldn't only need a single byte).
- *pbData = (unsigned char) nLength;
+ *pbData = (unsigned char) nLength;
}
return nNumBytesRequired;
@@ -545,11 +565,12 @@
//
////////////////////////////////////////////////////////////////////////////
-int ASNDerWriteToken( unsigned char* pbData, unsigned char ucType,
- unsigned char* pbTokenValue, long nLength )
+int
+ASNDerWriteToken(unsigned char *pbData, unsigned char ucType,
+ unsigned char *pbTokenValue, long nLength)
{
- int nTotalBytesWrittenOut = 0L;
- int nNumLengthBytesWritten = 0L;
+ int nTotalBytesWrittenOut = 0L;
+ int nNumLengthBytesWritten = 0L;
// Write out the type
*pbData = ucType;
@@ -559,7 +580,7 @@
pbData++;
// Now write out the length and adjust the number of bytes written out
- nNumLengthBytesWritten = ASNDerWriteLength( pbData, nLength );
+ nNumLengthBytesWritten = ASNDerWriteLength(pbData, nLength);
nTotalBytesWrittenOut += nNumLengthBytesWritten;
pbData += nNumLengthBytesWritten;
@@ -567,9 +588,9 @@
// Write out the token value if we got one. The assumption is that the
// nLength value indicates how many bytes are in pbTokenValue.
- if ( NULL != pbTokenValue ) {
- memcpy( pbData, pbTokenValue, nLength );
- nTotalBytesWrittenOut += nLength;
+ if (NULL != pbTokenValue) {
+ memcpy(pbData, pbTokenValue, nLength);
+ nTotalBytesWrittenOut += nLength;
}
return nTotalBytesWrittenOut;
@@ -595,10 +616,12 @@
//
////////////////////////////////////////////////////////////////////////////
-int ASNDerWriteOID( unsigned char* pbData, SPNEGO_MECH_OID eMechOID )
+int
+ASNDerWriteOID(unsigned char *pbData, SPNEGO_MECH_OID eMechOID)
{
- memcpy( pbData, g_stcMechOIDList[eMechOID].ucOid, g_stcMechOIDList[eMechOID].iLen );
+ memcpy(pbData, g_stcMechOIDList[eMechOID].ucOid,
+ g_stcMechOIDList[eMechOID].iLen);
return g_stcMechOIDList[eMechOID].iLen;
}
@@ -623,15 +646,16 @@
//
////////////////////////////////////////////////////////////////////////////
-long ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID mechoid )
+long
+ASNDerWriteMechList(unsigned char *pbData, SPNEGO_MECH_OID mechoid)
{
// First get the length
- long nInternalLength = 0L;
- long nMechListLength = ASNDerCalcMechListLength( mechoid, &nInternalLength );
- long nTempLength = 0L;
+ long nInternalLength = 0L;
+ long nMechListLength = ASNDerCalcMechListLength(mechoid, &nInternalLength);
+ long nTempLength = 0L;
- nTempLength = ASNDerWriteToken( pbData, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
- NULL, nInternalLength );
+ nTempLength = ASNDerWriteToken(pbData, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
+ NULL, nInternalLength);
// Adjust the data pointer
pbData += nTempLength;
@@ -639,9 +663,8 @@
// Now write the Sequence token and the OID (the OID is a BLOB in the global
// structure.
- nTempLength = ASNDerWriteToken( pbData, SPNEGO_CONSTRUCTED_SEQUENCE,
- g_stcMechOIDList[mechoid].ucOid,
- g_stcMechOIDList[mechoid].iLen );
+ nTempLength = ASNDerWriteToken(pbData, SPNEGO_CONSTRUCTED_SEQUENCE,
+ g_stcMechOIDList[mechoid].ucOid, g_stcMechOIDList[mechoid].iLen);
return nMechListLength;
}
@@ -668,23 +691,24 @@
//
////////////////////////////////////////////////////////////////////////////
-int ASNDerWriteElement( unsigned char* pbData, unsigned char ucElementSequence,
- unsigned char ucType, unsigned char* pbTokenValue, long nLength )
+int
+ASNDerWriteElement(unsigned char *pbData, unsigned char ucElementSequence,
+ unsigned char ucType, unsigned char *pbTokenValue, long nLength)
{
// First get the length
- long nInternalLength = 0L;
- long nElementLength = ASNDerCalcElementLength( nLength, &nInternalLength );
- long nTempLength = 0L;
+ long nInternalLength = 0L;
+ long nElementLength = ASNDerCalcElementLength(nLength, &nInternalLength);
+ long nTempLength = 0L;
// Write out the sequence byte and the length of the type and data
- nTempLength = ASNDerWriteToken( pbData, ucElementSequence, NULL, nInternalLength );
+ nTempLength =
+ ASNDerWriteToken(pbData, ucElementSequence, NULL, nInternalLength);
// Adjust the data pointer
pbData += nTempLength;
// Now write the type and the data.
- nTempLength = ASNDerWriteToken( pbData, ucType, pbTokenValue, nLength );
+ nTempLength = ASNDerWriteToken(pbData, ucType, pbTokenValue, nLength);
return nElementLength;
}
-
=== modified file 'helpers/negotiate_auth/kerberos/spnegohelp/derparse.h'
--- helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.h 2009-08-23 09:30:49 +0000
+++ helpers/negotiate_auth/kerberos/spnegohelp/derparse.h 2009-09-04 12:59:38 +0000
@@ -26,55 +26,56 @@
// C++ Specific
#if defined(__cplusplus)
-extern "C" {
+extern "C"
+{
#endif
- /* Identifier Types */
-#define IDENTIFIER_MASK 0xC0 // Bits 7 and 8
-#define IDENTIFIER_UNIVERSAL 0x00 // 00 = universal
-#define IDENTIFIER_APPLICATION 0x40 // 01 = application
-#define IDENTIFIER_CONTEXT_SPECIFIC 0x80 // 10 = context specific
-#define IDENTIFIER_PRIVATE 0xC0 // 11 = Private
-
- /* Encoding type */
-
-#define FORM_MASK 0x20 /* Bit 6 */
-#define PRIMITIVE 0x00 /* 0 = primitive */
-#define CONSTRUCTED 0x20 /* 1 = constructed */
-
- /* Universal tags */
-
-#define TAG_MASK 0x1F /* Bits 5 - 1 */
-#define BOOLEAN 0x01 /* 1: TRUE or FALSE */
-#define INTEGER 0x02 /* 2: Arbitrary precision integer */
-#define BITSTRING 0x03 /* 2: Sequence of bits */
-#define OCTETSTRING 0x04 /* 4: Sequence of bytes */
-#define NULLTAG 0x05 /* 5: NULL */
-#define OID 0x06 /* 6: Object Identifier (numeric sequence) */
-#define OBJDESCRIPTOR 0x07 /* 7: Object Descriptor (human readable) */
-#define EXTERNAL 0x08 /* 8: External / Instance Of */
-#define REAL 0x09 /* 9: Real (Mantissa * Base^Exponent) */
-#define ENUMERATED 0x0A /* 10: Enumerated */
-#define EMBEDDED_PDV 0x0B /* 11: Embedded Presentation Data Value */
-#define SEQUENCE 0x10 /* 16: Constructed Sequence / Sequence Of */
-#define SET 0x11 /* 17: Constructed Set / Set Of */
-#define NUMERICSTR 0x12 /* 18: Numeric String (digits only) */
-#define PRINTABLESTR 0x13 /* 19: Printable String */
-#define T61STR 0x14 /* 20: T61 String (Teletex) */
-#define VIDEOTEXSTR 0x15 /* 21: Videotex String */
-#define IA5STR 0x16 /* 22: IA5 String */
-#define UTCTIME 0x17 /* 23: UTC Time */
-#define GENERALIZEDTIME 0x18 /* 24: Generalized Time */
-#define GRAPHICSTR 0x19 /* 25: Graphic String */
-#define VISIBLESTR 0x1A /* 26: Visible String (ISO 646) */
-#define GENERALSTR 0x1B /* 27: General String */
-#define UNIVERSALSTR 0x1C /* 28: Universal String */
-#define BMPSTR 0x1E /* 30: Basic Multilingual Plane String */
-
- /* Length encoding */
-
-#define LEN_XTND 0x80 /* Indefinite or long form */
-#define LEN_MASK 0x7f /* Bits 7 - 1 */
+/* Identifier Types */
+#define IDENTIFIER_MASK 0xC0 // Bits 7 and 8
+#define IDENTIFIER_UNIVERSAL 0x00 // 00 = universal
+#define IDENTIFIER_APPLICATION 0x40 // 01 = application
+#define IDENTIFIER_CONTEXT_SPECIFIC 0x80 // 10 = context specific
+#define IDENTIFIER_PRIVATE 0xC0 // 11 = Private
+
+/* Encoding type */
+
+#define FORM_MASK 0x20 /* Bit 6 */
+#define PRIMITIVE 0x00 /* 0 = primitive */
+#define CONSTRUCTED 0x20 /* 1 = constructed */
+
+/* Universal tags */
+
+#define TAG_MASK 0x1F /* Bits 5 - 1 */
+#define BOOLEAN 0x01 /* 1: TRUE or FALSE */
+#define INTEGER 0x02 /* 2: Arbitrary precision integer */
+#define BITSTRING 0x03 /* 2: Sequence of bits */
+#define OCTETSTRING 0x04 /* 4: Sequence of bytes */
+#define NULLTAG 0x05 /* 5: NULL */
+#define OID 0x06 /* 6: Object Identifier (numeric sequence) */
+#define OBJDESCRIPTOR 0x07 /* 7: Object Descriptor (human readable) */
+#define EXTERNAL 0x08 /* 8: External / Instance Of */
+#define REAL 0x09 /* 9: Real (Mantissa * Base^Exponent) */
+#define ENUMERATED 0x0A /* 10: Enumerated */
+#define EMBEDDED_PDV 0x0B /* 11: Embedded Presentation Data Value */
+#define SEQUENCE 0x10 /* 16: Constructed Sequence / Sequence Of */
+#define SET 0x11 /* 17: Constructed Set / Set Of */
+#define NUMERICSTR 0x12 /* 18: Numeric String (digits only) */
+#define PRINTABLESTR 0x13 /* 19: Printable String */
+#define T61STR 0x14 /* 20: T61 String (Teletex) */
+#define VIDEOTEXSTR 0x15 /* 21: Videotex String */
+#define IA5STR 0x16 /* 22: IA5 String */
+#define UTCTIME 0x17 /* 23: UTC Time */
+#define GENERALIZEDTIME 0x18 /* 24: Generalized Time */
+#define GRAPHICSTR 0x19 /* 25: Graphic String */
+#define VISIBLESTR 0x1A /* 26: Visible String (ISO 646) */
+#define GENERALSTR 0x1B /* 27: General String */
+#define UNIVERSALSTR 0x1C /* 28: Universal String */
+#define BMPSTR 0x1E /* 30: Basic Multilingual Plane String */
+
+/* Length encoding */
+
+#define LEN_XTND 0x80 /* Indefinite or long form */
+#define LEN_MASK 0x7f /* Bits 7 - 1 */
//
// SPNEGO Token Parsing Constants
@@ -91,7 +92,7 @@
#define SPNEGO_NEGTARG_MAXLEN_NEGRESULT 1
// Application Specific Construct - Always at the start of a NegTokenInit
-#define SPNEGO_NEGINIT_APP_CONSTRUCT ( IDENTIFIER_APPLICATION | CONSTRUCTED ) // 0x60
+#define SPNEGO_NEGINIT_APP_CONSTRUCT ( IDENTIFIER_APPLICATION | CONSTRUCTED ) // 0x60
// Constructed Sequence token - after the actual token identifier token
#define SPNEGO_CONSTRUCTED_SEQUENCE ( SEQUENCE | CONSTRUCTED )
@@ -108,10 +109,10 @@
SPNEGO_TOKEN_INIT )
// Structure elements for NegTokenInit
-#define SPNEGO_NEGINIT_MECHTYPES 0x0 // MechTypes is element 0
-#define SPNEGO_NEGINIT_REQFLAGS 0x1 // ReqFlags is element 1
-#define SPNEGO_NEGINIT_MECHTOKEN 0x2 // MechToken is element 2
-#define SPNEGO_NEGINIT_MECHLISTMIC 0x3 // MechListMIC is element 3
+#define SPNEGO_NEGINIT_MECHTYPES 0x0 // MechTypes is element 0
+#define SPNEGO_NEGINIT_REQFLAGS 0x1 // ReqFlags is element 1
+#define SPNEGO_NEGINIT_MECHTOKEN 0x2 // MechToken is element 2
+#define SPNEGO_NEGINIT_MECHLISTMIC 0x3 // MechListMIC is element 3
// MechTypes element is 0xa0
#define SPNEGO_NEGINIT_ELEMENT_MECHTYPES ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
@@ -138,10 +139,10 @@
SPNEGO_TOKEN_TARG )
// Structure elements for NegTokenTarg
-#define SPNEGO_NEGTARG_NEGRESULT 0x0 // NegResult is element 0
-#define SPNEGO_NEGTARG_SUPPORTEDMECH 0x1 // SupportedMech is element 1
-#define SPNEGO_NEGTARG_RESPONSETOKEN 0x2 // ResponseToken is element 2
-#define SPNEGO_NEGTARG_MECHLISTMIC 0x3 // MechListMIC is element 3
+#define SPNEGO_NEGTARG_NEGRESULT 0x0 // NegResult is element 0
+#define SPNEGO_NEGTARG_SUPPORTEDMECH 0x1 // SupportedMech is element 1
+#define SPNEGO_NEGTARG_RESPONSETOKEN 0x2 // ResponseToken is element 2
+#define SPNEGO_NEGTARG_MECHLISTMIC 0x3 // MechListMIC is element 3
// NegResult element is 0xa0
#define SPNEGO_NEGTARG_ELEMENT_NEGRESULT ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
@@ -164,11 +165,12 @@
// of these which we'll use for validation/searches/parsing.
//
- typedef struct _mechOID {
- unsigned char* ucOid; // Byte representation of OID
- int iLen; // Length of the OID, length and identifier
- int iActualDataLen; // Length of the actual OID
- SPNEGO_MECH_OID eMechanismOID; // Which OID is this?
+ typedef struct _mechOID
+ {
+ unsigned char *ucOid; // Byte representation of OID
+ int iLen; // Length of the OID, length and identifier
+ int iActualDataLen; // Length of the actual OID
+ SPNEGO_MECH_OID eMechanismOID; // Which OID is this?
} MECH_OID;
@@ -176,24 +178,26 @@
// ASN Der functions
//
- int ASNDerGetLength( unsigned char* pbLengthData, long nBoundaryLength, long* pnLength,
- long* pnNumLengthBytes );
- int ASNDerCheckToken( unsigned char* pbTokenData, unsigned char nToken,
- long nCheckLength, long nBoundaryLength, long* pnLength,
- long* pnTokenLength );
- int ASNDerCheckOID( unsigned char* pbTokenData, SPNEGO_MECH_OID nMechOID, long nBoundaryLength,
- long* pnTokenLength );
- int ASNDerCalcNumLengthBytes( long nLength );
- long ASNDerCalcTokenLength( long nLength, long nDataLength );
- long ASNDerCalcElementLength( long nDataLength, long* pnInternalLength );
- long ASNDerCalcMechListLength( SPNEGO_MECH_OID mechoid, long* pnInternalLength );
- int ASNDerWriteLength( unsigned char* pbData, long nLength );
- int ASNDerWriteToken( unsigned char* pbData, unsigned char ucType,
- unsigned char* pbTokenValue, long nLength );
- int ASNDerWriteOID( unsigned char* pbData, SPNEGO_MECH_OID eMechOID );
- long ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID mechoid );
- int ASNDerWriteElement( unsigned char* pbData, unsigned char ucElementSequence,
- unsigned char ucType, unsigned char* pbTokenValue, long nLength );
+ int ASNDerGetLength(unsigned char *pbLengthData, long nBoundaryLength,
+ long *pnLength, long *pnNumLengthBytes);
+ int ASNDerCheckToken(unsigned char *pbTokenData, unsigned char nToken,
+ long nCheckLength, long nBoundaryLength, long *pnLength,
+ long *pnTokenLength);
+ int ASNDerCheckOID(unsigned char *pbTokenData, SPNEGO_MECH_OID nMechOID,
+ long nBoundaryLength, long *pnTokenLength);
+ int ASNDerCalcNumLengthBytes(long nLength);
+ long ASNDerCalcTokenLength(long nLength, long nDataLength);
+ long ASNDerCalcElementLength(long nDataLength, long *pnInternalLength);
+ long ASNDerCalcMechListLength(SPNEGO_MECH_OID mechoid,
+ long *pnInternalLength);
+ int ASNDerWriteLength(unsigned char *pbData, long nLength);
+ int ASNDerWriteToken(unsigned char *pbData, unsigned char ucType,
+ unsigned char *pbTokenValue, long nLength);
+ int ASNDerWriteOID(unsigned char *pbData, SPNEGO_MECH_OID eMechOID);
+ long ASNDerWriteMechList(unsigned char *pbData, SPNEGO_MECH_OID mechoid);
+ int ASNDerWriteElement(unsigned char *pbData,
+ unsigned char ucElementSequence, unsigned char ucType,
+ unsigned char *pbTokenValue, long nLength);
// C++ Specific
@@ -202,4 +206,3 @@
#endif
#endif
-
=== renamed file 'helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.c' => 'helpers/negotiate_auth/kerberos/spnegohelp/spnego.cc'
--- helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.c 2008-10-10 08:02:53 +0000
+++ helpers/negotiate_auth/kerberos/spnegohelp/spnego.cc 2009-09-11 07:19:29 +0000
@@ -32,7 +32,7 @@
// Defined in DERPARSE.C
//
-extern MECH_OID g_stcMechOIDList [];
+extern MECH_OID g_stcMechOIDList[];
/**********************************************************************/
@@ -69,19 +69,21 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoInitFromBinary( unsigned char* pbTokenData, unsigned long ulLength, SPNEGO_TOKEN_HANDLE* phSpnegoToken )
+int
+spnegoInitFromBinary(unsigned char *pbTokenData, unsigned long ulLength,
+ SPNEGO_TOKEN_HANDLE * phSpnegoToken)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN **ppSpnegoToken = (SPNEGO_TOKEN **) phSpnegoToken;
// Pass off to a handler function that allows tighter control over how the token structure
// is handled. In this case, we want the token data copied and we want the associated buffer
// freed.
- nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYDATA,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, pbTokenData,
- ulLength, ppSpnegoToken );
+ nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYDATA,
+ SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, pbTokenData,
+ ulLength, ppSpnegoToken);
- LOG(("spnegoInitFromBinary returned %d\n",nReturn));
+ LOG(("spnegoInitFromBinary returned %d\n", nReturn));
return nReturn;
}
@@ -112,62 +114,62 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken )
+int
+spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,
+ unsigned char ucContextFlags, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- long nTokenLength = 0L;
- long nInternalTokenLength = 0L;
- unsigned char* pbTokenData = NULL;
- SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken;
-
- if ( NULL != ppSpnegoToken &&
- IsValidMechOid( MechType ) &&
- IsValidContextFlags( ucContextFlags ) ) {
- // Get the actual token size
-
- if ( ( nReturn = CalculateMinSpnegoInitTokenSize( ulMechTokenLen, ulMechListMICLen,
- MechType, ( ucContextFlags != 0L ),
- &nTokenLength, &nInternalTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // Allocate a buffer to hold the data.
- pbTokenData = calloc( 1, nTokenLength );
-
- if ( NULL != pbTokenData ) {
-
- // Now write the token
- if ( ( nReturn = CreateSpnegoInitToken( MechType,
- ucContextFlags, pbMechToken,
- ulMechTokenLen, pbMechListMIC,
- ulMechListMICLen, pbTokenData,
- nTokenLength, nInternalTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
-
- // This will copy our allocated pointer, and ensure that the sructure cleans
- // up the data later
- nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYPTR,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
- pbTokenData, nTokenLength, ppSpnegoToken );
-
- }
-
- // Cleanup on failure
- if ( SPNEGO_E_SUCCESS != nReturn ) {
- free( pbTokenData );
- }
-
- } // IF alloc succeeded
- else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // If calculated token size
-
- } // IF Valid Parameters
-
- LOG(("spnegoCreateNegTokenInit returned %d\n",nReturn));
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ long nTokenLength = 0L;
+ long nInternalTokenLength = 0L;
+ unsigned char *pbTokenData = NULL;
+ SPNEGO_TOKEN **ppSpnegoToken = (SPNEGO_TOKEN **) phSpnegoToken;
+
+ if (NULL != ppSpnegoToken &&
+ IsValidMechOid(MechType) && IsValidContextFlags(ucContextFlags)) {
+ // Get the actual token size
+
+ if ((nReturn =
+ CalculateMinSpnegoInitTokenSize(ulMechTokenLen,
+ ulMechListMICLen, MechType, (ucContextFlags != 0L),
+ &nTokenLength, &nInternalTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Allocate a buffer to hold the data.
+ pbTokenData = calloc(1, nTokenLength);
+
+ if (NULL != pbTokenData) {
+
+ // Now write the token
+ if ((nReturn = CreateSpnegoInitToken(MechType,
+ ucContextFlags, pbMechToken,
+ ulMechTokenLen, pbMechListMIC,
+ ulMechListMICLen, pbTokenData,
+ nTokenLength, nInternalTokenLength))
+ == SPNEGO_E_SUCCESS) {
+
+ // This will copy our allocated pointer, and ensure that the sructure cleans
+ // up the data later
+ nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
+ SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
+ pbTokenData, nTokenLength, ppSpnegoToken);
+
+ }
+ // Cleanup on failure
+ if (SPNEGO_E_SUCCESS != nReturn) {
+ free(pbTokenData);
+ }
+
+ } // IF alloc succeeded
+ else {
+ nReturn = SPNEGO_E_OUT_OF_MEMORY;
+ }
+
+ } // If calculated token size
+
+ } // IF Valid Parameters
+
+ LOG(("spnegoCreateNegTokenInit returned %d\n", nReturn));
return nReturn;
}
@@ -197,16 +199,17 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoCreateNegTokenTarg( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken )
+int
+spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,
+ SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- long nTokenLength = 0L;
- long nInternalTokenLength = 0L;
- unsigned char* pbTokenData = NULL;
- SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ long nTokenLength = 0L;
+ long nInternalTokenLength = 0L;
+ unsigned char *pbTokenData = NULL;
+ SPNEGO_TOKEN **ppSpnegoToken = (SPNEGO_TOKEN **) phSpnegoToken;
//
// spnego_mech_oid_NotUsed and spnego_negresult_NotUsed
@@ -215,60 +218,57 @@
// is specified.
//
- if ( NULL != ppSpnegoToken &&
-
- ( IsValidMechOid( MechType ) ||
- spnego_mech_oid_NotUsed == MechType ) &&
-
- ( IsValidNegResult( spnegoNegResult ) ||
- spnego_negresult_NotUsed == spnegoNegResult ) &&
-
- !( !IsValidMechOid( MechType ) &&
- ( spnego_negresult_success == spnegoNegResult ||
- spnego_negresult_incomplete == spnegoNegResult ) ) ) {
-
- // Get the actual token size
-
- if ( ( nReturn = CalculateMinSpnegoTargTokenSize( MechType, spnegoNegResult, ulMechTokenLen,
- ulMechListMICLen, &nTokenLength,
- &nInternalTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // Allocate a buffer to hold the data.
- pbTokenData = calloc( 1, nTokenLength );
-
- if ( NULL != pbTokenData ) {
-
- // Now write the token
- if ( ( nReturn = CreateSpnegoTargToken( MechType,
- spnegoNegResult, pbMechToken,
- ulMechTokenLen, pbMechListMIC,
- ulMechListMICLen, pbTokenData,
- nTokenLength, nInternalTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
-
- // This will copy our allocated pointer, and ensure that the sructure cleans
- // up the data later
- nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYPTR,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
- pbTokenData, nTokenLength, ppSpnegoToken );
-
- }
-
- // Cleanup on failure
- if ( SPNEGO_E_SUCCESS != nReturn ) {
- free( pbTokenData );
- }
-
- } // IF alloc succeeded
- else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // If calculated token size
-
- } // IF Valid Parameters
-
- LOG(("spnegoCreateNegTokenTarg returned %d\n",nReturn));
+ if (NULL != ppSpnegoToken &&
+ (IsValidMechOid(MechType) ||
+ spnego_mech_oid_NotUsed == MechType) &&
+ (IsValidNegResult(spnegoNegResult) ||
+ spnego_negresult_NotUsed == spnegoNegResult) &&
+ !(!IsValidMechOid(MechType) &&
+ (spnego_negresult_success == spnegoNegResult ||
+ spnego_negresult_incomplete == spnegoNegResult))) {
+
+ // Get the actual token size
+
+ if ((nReturn =
+ CalculateMinSpnegoTargTokenSize(MechType, spnegoNegResult,
+ ulMechTokenLen, ulMechListMICLen, &nTokenLength,
+ &nInternalTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Allocate a buffer to hold the data.
+ pbTokenData = calloc(1, nTokenLength);
+
+ if (NULL != pbTokenData) {
+
+ // Now write the token
+ if ((nReturn = CreateSpnegoTargToken(MechType,
+ spnegoNegResult, pbMechToken,
+ ulMechTokenLen, pbMechListMIC,
+ ulMechListMICLen, pbTokenData,
+ nTokenLength, nInternalTokenLength))
+ == SPNEGO_E_SUCCESS) {
+
+ // This will copy our allocated pointer, and ensure that the sructure cleans
+ // up the data later
+ nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
+ SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
+ pbTokenData, nTokenLength, ppSpnegoToken);
+
+ }
+ // Cleanup on failure
+ if (SPNEGO_E_SUCCESS != nReturn) {
+ free(pbTokenData);
+ }
+
+ } // IF alloc succeeded
+ else {
+ nReturn = SPNEGO_E_OUT_OF_MEMORY;
+ }
+
+ } // If calculated token size
+
+ } // IF Valid Parameters
+
+ LOG(("spnegoCreateNegTokenTarg returned %d\n", nReturn));
return nReturn;
}
@@ -295,30 +295,30 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoTokenGetBinary( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData,
- unsigned long * pulDataLen )
+int
+spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ unsigned char *pbTokenData, unsigned long *pulDataLen)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters - pbTokenData is optional
- if ( IsValidSpnegoToken( pSpnegoToken ) &&
- NULL != pulDataLen ) {
-
- // Check for Buffer too small conditions
- if ( NULL == pbTokenData ||
- pSpnegoToken->ulBinaryDataLen > *pulDataLen ) {
- *pulDataLen = pSpnegoToken->ulBinaryDataLen;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- memcpy( pbTokenData, pSpnegoToken->pbBinaryData, pSpnegoToken->ulBinaryDataLen );
- *pulDataLen = pSpnegoToken->ulBinaryDataLen;
- nReturn = SPNEGO_E_SUCCESS;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoTokenGetBinary returned %d\n",nReturn));
+ if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
+
+ // Check for Buffer too small conditions
+ if (NULL == pbTokenData || pSpnegoToken->ulBinaryDataLen > *pulDataLen) {
+ *pulDataLen = pSpnegoToken->ulBinaryDataLen;
+ nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
+ } else {
+ memcpy(pbTokenData, pSpnegoToken->pbBinaryData,
+ pSpnegoToken->ulBinaryDataLen);
+ *pulDataLen = pSpnegoToken->ulBinaryDataLen;
+ nReturn = SPNEGO_E_SUCCESS;
+ }
+
+ } // IF parameters OK
+
+ LOG(("spnegoTokenGetBinary returned %d\n", nReturn));
return nReturn;;
}
@@ -339,9 +339,10 @@
//
////////////////////////////////////////////////////////////////////////////
-void spnegoFreeData( SPNEGO_TOKEN_HANDLE hSpnegoToken )
+void
+spnegoFreeData(SPNEGO_TOKEN_HANDLE hSpnegoToken)
{
- FreeSpnegoToken( (SPNEGO_TOKEN*) hSpnegoToken);
+ FreeSpnegoToken((SPNEGO_TOKEN *) hSpnegoToken);
return;
}
@@ -364,26 +365,25 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoGetTokenType( SPNEGO_TOKEN_HANDLE hSpnegoToken, int * piTokenType )
+int
+spnegoGetTokenType(SPNEGO_TOKEN_HANDLE hSpnegoToken, int *piTokenType)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
- if ( IsValidSpnegoToken( pSpnegoToken ) &&
- NULL != piTokenType &&
- pSpnegoToken) {
-
- // Check that the type in the structure makes sense
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) {
- *piTokenType = pSpnegoToken->ucTokenType;
- nReturn = SPNEGO_E_SUCCESS;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetTokenType returned %d\n",nReturn));
+ if (IsValidSpnegoToken(pSpnegoToken) && NULL != piTokenType && pSpnegoToken) {
+
+ // Check that the type in the structure makes sense
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
+ SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
+ *piTokenType = pSpnegoToken->ucTokenType;
+ nReturn = SPNEGO_E_SUCCESS;
+ }
+
+ } // IF parameters OK
+
+ LOG(("spnegoGetTokenType returned %d\n", nReturn));
return nReturn;
}
@@ -411,31 +411,34 @@
////////////////////////////////////////////////////////////////////////////
// Returns the Initial Mech Type in the MechList element in the NegInitToken.
-int spnegoIsMechTypeAvailable( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID MechOID, int * piMechTypeIndex )
+int
+spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ SPNEGO_MECH_OID MechOID, int *piMechTypeIndex)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
- if ( IsValidSpnegoToken( pSpnegoToken ) &&
- NULL != piMechTypeIndex &&
- IsValidMechOid( MechOID ) &&
- SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) {
-
- // Check if MechList is available
- if ( pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT].iElementPresent
- == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) {
- // Locate the MechOID in the list element
- nReturn = FindMechOIDInMechList(
- &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT],
- MechOID, piMechTypeIndex );
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoIsMechTypeAvailable returned %d\n",nReturn));
+ if (IsValidSpnegoToken(pSpnegoToken) &&
+ NULL != piMechTypeIndex &&
+ IsValidMechOid(MechOID) &&
+ SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+
+ // Check if MechList is available
+ if (pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT].
+ iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
+ // Locate the MechOID in the list element
+ nReturn =
+ FindMechOIDInMechList(&pSpnegoToken->
+ aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT], MechOID,
+ piMechTypeIndex);
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
+
+ } // IF parameters OK
+
+ LOG(("spnegoIsMechTypeAvailable returned %d\n", nReturn));
return nReturn;;
}
@@ -460,37 +463,44 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoGetContextFlags( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pucContextFlags )
+int
+spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ unsigned char *pucContextFlags)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
- if ( IsValidSpnegoToken( pSpnegoToken ) &&
- NULL != pucContextFlags &&
- SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) {
-
- // Check if ContextFlags is available
- if ( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].iElementPresent
- == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) {
- // The length should be two, the value should show a 1 bit difference in the difference byte, and
- // the value must be valid
- if ( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].nDatalength == SPNEGO_NEGINIT_MAXLEN_REQFLAGS &&
- pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[0] == SPNEGO_NEGINIT_REQFLAGS_BITDIFF &&
- IsValidContextFlags( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1] ) ) {
- *pucContextFlags = pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1];
- nReturn = SPNEGO_E_SUCCESS;
- } else {
- nReturn = SPNEGO_E_INVALID_ELEMENT;
- }
-
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetContextFlags returned %d\n",nReturn));
+ if (IsValidSpnegoToken(pSpnegoToken) &&
+ NULL != pucContextFlags &&
+ SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+
+ // Check if ContextFlags is available
+ if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
+ iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
+ // The length should be two, the value should show a 1 bit difference in the difference byte, and
+ // the value must be valid
+ if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
+ nDatalength == SPNEGO_NEGINIT_MAXLEN_REQFLAGS
+ && pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
+ pbData[0] == SPNEGO_NEGINIT_REQFLAGS_BITDIFF
+ && IsValidContextFlags(pSpnegoToken->
+ aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1])) {
+ *pucContextFlags =
+ pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
+ pbData[1];
+ nReturn = SPNEGO_E_SUCCESS;
+ } else {
+ nReturn = SPNEGO_E_INVALID_ELEMENT;
+ }
+
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
+
+ } // IF parameters OK
+
+ LOG(("spnegoGetContextFlags returned %d\n", nReturn));
return nReturn;;
}
@@ -515,34 +525,39 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoGetNegotiationResult( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_NEGRESULT* pnegResult )
+int
+spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ SPNEGO_NEGRESULT * pnegResult)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
- if ( IsValidSpnegoToken( pSpnegoToken ) &&
- NULL != pnegResult &&
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) {
-
- // Check if NegResult is available
- if ( pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].iElementPresent
- == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) {
- // Must be 1 byte long and a valid value
- if ( pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].nDatalength == SPNEGO_NEGTARG_MAXLEN_NEGRESULT &&
- IsValidNegResult( *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData ) ) {
- *pnegResult = *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData;
- nReturn = SPNEGO_E_SUCCESS;
- } else {
- nReturn = SPNEGO_E_INVALID_ELEMENT;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetNegotiationResult returned %d\n",nReturn));
+ if (IsValidSpnegoToken(pSpnegoToken) &&
+ NULL != pnegResult && SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
+
+ // Check if NegResult is available
+ if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
+ iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
+ // Must be 1 byte long and a valid value
+ if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
+ nDatalength == SPNEGO_NEGTARG_MAXLEN_NEGRESULT
+ && IsValidNegResult(*pSpnegoToken->
+ aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData)) {
+ *pnegResult =
+ *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
+ pbData;
+ nReturn = SPNEGO_E_SUCCESS;
+ } else {
+ nReturn = SPNEGO_E_INVALID_ELEMENT;
+ }
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
+
+ } // IF parameters OK
+
+ LOG(("spnegoGetNegotiationResult returned %d\n", nReturn));
return nReturn;;
}
@@ -568,45 +583,48 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoGetSupportedMechType( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID* pMechOID )
+int
+spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ SPNEGO_MECH_OID * pMechOID)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- int nCtr = 0L;
- long nLength = 0L;
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ int nCtr = 0L;
+ long nLength = 0L;
+ SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
- if ( IsValidSpnegoToken( pSpnegoToken ) &&
- NULL != pMechOID &&
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) {
-
- // Check if MechList is available
- if ( pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].iElementPresent
- == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) {
-
- for ( nCtr = 0;
- nReturn != SPNEGO_E_SUCCESS &&
- g_stcMechOIDList[nCtr].eMechanismOID != spnego_mech_oid_NotUsed;
- nCtr++ ) {
-
- if ( ( nReturn = ASNDerCheckOID(
- pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].pbData,
- nCtr,
- pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].nDatalength,
- &nLength ) ) == SPNEGO_E_SUCCESS ) {
- *pMechOID = nCtr;
- }
-
- } // For enum MechOIDs
-
-
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetSupportedMechType returned %d\n",nReturn));
+ if (IsValidSpnegoToken(pSpnegoToken) &&
+ NULL != pMechOID && SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
+
+ // Check if MechList is available
+ if (pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].
+ iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
+
+ for (nCtr = 0;
+ nReturn != SPNEGO_E_SUCCESS &&
+ g_stcMechOIDList[nCtr].eMechanismOID != spnego_mech_oid_NotUsed;
+ nCtr++) {
+
+ if ((nReturn =
+ ASNDerCheckOID(pSpnegoToken->
+ aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].pbData,
+ nCtr,
+ pSpnegoToken->
+ aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].
+ nDatalength, &nLength)) == SPNEGO_E_SUCCESS) {
+ *pMechOID = nCtr;
+ }
+
+ } // For enum MechOIDs
+
+
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
+
+ } // IF parameters OK
+
+ LOG(("spnegoGetSupportedMechType returned %d\n", nReturn));
return nReturn;;
}
@@ -637,43 +655,47 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoGetMechToken( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData, unsigned long* pulDataLen )
+int
+spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char *pbTokenData,
+ unsigned long *pulDataLen)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken;
- SPNEGO_ELEMENT* pSpnegoElement = NULL;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
+ SPNEGO_ELEMENT *pSpnegoElement = NULL;
// Check parameters
- if ( IsValidSpnegoToken( pSpnegoToken ) &&
- NULL != pulDataLen ) {
-
- // Point at the proper Element
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) {
- pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTOKEN_ELEMENT];
- } else {
- pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_TARG_RESPTOKEN_ELEMENT];
- }
-
- // Check if MechType is available
- if ( SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent ) {
- // Check for Buffer too small conditions
- if ( NULL == pbTokenData ||
- pSpnegoElement->nDatalength > *pulDataLen ) {
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- // Copy Memory
- memcpy( pbTokenData, pSpnegoElement->pbData, pSpnegoElement->nDatalength );
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_SUCCESS;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetMechToken returned %d\n",nReturn));
+ if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
+
+ // Point at the proper Element
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+ pSpnegoElement =
+ &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTOKEN_ELEMENT];
+ } else {
+ pSpnegoElement =
+ &pSpnegoToken->aElementArray[SPNEGO_TARG_RESPTOKEN_ELEMENT];
+ }
+
+ // Check if MechType is available
+ if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent) {
+ // Check for Buffer too small conditions
+ if (NULL == pbTokenData ||
+ pSpnegoElement->nDatalength > *pulDataLen) {
+ *pulDataLen = pSpnegoElement->nDatalength;
+ nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
+ } else {
+ // Copy Memory
+ memcpy(pbTokenData, pSpnegoElement->pbData,
+ pSpnegoElement->nDatalength);
+ *pulDataLen = pSpnegoElement->nDatalength;
+ nReturn = SPNEGO_E_SUCCESS;
+ }
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
+
+ } // IF parameters OK
+
+ LOG(("spnegoGetMechToken returned %d\n", nReturn));
return nReturn;;
}
@@ -702,43 +724,45 @@
//
////////////////////////////////////////////////////////////////////////////
-int spnegoGetMechListMIC( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbMICData, unsigned long* pulDataLen )
+int
+spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char *pbMICData,
+ unsigned long *pulDataLen)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken;
- SPNEGO_ELEMENT* pSpnegoElement = NULL;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
+ SPNEGO_ELEMENT *pSpnegoElement = NULL;
// Check parameters
- if ( IsValidSpnegoToken( pSpnegoToken ) &&
- NULL != pulDataLen ) {
-
- // Point at the proper Element
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) {
- pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHLISTMIC_ELEMENT];
- } else {
- pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_TARG_MECHLISTMIC_ELEMENT];
- }
-
- // Check if MechType is available
- if ( SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent ) {
- // Check for Buffer too small conditions
- if ( NULL == pbMICData ||
- pSpnegoElement->nDatalength > *pulDataLen ) {
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- // Copy Memory
- memcpy( pbMICData, pSpnegoElement->pbData, pSpnegoElement->nDatalength );
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_SUCCESS;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetMechListMIC returned %d\n",nReturn));
+ if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
+
+ // Point at the proper Element
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+ pSpnegoElement =
+ &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHLISTMIC_ELEMENT];
+ } else {
+ pSpnegoElement =
+ &pSpnegoToken->aElementArray[SPNEGO_TARG_MECHLISTMIC_ELEMENT];
+ }
+
+ // Check if MechType is available
+ if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent) {
+ // Check for Buffer too small conditions
+ if (NULL == pbMICData || pSpnegoElement->nDatalength > *pulDataLen) {
+ *pulDataLen = pSpnegoElement->nDatalength;
+ nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
+ } else {
+ // Copy Memory
+ memcpy(pbMICData, pSpnegoElement->pbData,
+ pSpnegoElement->nDatalength);
+ *pulDataLen = pSpnegoElement->nDatalength;
+ nReturn = SPNEGO_E_SUCCESS;
+ }
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
+
+ } // IF parameters OK
+
+ LOG(("spnegoGetMechListMIC returned %d\n", nReturn));
return nReturn;;
}
-
=== modified file 'helpers/negotiate_auth/kerberos/spnegohelp/spnego.h'
--- helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.h 2009-08-23 09:30:49 +0000
+++ helpers/negotiate_auth/kerberos/spnegohelp/spnego.h 2009-09-04 12:59:38 +0000
@@ -27,7 +27,8 @@
// C++ Specific
#if defined(__cplusplus)
-extern "C" {
+extern "C"
+{
#endif
// Type Definitions
@@ -36,30 +37,30 @@
// Users of SPNEGO Token Handler API will request
// these as well as free them,
//
- typedef void* SPNEGO_TOKEN_HANDLE;
+ typedef void *SPNEGO_TOKEN_HANDLE;
//
// Defines the element types that are found
// in each of the tokens.
//
- typedef enum spnego_element_type {
- spnego_element_min, // Lower bound
-
- // Init token elements
- spnego_init_mechtypes,
- spnego_init_reqFlags,
- spnego_init_mechToken,
- spnego_init_mechListMIC,
-
- // Targ token elements
- spnego_targ_negResult,
- spnego_targ_supportedMech,
- spnego_targ_responseToken,
- spnego_targ_mechListMIC,
-
- spnego_element_max // Upper bound
-
+ typedef enum spnego_element_type
+ {
+ spnego_element_min, // Lower bound
+
+ // Init token elements
+ spnego_init_mechtypes,
+ spnego_init_reqFlags,
+ spnego_init_mechToken,
+ spnego_init_mechListMIC,
+
+ // Targ token elements
+ spnego_targ_negResult,
+ spnego_targ_supportedMech,
+ spnego_targ_responseToken,
+ spnego_targ_mechListMIC,
+
+ spnego_element_max // Upper bound
} SPNEGO_ELEMENT_TYPE;
//
@@ -87,24 +88,25 @@
// defined in the parsing code.
//
- typedef enum spnego_mech_oid {
- // Init token elements
- spnego_mech_oid_Kerberos_V5_Legacy, // Really V5, but OID off by 1 bit
- spnego_mech_oid_Kerberos_V5,
- spnego_mech_oid_Spnego,
- spnego_mech_oid_NotUsed = -1
-
+ typedef enum spnego_mech_oid
+ {
+ // Init token elements
+ spnego_mech_oid_Kerberos_V5_Legacy, // Really V5, but OID off by 1 bit
+ spnego_mech_oid_Kerberos_V5,
+ spnego_mech_oid_Spnego,
+ spnego_mech_oid_NotUsed = -1
} SPNEGO_MECH_OID;
//
// Defines the negResult values.
//
- typedef enum spnego_negResult {
- spnego_negresult_success,
- spnego_negresult_incomplete,
- spnego_negresult_rejected,
- spnego_negresult_NotUsed = -1
+ typedef enum spnego_negResult
+ {
+ spnego_negresult_success,
+ spnego_negresult_incomplete,
+ spnego_negresult_rejected,
+ spnego_negresult_NotUsed = -1
} SPNEGO_NEGRESULT;
//
@@ -128,7 +130,7 @@
// Mask to retrieve valid values.
//
-#define SPNEGO_NEGINIT_CONTEXT_MASK 0xFE // Logical combination of above flags
+#define SPNEGO_NEGINIT_CONTEXT_MASK 0xFE // Logical combination of above flags
//
// SPNEGO API return codes.
@@ -176,58 +178,65 @@
// A Token Element was invalid (e.g. improper length or value)
#define SPNEGO_E_INVALID_ELEMENT -13
- /* Miscelaneous API Functions */
+/* Miscelaneous API Functions */
// Frees opaque data
- void spnegoFreeData( SPNEGO_TOKEN_HANDLE hSpnegoToken );
+ void spnegoFreeData(SPNEGO_TOKEN_HANDLE hSpnegoToken);
// Initializes SPNEGO_TOKEN structure from DER encoded binary data
- int spnegoInitFromBinary( unsigned char* pbTokenData, unsigned long ulLength, SPNEGO_TOKEN_HANDLE* phSpnegoToken );
+ int spnegoInitFromBinary(unsigned char *pbTokenData, unsigned long ulLength,
+ SPNEGO_TOKEN_HANDLE * phSpnegoToken);
// Initializes SPNEGO_TOKEN structure for a NegTokenInit type using the
// supplied parameters
- int spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechTokenMIC,
- unsigned long ulMechTokenMIC, SPNEGO_TOKEN_HANDLE* phSpnegoToken );
+ int spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,
+ unsigned char ucContextFlags, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechTokenMIC,
+ unsigned long ulMechTokenMIC, SPNEGO_TOKEN_HANDLE * phSpnegoToken);
// Initializes SPNEGO_TOKEN structure for a NegTokenTarg type using the
// supplied parameters
- int spnegoCreateNegTokenTarg( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken );
+ int spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,
+ SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken);
// Copies binary representation of SPNEGO Data into user supplied buffer
- int spnegoTokenGetBinary( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData,
- unsigned long * pulDataLen );
+ int spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ unsigned char *pbTokenData, unsigned long *pulDataLen);
// Returns SPNEGO Token Type
- int spnegoGetTokenType( SPNEGO_TOKEN_HANDLE hSpnegoToken, int * piTokenType );
+ int spnegoGetTokenType(SPNEGO_TOKEN_HANDLE hSpnegoToken, int *piTokenType);
- /* Reading an Init Token */
+/* Reading an Init Token */
// Returns the Initial Mech Type in the MechList element in the NegInitToken.
- int spnegoIsMechTypeAvailable( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID MechOID, int * piMechTypeIndex );
+ int spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
// Returns the value from the context flags element in the NegInitToken as an unsigned long
- int spnegoGetContextFlags( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pucContextFlags );
+ int spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ unsigned char *pucContextFlags);
- /* Reading a Response Token */
+/* Reading a Response Token */
// Returns the value from the negResult element (Status code of GSS call - 0,1,2)
- int spnegoGetNegotiationResult( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_NEGRESULT* pnegResult );
+ int spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ SPNEGO_NEGRESULT * pnegResult);
// Returns the Supported Mech Type from the NegTokenTarg.
- int spnegoGetSupportedMechType( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID* pMechOID );
+ int spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ SPNEGO_MECH_OID * pMechOID);
- /* Reading either Token Type */
+/* Reading either Token Type */
// Returns the actual Mechanism data from the token (this is what is passed into GSS-API functions
- int spnegoGetMechToken( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData, unsigned long* pulDataLen );
+ int spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ unsigned char *pbTokenData, unsigned long *pulDataLen);
// Returns the Message Integrity BLOB in the token
- int spnegoGetMechListMIC( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbMICData, unsigned long* pulDataLen );
+ int spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken,
+ unsigned char *pbMICData, unsigned long *pulDataLen);
// C++ Specific
#if defined(__cplusplus)
=== renamed file 'helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c' => 'helpers/negotiate_auth/kerberos/spnegohelp/spnegohelp.cc'
--- helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c 2008-10-10 08:02:53 +0000
+++ helpers/negotiate_auth/kerberos/spnegohelp/spnegohelp.cc 2009-09-11 07:19:29 +0000
@@ -1,248 +1,231 @@
-/* -----------------------------------------------------------------------------
- * spnegohelp.c defines RFC 2478 SPNEGO GSS-API mechanism APIs.
- *
- * Author: Frank Balluffi
- *
- * Copyright (C) 2002-2003 All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- * -----------------------------------------------------------------------------
- */
-
-#include "spnegohelp.h"
-#include "spnego.h"
-
-#include <stdlib.h>
-
-int makeNegTokenTarg (const unsigned char * kerberosToken,
- size_t kerberosTokenLength,
- const unsigned char ** negTokenTarg,
- size_t * negTokenTargLength)
-{
- SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
- int rc1 = 1;
- int rc2 = SPNEGO_E_SUCCESS;
-
- /* Check arguments. */
-
- if (!kerberosToken ||
- !negTokenTarg ||
- !negTokenTargLength)
- return 10;
-
- /* Does IIS reply with 1.2.840.48018.1.2.2 or 1.2.840.113554.1.2.2? */
-
- /* Does IIS always reply with accept_completed? */
-
- /* IIS does not include a MIC. */
-
- rc2 = spnegoCreateNegTokenTarg (spnego_mech_oid_Kerberos_V5_Legacy,
- spnego_negresult_success,
- (unsigned char *) kerberosToken,
- kerberosTokenLength,
- NULL,
- 0,
- &hSpnegoToken);
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2)+100;
- goto cleanup;
- }
-
- /* Get NegTokenTarg length. */
-
- rc2 = spnegoTokenGetBinary (hSpnegoToken,
- NULL,
- (unsigned long*) negTokenTargLength);
-
- if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL) {
- rc1 = abs(rc2)+200;
- goto cleanup;
- }
-
- *negTokenTarg = malloc (*negTokenTargLength);
-
- if (!*negTokenTarg) {
- rc1 = abs(rc2)+300;
- goto cleanup;
- }
-
- /* Get NegTokenTarg data. */
-
- rc2 = spnegoTokenGetBinary (hSpnegoToken,
- (unsigned char *) *negTokenTarg,
- (unsigned long*) negTokenTargLength);
-
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2)+400;
- goto error;
- }
-
- rc1 = 0;
-
- goto cleanup;
-
-error:
-
- if (*negTokenTarg) {
- free ((unsigned char *) *negTokenTarg);
- *negTokenTarg = NULL;
- *negTokenTargLength = 0;
- }
-
-cleanup:
-
- if (hSpnegoToken)
- spnegoFreeData (hSpnegoToken);
-
- LOG(("makeNegTokenTarg returned %d\n",rc1));
- return rc1;
-}
-
-int parseNegTokenInit (const unsigned char * negTokenInit,
- size_t negTokenInitLength,
- const unsigned char ** kerberosToken,
- size_t * kerberosTokenLength)
-{
- SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
- int pindex = -1;
- int rc1 = 1;
- int rc2 = SPNEGO_E_SUCCESS;
- unsigned char reqFlags = 0;
- int tokenType = 0;
-
- /* Check arguments. */
-
- if (!negTokenInit ||
- !kerberosToken ||
- !kerberosTokenLength)
- return 10;
-
- /* Decode SPNEGO token. */
-
- rc2 = spnegoInitFromBinary ((unsigned char *) negTokenInit,
- negTokenInitLength,
- &hSpnegoToken);
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2)+100;
- goto cleanup;
- }
-
- /* Check for negTokenInit choice. */
-
- rc2 = spnegoGetTokenType (hSpnegoToken,
- &tokenType);
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2)+200;
- goto cleanup;
- }
-
- if (tokenType != SPNEGO_TOKEN_INIT) {
- rc1 = abs(rc2)+300;
- goto cleanup;
- }
-
- /*
- Check that first mechType is 1.2.840.113554.1.2.2 or 1.2.840.48018.1.2.2.
- */
-
- /*
- IE seems to reply with 1.2.840.48018.1.2.2 and then 1.2.840.113554.1.2.2.
- */
-
- rc2 = spnegoIsMechTypeAvailable (hSpnegoToken,
- spnego_mech_oid_Kerberos_V5_Legacy,
- &pindex);
-
- if (rc2 != SPNEGO_E_SUCCESS ||
- pindex != 0) {
- rc2 = spnegoIsMechTypeAvailable (hSpnegoToken,
- spnego_mech_oid_Kerberos_V5,
- &pindex);
-
- if (rc2 != SPNEGO_E_SUCCESS ||
- pindex != 0) {
- rc1 = abs(rc2)+400;
- goto cleanup;
- }
- }
-
- /* Check for no reqFlags. */
-
- /* Does IE ever send reqFlags? */
-
- rc2 = spnegoGetContextFlags (hSpnegoToken,
- &reqFlags);
-
- if (rc2 == SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2)+500;
- goto cleanup;
- }
-
- /* Get mechanism token length. */
-
- rc2 = spnegoGetMechToken (hSpnegoToken,
- NULL,
- (unsigned long*) kerberosTokenLength);
-
- if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL) {
- rc1 = abs(rc2)+600;
- goto cleanup;
- }
-
- *kerberosToken = malloc (*kerberosTokenLength);
-
- if (!*kerberosToken) {
- rc1 = abs(rc2)+700;
- goto cleanup;
- }
-
- /* Get mechanism token data. */
-
- rc2 = spnegoGetMechToken (hSpnegoToken,
- (unsigned char *) *kerberosToken,
- (unsigned long*) kerberosTokenLength);
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2)+800;
- goto error;
- }
-
- /* According to Microsoft, IE does not send a MIC. */
-
- rc1 = 0;
-
- goto cleanup;
-
-error:
-
- if (*kerberosToken) {
- free ((unsigned char *) *kerberosToken);
- *kerberosToken = NULL;
- *kerberosTokenLength = 0;
- }
-
-cleanup:
-
- if (hSpnegoToken)
- spnegoFreeData (hSpnegoToken);
-
- LOG(("parseNegTokenInit returned %d\n",rc1));
- return rc1;
-}
+/* -----------------------------------------------------------------------------
+ * spnegohelp.c defines RFC 2478 SPNEGO GSS-API mechanism APIs.
+ *
+ * Author: Frank Balluffi
+ *
+ * Copyright (C) 2002-2003 All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "spnegohelp.h"
+#include "spnego.h"
+
+#include <stdlib.h>
+
+int
+makeNegTokenTarg(const unsigned char *kerberosToken,
+ size_t kerberosTokenLength,
+ const unsigned char **negTokenTarg, size_t * negTokenTargLength)
+{
+ SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
+ int rc1 = 1;
+ int rc2 = SPNEGO_E_SUCCESS;
+
+ /* Check arguments. */
+
+ if (!kerberosToken || !negTokenTarg || !negTokenTargLength)
+ return 10;
+
+ /* Does IIS reply with 1.2.840.48018.1.2.2 or 1.2.840.113554.1.2.2? */
+
+ /* Does IIS always reply with accept_completed? */
+
+ /* IIS does not include a MIC. */
+
+ rc2 = spnegoCreateNegTokenTarg(spnego_mech_oid_Kerberos_V5_Legacy,
+ spnego_negresult_success,
+ (unsigned char *) kerberosToken,
+ kerberosTokenLength, NULL, 0, &hSpnegoToken);
+
+ if (rc2 != SPNEGO_E_SUCCESS) {
+ rc1 = abs(rc2) + 100;
+ goto cleanup;
+ }
+
+ /* Get NegTokenTarg length. */
+
+ rc2 = spnegoTokenGetBinary(hSpnegoToken,
+ NULL, (unsigned long *) negTokenTargLength);
+
+ if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL) {
+ rc1 = abs(rc2) + 200;
+ goto cleanup;
+ }
+
+ *negTokenTarg = malloc(*negTokenTargLength);
+
+ if (!*negTokenTarg) {
+ rc1 = abs(rc2) + 300;
+ goto cleanup;
+ }
+
+ /* Get NegTokenTarg data. */
+
+ rc2 = spnegoTokenGetBinary(hSpnegoToken,
+ (unsigned char *) *negTokenTarg, (unsigned long *) negTokenTargLength);
+
+
+ if (rc2 != SPNEGO_E_SUCCESS) {
+ rc1 = abs(rc2) + 400;
+ goto error;
+ }
+
+ rc1 = 0;
+
+ goto cleanup;
+
+ error:
+
+ if (*negTokenTarg) {
+ free((unsigned char *) *negTokenTarg);
+ *negTokenTarg = NULL;
+ *negTokenTargLength = 0;
+ }
+
+ cleanup:
+
+ if (hSpnegoToken)
+ spnegoFreeData(hSpnegoToken);
+
+ LOG(("makeNegTokenTarg returned %d\n", rc1));
+ return rc1;
+}
+
+int
+parseNegTokenInit(const unsigned char *negTokenInit,
+ size_t negTokenInitLength,
+ const unsigned char **kerberosToken, size_t * kerberosTokenLength)
+{
+ SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
+ int pindex = -1;
+ int rc1 = 1;
+ int rc2 = SPNEGO_E_SUCCESS;
+ unsigned char reqFlags = 0;
+ int tokenType = 0;
+
+ /* Check arguments. */
+
+ if (!negTokenInit || !kerberosToken || !kerberosTokenLength)
+ return 10;
+
+ /* Decode SPNEGO token. */
+
+ rc2 = spnegoInitFromBinary((unsigned char *) negTokenInit,
+ negTokenInitLength, &hSpnegoToken);
+
+ if (rc2 != SPNEGO_E_SUCCESS) {
+ rc1 = abs(rc2) + 100;
+ goto cleanup;
+ }
+
+ /* Check for negTokenInit choice. */
+
+ rc2 = spnegoGetTokenType(hSpnegoToken, &tokenType);
+
+ if (rc2 != SPNEGO_E_SUCCESS) {
+ rc1 = abs(rc2) + 200;
+ goto cleanup;
+ }
+
+ if (tokenType != SPNEGO_TOKEN_INIT) {
+ rc1 = abs(rc2) + 300;
+ goto cleanup;
+ }
+
+ /*
+ * Check that first mechType is 1.2.840.113554.1.2.2 or 1.2.840.48018.1.2.2.
+ */
+
+ /*
+ * IE seems to reply with 1.2.840.48018.1.2.2 and then 1.2.840.113554.1.2.2.
+ */
+
+ rc2 = spnegoIsMechTypeAvailable(hSpnegoToken,
+ spnego_mech_oid_Kerberos_V5_Legacy, &pindex);
+
+ if (rc2 != SPNEGO_E_SUCCESS || pindex != 0) {
+ rc2 = spnegoIsMechTypeAvailable(hSpnegoToken,
+ spnego_mech_oid_Kerberos_V5, &pindex);
+
+ if (rc2 != SPNEGO_E_SUCCESS || pindex != 0) {
+ rc1 = abs(rc2) + 400;
+ goto cleanup;
+ }
+ }
+
+ /* Check for no reqFlags. */
+
+ /* Does IE ever send reqFlags? */
+
+ rc2 = spnegoGetContextFlags(hSpnegoToken, &reqFlags);
+
+ if (rc2 == SPNEGO_E_SUCCESS) {
+ rc1 = abs(rc2) + 500;
+ goto cleanup;
+ }
+
+ /* Get mechanism token length. */
+
+ rc2 = spnegoGetMechToken(hSpnegoToken,
+ NULL, (unsigned long *) kerberosTokenLength);
+
+ if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL) {
+ rc1 = abs(rc2) + 600;
+ goto cleanup;
+ }
+
+ *kerberosToken = malloc(*kerberosTokenLength);
+
+ if (!*kerberosToken) {
+ rc1 = abs(rc2) + 700;
+ goto cleanup;
+ }
+
+ /* Get mechanism token data. */
+
+ rc2 = spnegoGetMechToken(hSpnegoToken,
+ (unsigned char *) *kerberosToken,
+ (unsigned long *) kerberosTokenLength);
+
+ if (rc2 != SPNEGO_E_SUCCESS) {
+ rc1 = abs(rc2) + 800;
+ goto error;
+ }
+
+ /* According to Microsoft, IE does not send a MIC. */
+
+ rc1 = 0;
+
+ goto cleanup;
+
+ error:
+
+ if (*kerberosToken) {
+ free((unsigned char *) *kerberosToken);
+ *kerberosToken = NULL;
+ *kerberosTokenLength = 0;
+ }
+
+ cleanup:
+
+ if (hSpnegoToken)
+ spnegoFreeData(hSpnegoToken);
+
+ LOG(("parseNegTokenInit returned %d\n", rc1));
+ return rc1;
+}
=== modified file 'helpers/negotiate_auth/kerberos/spnegohelp/spnegohelp.h'
--- helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h 2009-08-23 09:30:49 +0000
+++ helpers/negotiate_auth/kerberos/spnegohelp/spnegohelp.h 2009-09-04 12:59:38 +0000
@@ -11,48 +11,47 @@
#define SPNEGOHELP_H
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
#include <stddef.h>
- /* -----------------------------------------------------------------------------
- * makeNegTokenTarg makes an RFC 2478 SPNEGO NegTokenTarg (token) from an
- * RFC 1964 Kerberos GSS-API token.
- *
- * If makeNegTokenTarg is successful, call free (*negTokenTarg) to free the
- * memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
-
- int makeNegTokenTarg (const unsigned char * kerberosToken,
- size_t kerberosTokenLength,
- const unsigned char ** negTokenTarg,
- size_t * negTokenTargLength);
-
- /* -----------------------------------------------------------------------------
- * parseNegTokenInit parses an RFC 2478 SPNEGO NegTokenInit (token) to extract
- * an RFC 1964 Kerberos GSS-API token.
- *
- * If the NegTokenInit does cotain a Kerberos GSS-API token, parseNegTokenInit
- * returns an error.
- *
- * If parseNegTokenInit is successful, call free (*kerberosToken) to
- * free the memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
-
- int parseNegTokenInit (const unsigned char * negTokenInit,
- size_t negTokenInitLength,
- const unsigned char ** kerberosToken,
- size_t * kerberosTokenLength);
+/* -----------------------------------------------------------------------------
+ * makeNegTokenTarg makes an RFC 2478 SPNEGO NegTokenTarg (token) from an
+ * RFC 1964 Kerberos GSS-API token.
+ *
+ * If makeNegTokenTarg is successful, call free (*negTokenTarg) to free the
+ * memory allocated by parseNegTokenInit.
+ *
+ * Returns 0 if successful, 1 otherwise.
+ * -----------------------------------------------------------------------------
+ */
+
+ int makeNegTokenTarg(const unsigned char *kerberosToken,
+ size_t kerberosTokenLength,
+ const unsigned char **negTokenTarg, size_t * negTokenTargLength);
+
+/* -----------------------------------------------------------------------------
+ * parseNegTokenInit parses an RFC 2478 SPNEGO NegTokenInit (token) to extract
+ * an RFC 1964 Kerberos GSS-API token.
+ *
+ * If the NegTokenInit does cotain a Kerberos GSS-API token, parseNegTokenInit
+ * returns an error.
+ *
+ * If parseNegTokenInit is successful, call free (*kerberosToken) to
+ * free the memory allocated by parseNegTokenInit.
+ *
+ * Returns 0 if successful, 1 otherwise.
+ * -----------------------------------------------------------------------------
+ */
+
+ int parseNegTokenInit(const unsigned char *negTokenInit,
+ size_t negTokenInitLength,
+ const unsigned char **kerberosToken, size_t * kerberosTokenLength);
#ifdef __cplusplus
}
#endif
-#endif /* SPNEGOHELP_H */
+#endif /* SPNEGOHELP_H */
=== renamed file 'helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.c' => 'helpers/negotiate_auth/kerberos/spnegohelp/spnegoparse.cc'
--- helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.c 2008-10-10 08:02:53 +0000
+++ helpers/negotiate_auth/kerberos/spnegohelp/spnegoparse.cc 2009-09-11 07:19:29 +0000
@@ -31,7 +31,7 @@
// Defined in DERPARSE.C
//
-extern MECH_OID g_stcMechOIDList [];
+extern MECH_OID g_stcMechOIDList[];
/**********************************************************************/
/** **/
@@ -74,61 +74,59 @@
//
////////////////////////////////////////////////////////////////////////////
-int CalculateMinSpnegoInitTokenSize( long nMechTokenLength,
- long nMechListMICLength, SPNEGO_MECH_OID mechOid,
- int nReqFlagsAvailable, long* pnTokenSize,
- long* pnInternalTokenLength )
+int
+CalculateMinSpnegoInitTokenSize(long nMechTokenLength,
+ long nMechListMICLength, SPNEGO_MECH_OID mechOid,
+ int nReqFlagsAvailable, long *pnTokenSize, long *pnInternalTokenLength)
{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
+ int nReturn = SPNEGO_E_INVALID_LENGTH;
// Start at 0.
- long nTotalLength = 0;
- long nTempLength= 0L;
+ long nTotalLength = 0;
+ long nTempLength = 0L;
// We will calculate this by walking the token backwards
// Start with MIC Element
- if ( nMechListMICLength > 0L ) {
- nTempLength = ASNDerCalcElementLength( nMechListMICLength, NULL );
-
- // Check for rollover error
- if ( nTempLength < nMechListMICLength ) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength += nTempLength;
+ if (nMechListMICLength > 0L) {
+ nTempLength = ASNDerCalcElementLength(nMechListMICLength, NULL);
+
+ // Check for rollover error
+ if (nTempLength < nMechListMICLength) {
+ goto xEndTokenInitLength;
+ }
+
+ nTotalLength += nTempLength;
}
-
// Next is the MechToken
- if ( nMechTokenLength > 0L ) {
- nTempLength += ASNDerCalcElementLength( nMechTokenLength, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
+ if (nMechTokenLength > 0L) {
+ nTempLength += ASNDerCalcElementLength(nMechTokenLength, NULL);
+
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
+ }
+
+ nTotalLength = nTempLength;
}
-
// Next is the ReqFlags
- if ( nReqFlagsAvailable ) {
- nTempLength += ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
+ if (nReqFlagsAvailable) {
+ nTempLength +=
+ ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL);
+
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
+ }
+
+ nTotalLength = nTempLength;
}
-
// Next is the MechList - This is REQUIRED
- nTempLength += ASNDerCalcMechListLength( mechOid, NULL );
+ nTempLength += ASNDerCalcMechListLength(mechOid, NULL);
// Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenInitLength;
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
}
nTotalLength = nTempLength;
@@ -136,21 +134,21 @@
// Following four fields are the basic header tokens
// Sequence Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
+ nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
// Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenInitLength;
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
}
nTotalLength = nTempLength;
// Neg Token Identifier Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
+ nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
// Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenInitLength;
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
}
nTotalLength = nTempLength;
@@ -159,20 +157,19 @@
nTempLength += g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
// Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenInitLength;
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
}
nTotalLength = nTempLength;
// App Constructed Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
+ nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
// Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenInitLength;
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
}
-
// The internal length doesn't include the number of bytes
// for the initial token
*pnInternalTokenLength = nTotalLength;
@@ -182,9 +179,9 @@
*pnTokenSize = nTotalLength;
nReturn = SPNEGO_E_SUCCESS;
-xEndTokenInitLength:
+ xEndTokenInitLength:
- LOG(("CalculateMinSpnegoInitTokenSize returned %d\n",nReturn));
+ LOG(("CalculateMinSpnegoInitTokenSize returned %d\n", nReturn));
return nReturn;
}
@@ -219,172 +216,181 @@
//
////////////////////////////////////////////////////////////////////////////
-int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char* pbTokenData,
- long nTokenLength, long nInternalTokenLength )
+int
+CreateSpnegoInitToken(SPNEGO_MECH_OID MechType,
+ unsigned char ucContextFlags, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, unsigned char *pbTokenData,
+ long nTokenLength, long nInternalTokenLength)
{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
+ int nReturn = SPNEGO_E_INVALID_LENGTH;
// Start at 0.
- long nTempLength= 0L;
- long nTotalBytesWritten = 0L;
- long nInternalLength = 0L;
+ long nTempLength = 0L;
+ long nTotalBytesWritten = 0L;
+ long nInternalLength = 0L;
- unsigned char* pbWriteTokenData = pbTokenData + nTokenLength;
+ unsigned char *pbWriteTokenData = pbTokenData + nTokenLength;
// Temporary buffer to hold the REQ Flags as BIT String Data
- unsigned char abTempReqFlags[SPNEGO_NEGINIT_MAXLEN_REQFLAGS];
+ unsigned char abTempReqFlags[SPNEGO_NEGINIT_MAXLEN_REQFLAGS];
// We will write the token out backwards to properly handle the cases
// where the length bytes become adjustable
// Start with MIC Element
- if ( ulMechListMICLen > 0L ) {
- nTempLength = ASNDerCalcElementLength( ulMechListMICLen, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
-
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC,
- OCTETSTRING, pbMechListMIC, ulMechListMICLen );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF MechListMIC is present
+ if (ulMechListMICLen > 0L) {
+ nTempLength =
+ ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength);
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC,
+ ulMechListMICLen);
+
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
+ }
+
+ } // IF MechListMIC is present
// Next is the MechToken
- if ( ulMechTokenLen > 0L ) {
- nTempLength = ASNDerCalcElementLength( ulMechTokenLen, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHTOKEN,
- OCTETSTRING, pbMechToken, ulMechTokenLen );
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF MechToken Length is present
+ if (ulMechTokenLen > 0L) {
+ nTempLength = ASNDerCalcElementLength(ulMechTokenLen, &nInternalLength);
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, OCTETSTRING, pbMechToken,
+ ulMechTokenLen);
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
+ }
+
+ } // IF MechToken Length is present
// Next is the ReqFlags
- if ( ucContextFlags > 0L ) {
-
- nTempLength = ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, &nInternalLength );
-
- // We need a byte that indicates how many bits difference between the number
- // of bits used in final octet (we only have one) and the max (8)
-
- abTempReqFlags[0] = SPNEGO_NEGINIT_REQFLAGS_BITDIFF;
- abTempReqFlags[1] = ucContextFlags;
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
- BITSTRING, abTempReqFlags, SPNEGO_NEGINIT_MAXLEN_REQFLAGS );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF ContextFlags
+ if (ucContextFlags > 0L) {
+
+ nTempLength =
+ ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS,
+ &nInternalLength);
+
+ // We need a byte that indicates how many bits difference between the number
+ // of bits used in final octet (we only have one) and the max (8)
+
+ abTempReqFlags[0] = SPNEGO_NEGINIT_REQFLAGS_BITDIFF;
+ abTempReqFlags[1] = ucContextFlags;
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGINIT_ELEMENT_REQFLAGS, BITSTRING, abTempReqFlags,
+ SPNEGO_NEGINIT_MAXLEN_REQFLAGS);
+
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
+ }
+
+ } // IF ContextFlags
// Next is the MechList - This is REQUIRED
- nTempLength = ASNDerCalcMechListLength( MechType, &nInternalLength );
+ nTempLength = ASNDerCalcMechListLength(MechType, &nInternalLength);
// Decrease the pbWriteTokenData, now we know the length and
// write it out.
pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteMechList( pbWriteTokenData, MechType );
+ nTempLength = ASNDerWriteMechList(pbWriteTokenData, MechType);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
nInternalTokenLength -= nTempLength;
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenInit;
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
}
-
// The next tokens we're writing out reflect the total number of bytes
// we have actually written out.
// Sequence Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
+ nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
// Decrease the pbWriteTokenData, now we know the length and
// write it out.
pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- NULL, nTotalBytesWritten );
+ nTempLength =
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL,
+ nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
nInternalTokenLength -= nTempLength;
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenInit;
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
}
-
// Neg Init Token Identifier Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
+ nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
// Decrease the pbWriteTokenData, now we know the length and
// write it out.
pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
- NULL, nTotalBytesWritten );
+ nTempLength =
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
+ NULL, nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
nInternalTokenLength -= nTempLength;
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenInit;
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
}
-
// SPNEGO OID Token
nTempLength = g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
// Decrease the pbWriteTokenData, now we know the length and
// write it out.
pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteOID( pbWriteTokenData, spnego_mech_oid_Spnego );
+ nTempLength = ASNDerWriteOID(pbWriteTokenData, spnego_mech_oid_Spnego);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
nInternalTokenLength -= nTempLength;
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenInit;
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
}
-
// App Constructed Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
+ nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
// Decrease the pbWriteTokenData, now we know the length and
// write it out.
pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT,
- NULL, nTotalBytesWritten );
+ nTempLength =
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, NULL,
+ nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
@@ -395,14 +401,14 @@
// to see the total number of bytes written out as well as the
// number of bytes left to write).
- if ( nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
- pbWriteTokenData == pbTokenData ) {
- nReturn = SPNEGO_E_SUCCESS;
+ if (nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
+ pbWriteTokenData == pbTokenData) {
+ nReturn = SPNEGO_E_SUCCESS;
}
-xEndWriteNegTokenInit:
+ xEndWriteNegTokenInit:
- LOG(("CreateSpnegoInitToken returned %d\n",nReturn));
+ LOG(("CreateSpnegoInitToken returned %d\n", nReturn));
return nReturn;
}
@@ -435,92 +441,91 @@
//
////////////////////////////////////////////////////////////////////////////
-int CalculateMinSpnegoTargTokenSize( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
- long nMechListMICLen, long* pnTokenSize,
- long* pnInternalTokenLength )
+int
+CalculateMinSpnegoTargTokenSize(SPNEGO_MECH_OID MechType,
+ SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
+ long nMechListMICLen, long *pnTokenSize, long *pnInternalTokenLength)
{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
+ int nReturn = SPNEGO_E_INVALID_LENGTH;
// Start at 0.
- long nTotalLength = 0;
- long nTempLength= 0L;
+ long nTotalLength = 0;
+ long nTempLength = 0L;
// We will calculate this by walking the token backwards
// Start with MIC Element
- if ( nMechListMICLen > 0L ) {
- nTempLength = ASNDerCalcElementLength( nMechListMICLen, NULL );
-
- // Check for rollover error
- if ( nTempLength < nMechListMICLen ) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength += nTempLength;
+ if (nMechListMICLen > 0L) {
+ nTempLength = ASNDerCalcElementLength(nMechListMICLen, NULL);
+
+ // Check for rollover error
+ if (nTempLength < nMechListMICLen) {
+ goto xEndTokenTargLength;
+ }
+
+ nTotalLength += nTempLength;
}
-
// Next is the MechToken
- if ( nMechTokenLen > 0L ) {
- nTempLength += ASNDerCalcElementLength( nMechTokenLen, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
+ if (nMechTokenLen > 0L) {
+ nTempLength += ASNDerCalcElementLength(nMechTokenLen, NULL);
+
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenTargLength;
+ }
+
+ nTotalLength = nTempLength;
}
-
// Supported MechType
- if ( spnego_mech_oid_NotUsed != MechType ) {
- // Supported MechOID element - we use the token function since
- // we already know the size of the OID token and value
- nTempLength += ASNDerCalcElementLength( g_stcMechOIDList[MechType].iActualDataLen,
- NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
-
- } // IF MechType is available
+ if (spnego_mech_oid_NotUsed != MechType) {
+ // Supported MechOID element - we use the token function since
+ // we already know the size of the OID token and value
+ nTempLength +=
+ ASNDerCalcElementLength(g_stcMechOIDList[MechType].iActualDataLen,
+ NULL);
+
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenTargLength;
+ }
+
+ nTotalLength = nTempLength;
+
+ } // IF MechType is available
// NegResult Element
- if ( spnego_negresult_NotUsed != spnegoNegResult ) {
- nTempLength += ASNDerCalcElementLength( SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
-
- } // IF negResult is available
+ if (spnego_negresult_NotUsed != spnegoNegResult) {
+ nTempLength +=
+ ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL);
+
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenTargLength;
+ }
+
+ nTotalLength = nTempLength;
+
+ } // IF negResult is available
// Following two fields are the basic header tokens
// Sequence Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
+ nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
// Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenTargLength;
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenTargLength;
}
nTotalLength = nTempLength;
// Neg Token Identifier Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
+ nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
// Check for rollover error
- if ( nTempLength < nTotalLength ) {
- goto xEndTokenTargLength;
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenTargLength;
}
-
// The internal length doesn't include the number of bytes
// for the initial token
*pnInternalTokenLength = nTotalLength;
@@ -530,9 +535,9 @@
*pnTokenSize = nTotalLength;
nReturn = SPNEGO_E_SUCCESS;
-xEndTokenTargLength:
+ xEndTokenTargLength:
- LOG(("CalculateMinSpnegoTargTokenSize returned %d\n",nReturn));
+ LOG(("CalculateMinSpnegoTargTokenSize returned %d\n", nReturn));
return nReturn;
}
@@ -567,142 +572,155 @@
//
////////////////////////////////////////////////////////////////////////////
-int CreateSpnegoTargToken( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT eNegResult, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char* pbTokenData,
- long nTokenLength, long nInternalTokenLength )
+int
+CreateSpnegoTargToken(SPNEGO_MECH_OID MechType,
+ SPNEGO_NEGRESULT eNegResult, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, unsigned char *pbTokenData,
+ long nTokenLength, long nInternalTokenLength)
{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
+ int nReturn = SPNEGO_E_INVALID_LENGTH;
// Start at 0.
- long nTempLength= 0L;
- long nTotalBytesWritten = 0L;
- long nInternalLength = 0L;
+ long nTempLength = 0L;
+ long nTotalBytesWritten = 0L;
+ long nInternalLength = 0L;
- unsigned char ucTemp = 0;
+ unsigned char ucTemp = 0;
// We will write the token out backwards to properly handle the cases
// where the length bytes become adjustable, so the write location
// is initialized to point *just* past the end of the buffer.
- unsigned char* pbWriteTokenData = pbTokenData + nTokenLength;
+ unsigned char *pbWriteTokenData = pbTokenData + nTokenLength;
// Start with MIC Element
- if ( ulMechListMICLen > 0L ) {
- nTempLength = ASNDerCalcElementLength( ulMechListMICLen, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
-
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC,
- OCTETSTRING, pbMechListMIC, ulMechListMICLen );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechListMIC is present
+ if (ulMechListMICLen > 0L) {
+ nTempLength =
+ ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength);
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC,
+ ulMechListMICLen);
+
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
+ }
+
+ } // IF MechListMIC is present
// Next is the MechToken
- if ( ulMechTokenLen > 0L ) {
- nTempLength = ASNDerCalcElementLength( ulMechTokenLen, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN,
- OCTETSTRING, pbMechToken, ulMechTokenLen );
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechToken Length is present
+ if (ulMechTokenLen > 0L) {
+ nTempLength = ASNDerCalcElementLength(ulMechTokenLen, &nInternalLength);
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, OCTETSTRING, pbMechToken,
+ ulMechTokenLen);
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
+ }
+
+ } // IF MechToken Length is present
// Supported Mech Type
- if ( spnego_mech_oid_NotUsed != MechType ) {
-
- nTempLength = ASNDerCalcElementLength( g_stcMechOIDList[MechType].iActualDataLen,
- &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
- g_stcMechOIDList[MechType].ucOid,
- g_stcMechOIDList[MechType].iLen );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechType is present
+ if (spnego_mech_oid_NotUsed != MechType) {
+
+ nTempLength =
+ ASNDerCalcElementLength(g_stcMechOIDList[MechType].iActualDataLen,
+ &nInternalLength);
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteToken(pbWriteTokenData,
+ SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
+ g_stcMechOIDList[MechType].ucOid, g_stcMechOIDList[MechType].iLen);
+
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
+ }
+
+ } // IF MechType is present
// Neg Result
// NegResult Element
- if ( spnego_negresult_NotUsed != eNegResult ) {
- ucTemp = (unsigned char) eNegResult;
-
- nTempLength = ASNDerCalcElementLength( SPNEGO_NEGTARG_MAXLEN_NEGRESULT, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_NEGRESULT,
- ENUMERATED, &ucTemp, SPNEGO_NEGTARG_MAXLEN_NEGRESULT );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenTarg;
- }
-
- } // If eNegResult is available
+ if (spnego_negresult_NotUsed != eNegResult) {
+ ucTemp = (unsigned char) eNegResult;
+
+ nTempLength =
+ ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT,
+ &nInternalLength);
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGTARG_ELEMENT_NEGRESULT, ENUMERATED, &ucTemp,
+ SPNEGO_NEGTARG_MAXLEN_NEGRESULT);
+
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
+ }
+
+ } // If eNegResult is available
// The next tokens we're writing out reflect the total number of bytes
// we have actually written out.
// Sequence Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
+ nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
// Decrease the pbWriteTokenData, now we know the length and
// write it out.
pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- NULL, nTotalBytesWritten );
+ nTempLength =
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL,
+ nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
nInternalTokenLength -= nTempLength;
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) {
- goto xEndWriteNegTokenTarg;
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
}
-
// Neg Targ Token Identifier Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
+ nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
// Decrease the pbWriteTokenData, now we know the length and
// write it out.
pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
- NULL, nTotalBytesWritten );
+ nTempLength =
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
+ NULL, nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
@@ -713,15 +731,15 @@
// to see the total number of bytes written out as well as the
// number of bytes left to write).
- if ( nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
- pbWriteTokenData == pbTokenData ) {
- nReturn = SPNEGO_E_SUCCESS;
+ if (nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
+ pbWriteTokenData == pbTokenData) {
+ nReturn = SPNEGO_E_SUCCESS;
}
-xEndWriteNegTokenTarg:
+ xEndWriteNegTokenTarg:
- LOG(("CreateSpnegoTargToken returned %d\n",nReturn));
+ LOG(("CreateSpnegoTargToken returned %d\n", nReturn));
return nReturn;
@@ -751,51 +769,54 @@
//
////////////////////////////////////////////////////////////////////////////
-SPNEGO_TOKEN* AllocEmptySpnegoToken( unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char * pbTokenData, unsigned long ulTokenSize )
+SPNEGO_TOKEN *
+AllocEmptySpnegoToken(unsigned char ucCopyData, unsigned long ulFlags,
+ unsigned char *pbTokenData, unsigned long ulTokenSize)
{
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) calloc( 1, sizeof(SPNEGO_TOKEN) );
-
- if ( NULL != pSpnegoToken ) {
- // Set the token size
- pSpnegoToken->nStructSize = SPNEGO_TOKEN_SIZE;
-
- // Initialize the element array
- InitSpnegoTokenElementArray( pSpnegoToken );
-
- // Assign the flags value
- pSpnegoToken->ulFlags = ulFlags;
-
- //
- // IF ucCopyData is TRUE, we will allocate a buffer and copy data into it.
- // Otherwise, we will just copy the pointer and the length. This is so we
- // can cut out additional allocations for performance reasons
- //
-
- if ( SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA == ucCopyData ) {
- // Alloc the internal buffer. Cleanup on failure.
- pSpnegoToken->pbBinaryData = (unsigned char*) calloc( ulTokenSize, sizeof(unsigned char) );
-
- if ( NULL != pSpnegoToken->pbBinaryData ) {
- // We must ALWAYS free this buffer
- pSpnegoToken->ulFlags |= SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA;
-
- // Copy the data locally
- memcpy( pSpnegoToken->pbBinaryData, pbTokenData, ulTokenSize );
- pSpnegoToken->ulBinaryDataLen = ulTokenSize;
- } else {
- free( pSpnegoToken );
- pSpnegoToken = NULL;
- }
-
- } // IF ucCopyData
- else {
- // Copy the pointer and the length directly - ulFlags will control whether or not
- // we are allowed to free the value
-
- pSpnegoToken->pbBinaryData = pbTokenData;
- pSpnegoToken->ulBinaryDataLen = ulTokenSize;
- }
+ SPNEGO_TOKEN *pSpnegoToken =
+ (SPNEGO_TOKEN *) calloc(1, sizeof(SPNEGO_TOKEN));
+
+ if (NULL != pSpnegoToken) {
+ // Set the token size
+ pSpnegoToken->nStructSize = SPNEGO_TOKEN_SIZE;
+
+ // Initialize the element array
+ InitSpnegoTokenElementArray(pSpnegoToken);
+
+ // Assign the flags value
+ pSpnegoToken->ulFlags = ulFlags;
+
+ //
+ // IF ucCopyData is TRUE, we will allocate a buffer and copy data into it.
+ // Otherwise, we will just copy the pointer and the length. This is so we
+ // can cut out additional allocations for performance reasons
+ //
+
+ if (SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA == ucCopyData) {
+ // Alloc the internal buffer. Cleanup on failure.
+ pSpnegoToken->pbBinaryData =
+ (unsigned char *) calloc(ulTokenSize, sizeof(unsigned char));
+
+ if (NULL != pSpnegoToken->pbBinaryData) {
+ // We must ALWAYS free this buffer
+ pSpnegoToken->ulFlags |= SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA;
+
+ // Copy the data locally
+ memcpy(pSpnegoToken->pbBinaryData, pbTokenData, ulTokenSize);
+ pSpnegoToken->ulBinaryDataLen = ulTokenSize;
+ } else {
+ free(pSpnegoToken);
+ pSpnegoToken = NULL;
+ }
+
+ } // IF ucCopyData
+ else {
+ // Copy the pointer and the length directly - ulFlags will control whether or not
+ // we are allowed to free the value
+
+ pSpnegoToken->pbBinaryData = pbTokenData;
+ pSpnegoToken->ulBinaryDataLen = ulTokenSize;
+ }
}
@@ -819,18 +840,19 @@
//
////////////////////////////////////////////////////////////////////////////
-void FreeSpnegoToken( SPNEGO_TOKEN* pSpnegoToken )
+void
+FreeSpnegoToken(SPNEGO_TOKEN * pSpnegoToken)
{
- if ( NULL != pSpnegoToken ) {
-
- // Cleanup internal allocation per the flags
- if ( pSpnegoToken->ulFlags & SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA &&
- NULL != pSpnegoToken->pbBinaryData ) {
- free( pSpnegoToken->pbBinaryData );
- pSpnegoToken->pbBinaryData = NULL;
- }
-
- free ( pSpnegoToken );
+ if (NULL != pSpnegoToken) {
+
+ // Cleanup internal allocation per the flags
+ if (pSpnegoToken->ulFlags & SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA &&
+ NULL != pSpnegoToken->pbBinaryData) {
+ free(pSpnegoToken->pbBinaryData);
+ pSpnegoToken->pbBinaryData = NULL;
+ }
+
+ free(pSpnegoToken);
}
}
@@ -851,9 +873,10 @@
//
////////////////////////////////////////////////////////////////////////////
-void InitSpnegoTokenElementArray( SPNEGO_TOKEN* pSpnegoToken )
+void
+InitSpnegoTokenElementArray(SPNEGO_TOKEN * pSpnegoToken)
{
- int nCtr;
+ int nCtr;
// Set the number of elemnts
pSpnegoToken->nNumElements = MAX_NUM_TOKEN_ELEMENTS;
@@ -862,10 +885,11 @@
// Initially, all elements are unavailable
//
- for ( nCtr = 0; nCtr < MAX_NUM_TOKEN_ELEMENTS; nCtr++ ) {
- // Set the element size as well
- pSpnegoToken->aElementArray[ nCtr ].nStructSize = SPNEGO_ELEMENT_SIZE;
- pSpnegoToken->aElementArray[ nCtr ].iElementPresent = SPNEGO_TOKEN_ELEMENT_UNAVAILABLE;
+ for (nCtr = 0; nCtr < MAX_NUM_TOKEN_ELEMENTS; nCtr++) {
+ // Set the element size as well
+ pSpnegoToken->aElementArray[nCtr].nStructSize = SPNEGO_ELEMENT_SIZE;
+ pSpnegoToken->aElementArray[nCtr].iElementPresent =
+ SPNEGO_TOKEN_ELEMENT_UNAVAILABLE;
}
}
@@ -894,112 +918,122 @@
//
////////////////////////////////////////////////////////////////////////////
-int InitSpnegoTokenType( SPNEGO_TOKEN* pSpnegoToken, long* pnTokenLength,
- long* pnRemainingTokenLength, unsigned char** ppbFirstElement )
+int
+InitSpnegoTokenType(SPNEGO_TOKEN * pSpnegoToken, long *pnTokenLength,
+ long *pnRemainingTokenLength, unsigned char **ppbFirstElement)
{
- int nReturn = SPNEGO_E_INVALID_TOKEN;
- long nActualTokenLength = 0L;
- long nBoundaryLength = pSpnegoToken->ulBinaryDataLen;
- unsigned char* pbTokenData = pSpnegoToken->pbBinaryData;
+ int nReturn = SPNEGO_E_INVALID_TOKEN;
+ long nActualTokenLength = 0L;
+ long nBoundaryLength = pSpnegoToken->ulBinaryDataLen;
+ unsigned char *pbTokenData = pSpnegoToken->pbBinaryData;
//
// First byte MUST be either an APP_CONSTRUCT or the NEGTARG_TOKEN_TARG
//
- if ( SPNEGO_NEGINIT_APP_CONSTRUCT == *pbTokenData ) {
- // Validate the above token - this will tell us the actual length of the token
- // per the encoding (minus the actual token bytes)
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, 0L, nBoundaryLength,
- pnTokenLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // Initialize the remaining token length value. This will be used
- // to tell the caller how much token there is left once we've parsed
- // the header (they could calculate it from the other values, but this
- // is a bit friendlier)
- *pnRemainingTokenLength = *pnTokenLength;
-
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
-
- // The next token should be an OID
- if ( ( nReturn = ASNDerCheckOID( pbTokenData, spnego_mech_oid_Spnego, nBoundaryLength,
- &nActualTokenLength ) ) == SPNEGO_E_SUCCESS ) {
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // The next token should specify the NegTokenInit
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // The next token should specify the start of a sequence
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // NegTokenInit header is now checked out!
-
- // Make adjustments to next token
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // Store pointer to first element
- *ppbFirstElement = pbTokenData + nActualTokenLength;
- pSpnegoToken->ucTokenType = SPNEGO_TOKEN_INIT;
- } // IF Check Sequence Token
-
- } // IF Check NegTokenInit token
-
-
- } // IF Check for SPNEGO OID
-
-
- } // IF check app construct token
-
- } else if ( SPNEGO_NEGTARG_TOKEN_IDENTIFIER == *pbTokenData ) {
-
- // The next token should specify the NegTokenInit
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // Initialize the remaining token length value. This will be used
- // to tell the caller how much token there is left once we've parsed
- // the header (they could calculate it from the other values, but this
- // is a bit friendlier)
- *pnRemainingTokenLength = *pnTokenLength;
-
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
-
- // The next token should specify the start of a sequence
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // NegTokenInit header is now checked out!
-
- // Make adjustments to next token
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // Store pointer to first element
- *ppbFirstElement = pbTokenData + nActualTokenLength;
- pSpnegoToken->ucTokenType = SPNEGO_TOKEN_TARG;
- } // IF Check Sequence Token
-
- } // IF Check NegTokenInit token
-
- } // ELSE IF it's a NegTokenTarg
-
- LOG(("InitSpnegoTokenType returned %d\n",nReturn));
+ if (SPNEGO_NEGINIT_APP_CONSTRUCT == *pbTokenData) {
+ // Validate the above token - this will tell us the actual length of the token
+ // per the encoding (minus the actual token bytes)
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, 0L,
+ nBoundaryLength, pnTokenLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Initialize the remaining token length value. This will be used
+ // to tell the caller how much token there is left once we've parsed
+ // the header (they could calculate it from the other values, but this
+ // is a bit friendlier)
+ *pnRemainingTokenLength = *pnTokenLength;
+
+ // Make adjustments to next token
+ pbTokenData += nActualTokenLength;
+ nBoundaryLength -= nActualTokenLength;
+
+ // The next token should be an OID
+ if ((nReturn =
+ ASNDerCheckOID(pbTokenData, spnego_mech_oid_Spnego,
+ nBoundaryLength,
+ &nActualTokenLength)) == SPNEGO_E_SUCCESS) {
+ // Make adjustments to next token
+ pbTokenData += nActualTokenLength;
+ nBoundaryLength -= nActualTokenLength;
+ *pnRemainingTokenLength -= nActualTokenLength;
+
+ // The next token should specify the NegTokenInit
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData,
+ SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
+ *pnRemainingTokenLength, nBoundaryLength,
+ pnTokenLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Make adjustments to next token
+ pbTokenData += nActualTokenLength;
+ nBoundaryLength -= nActualTokenLength;
+ *pnRemainingTokenLength -= nActualTokenLength;
+
+ // The next token should specify the start of a sequence
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData,
+ SPNEGO_CONSTRUCTED_SEQUENCE,
+ *pnRemainingTokenLength, nBoundaryLength,
+ pnTokenLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // NegTokenInit header is now checked out!
+
+ // Make adjustments to next token
+ *pnRemainingTokenLength -= nActualTokenLength;
+
+ // Store pointer to first element
+ *ppbFirstElement = pbTokenData + nActualTokenLength;
+ pSpnegoToken->ucTokenType = SPNEGO_TOKEN_INIT;
+ } // IF Check Sequence Token
+
+ } // IF Check NegTokenInit token
+
+
+ } // IF Check for SPNEGO OID
+
+
+ } // IF check app construct token
+
+ } else if (SPNEGO_NEGTARG_TOKEN_IDENTIFIER == *pbTokenData) {
+
+ // The next token should specify the NegTokenInit
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
+ *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
+ &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Initialize the remaining token length value. This will be used
+ // to tell the caller how much token there is left once we've parsed
+ // the header (they could calculate it from the other values, but this
+ // is a bit friendlier)
+ *pnRemainingTokenLength = *pnTokenLength;
+
+ // Make adjustments to next token
+ pbTokenData += nActualTokenLength;
+ nBoundaryLength -= nActualTokenLength;
+
+ // The next token should specify the start of a sequence
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
+ *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
+ &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // NegTokenInit header is now checked out!
+
+ // Make adjustments to next token
+ *pnRemainingTokenLength -= nActualTokenLength;
+
+ // Store pointer to first element
+ *ppbFirstElement = pbTokenData + nActualTokenLength;
+ pSpnegoToken->ucTokenType = SPNEGO_TOKEN_TARG;
+ } // IF Check Sequence Token
+
+ } // IF Check NegTokenInit token
+
+ } // ELSE IF it's a NegTokenTarg
+
+ LOG(("InitSpnegoTokenType returned %d\n", nReturn));
return nReturn;
}
@@ -1027,37 +1061,39 @@
//
////////////////////////////////////////////////////////////////////////////
-int GetSpnegoInitTokenMechList( unsigned char* pbTokenData, int nMechListLength,
- SPNEGO_ELEMENT* pSpnegoElement )
+int
+GetSpnegoInitTokenMechList(unsigned char *pbTokenData, int nMechListLength,
+ SPNEGO_ELEMENT * pSpnegoElement)
{
- int nReturn = SPNEGO_E_INVALID_TOKEN;
- long nLength = 0L;
- long nActualTokenLength = 0L;
+ int nReturn = SPNEGO_E_INVALID_TOKEN;
+ long nLength = 0L;
+ long nActualTokenLength = 0L;
// Actual MechList is prepended by a Constructed Sequence Token
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- nMechListLength, nMechListLength,
- &nLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // Adjust for this token
- nMechListLength -= nActualTokenLength;
- pbTokenData += nActualTokenLength;
-
- // Perform simple validation of the actual MechList (i.e. ensure that
- // the OIDs in the MechList are reasonable).
-
- if ( ( nReturn = ValidateMechList( pbTokenData, nLength ) ) == SPNEGO_E_SUCCESS ) {
- // Initialize the element now
- pSpnegoElement->eElementType = spnego_init_mechtypes;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = SPNEGO_MECHLIST_TYPE;
- pSpnegoElement->nDatalength = nLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF Check Token
-
- LOG(("GetSpnegoInitTokenMechList returned %d\n",nReturn));
+ if ((nReturn = ASNDerCheckToken(pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
+ nMechListLength, nMechListLength,
+ &nLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Adjust for this token
+ nMechListLength -= nActualTokenLength;
+ pbTokenData += nActualTokenLength;
+
+ // Perform simple validation of the actual MechList (i.e. ensure that
+ // the OIDs in the MechList are reasonable).
+
+ if ((nReturn =
+ ValidateMechList(pbTokenData, nLength)) == SPNEGO_E_SUCCESS) {
+ // Initialize the element now
+ pSpnegoElement->eElementType = spnego_init_mechtypes;
+ pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
+ pSpnegoElement->type = SPNEGO_MECHLIST_TYPE;
+ pSpnegoElement->nDatalength = nLength;
+ pSpnegoElement->pbData = pbTokenData;
+ }
+
+ } // IF Check Token
+
+ LOG(("GetSpnegoInitTokenMechList returned %d\n", nReturn));
return nReturn;
}
@@ -1080,43 +1116,43 @@
//
// Comments :
// Checks that pbTokenData is pointing at the specified DER type. If so,
-// then we verify that lengths are proper and then fill out the
+// then we verify that lengths are proper and then fill out the
// SPNEGO_ELEMENT data structure.
//
////////////////////////////////////////////////////////////////////////////
-int InitSpnegoTokenElementFromBasicType( unsigned char* pbTokenData, int nElementLength,
- unsigned char ucExpectedType,
- SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT* pSpnegoElement )
+int
+InitSpnegoTokenElementFromBasicType(unsigned char *pbTokenData,
+ int nElementLength, unsigned char ucExpectedType,
+ SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement)
{
- int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
- long nLength = 0L;
- long nActualTokenLength = 0L;
+ int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
+ long nLength = 0L;
+ long nActualTokenLength = 0L;
// The type BYTE must match our token data or something is badly wrong
- if ( *pbTokenData == ucExpectedType ) {
-
- // Check that we are pointing at the specified type
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, ucExpectedType,
- nElementLength, nElementLength,
- &nLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // Adjust for this token
- nElementLength -= nActualTokenLength;
- pbTokenData += nActualTokenLength;
-
- // Initialize the element now
- pSpnegoElement->eElementType = spnegoElementType;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = ucExpectedType;
- pSpnegoElement->nDatalength = nLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF type makes sense
-
- LOG(("InitSpnegoTokenElementFromBasicType returned %d\n",nReturn));
+ if (*pbTokenData == ucExpectedType) {
+
+ // Check that we are pointing at the specified type
+ if ((nReturn = ASNDerCheckToken(pbTokenData, ucExpectedType,
+ nElementLength, nElementLength,
+ &nLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Adjust for this token
+ nElementLength -= nActualTokenLength;
+ pbTokenData += nActualTokenLength;
+
+ // Initialize the element now
+ pSpnegoElement->eElementType = spnegoElementType;
+ pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
+ pSpnegoElement->type = ucExpectedType;
+ pSpnegoElement->nDatalength = nLength;
+ pSpnegoElement->pbData = pbTokenData;
+ }
+
+ } // IF type makes sense
+
+ LOG(("InitSpnegoTokenElementFromBasicType returned %d\n", nReturn));
return nReturn;
}
@@ -1145,35 +1181,35 @@
//
////////////////////////////////////////////////////////////////////////////
-int InitSpnegoTokenElementFromOID( unsigned char* pbTokenData, int nElementLength,
- SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT* pSpnegoElement )
+int
+InitSpnegoTokenElementFromOID(unsigned char *pbTokenData, int nElementLength,
+ SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement)
{
- int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
- long nLength = 0L;
- long nActualTokenLength = 0L;
+ int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
+ long nLength = 0L;
+ long nActualTokenLength = 0L;
// The type BYTE must match our token data or something is badly wrong
- if ( *pbTokenData == OID ) {
-
- // Check that we are pointing at an OID type
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, OID,
- nElementLength, nElementLength,
- &nLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- // Don't adjust any values for this function
-
- // Initialize the element now
- pSpnegoElement->eElementType = spnegoElementType;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = OID;
- pSpnegoElement->nDatalength = nElementLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF type makes sense
-
- LOG(("InitSpnegoTokenElementFromBasicType returned %d\n",nReturn));
+ if (*pbTokenData == OID) {
+
+ // Check that we are pointing at an OID type
+ if ((nReturn = ASNDerCheckToken(pbTokenData, OID,
+ nElementLength, nElementLength,
+ &nLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Don't adjust any values for this function
+
+ // Initialize the element now
+ pSpnegoElement->eElementType = spnegoElementType;
+ pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
+ pSpnegoElement->type = OID;
+ pSpnegoElement->nDatalength = nElementLength;
+ pSpnegoElement->pbData = pbTokenData;
+ }
+
+ } // IF type makes sense
+
+ LOG(("InitSpnegoTokenElementFromBasicType returned %d\n", nReturn));
return nReturn;
}
@@ -1201,8 +1237,9 @@
//
////////////////////////////////////////////////////////////////////////////
-int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenData,
- long nRemainingTokenLength )
+int
+InitSpnegoTokenElements(SPNEGO_TOKEN * pSpnegoToken, unsigned char *pbTokenData,
+ long nRemainingTokenLength)
{
//
// The following arrays contain the token identifiers for the elements
@@ -1210,191 +1247,213 @@
// no defaults.
//
- static unsigned char abNegTokenInitElements[] = { SPNEGO_NEGINIT_ELEMENT_MECHTYPES, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
- SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC
- };
-
- static unsigned char abNegTokenTargElements[] = { SPNEGO_NEGTARG_ELEMENT_NEGRESULT, SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
- SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC
- };
-
- int nReturn = SPNEGO_E_SUCCESS;
- int nCtr = 0L;
- long nElementLength = 0L;
- long nActualTokenLength = 0L;
- unsigned char* pbElements = NULL;
+ static unsigned char abNegTokenInitElements[] =
+ { SPNEGO_NEGINIT_ELEMENT_MECHTYPES, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
+ SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC
+ };
+
+ static unsigned char abNegTokenTargElements[] =
+ { SPNEGO_NEGTARG_ELEMENT_NEGRESULT,
+ SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
+ SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC
+ };
+
+ int nReturn = SPNEGO_E_SUCCESS;
+ int nCtr = 0L;
+ long nElementLength = 0L;
+ long nActualTokenLength = 0L;
+ unsigned char *pbElements = NULL;
// Point to the correct array
- switch ( pSpnegoToken->ucTokenType ) {
- case SPNEGO_TOKEN_INIT: {
- pbElements = abNegTokenInitElements;
- }
- break;
-
- case SPNEGO_TOKEN_TARG: {
- pbElements = abNegTokenTargElements;
- }
- break;
-
- } // SWITCH tokentype
+ switch (pSpnegoToken->ucTokenType) {
+ case SPNEGO_TOKEN_INIT:
+ {
+ pbElements = abNegTokenInitElements;
+ }
+ break;
+
+ case SPNEGO_TOKEN_TARG:
+ {
+ pbElements = abNegTokenTargElements;
+ }
+ break;
+
+ } // SWITCH tokentype
//
// Enumerate the element arrays and look for the tokens at our current location
//
- for ( nCtr = 0L;
- SPNEGO_E_SUCCESS == nReturn &&
- nCtr < MAX_NUM_TOKEN_ELEMENTS &&
- nRemainingTokenLength > 0L;
- nCtr++ ) {
-
- // Check if the token exists
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, pbElements[nCtr],
- 0L, nRemainingTokenLength,
- &nElementLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
-
- // Token data should skip over the sequence token and then
- // call the appropriate function to initialize the element
- pbTokenData += nActualTokenLength;
-
- // Lengths in the elements should NOT go beyond the element
- // length
-
- // Different tokens mean different elements
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) {
-
- // Handle each element as appropriate
- switch ( pbElements[nCtr] ) {
-
- case SPNEGO_NEGINIT_ELEMENT_MECHTYPES: {
- //
- // This is a Mech List that specifies which OIDs the
- // originator of the Init Token supports.
- //
-
- nReturn = GetSpnegoInitTokenMechList( pbTokenData, nElementLength,
- &pSpnegoToken->aElementArray[nCtr] );
-
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_REQFLAGS: {
- //
- // This is a BITSTRING which specifies the flags that the receiver
- // pass to the gss_accept_sec_context() function.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- BITSTRING, spnego_init_reqFlags,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_MECHTOKEN: {
- //
- // This is an OCTETSTRING which contains a GSSAPI token corresponding
- // to the first OID in the MechList.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_init_mechToken,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC: {
- //
- // This is an OCTETSTRING which contains a message integrity BLOB.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_init_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- } // SWITCH Element
- } else {
-
- switch ( pbElements[nCtr] ) {
-
- case SPNEGO_NEGTARG_ELEMENT_NEGRESULT: {
- //
- // This is an ENUMERATION which specifies result of the last GSS
- // token negotiation call.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- ENUMERATED, spnego_targ_negResult,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH: {
- //
- // This is an OID which specifies a supported mechanism.
- //
-
- nReturn = InitSpnegoTokenElementFromOID( pbTokenData, nElementLength,
- spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN: {
- //
- // This is an OCTETSTRING which specifies results of the last GSS
- // token negotiation call.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_targ_responseToken,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC: {
- //
- // This is an OCTETSTRING which specifies a message integrity BLOB.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- } // SWITCH Element
-
- } // ELSE !NegTokenInit
-
- // Account for the entire token and following data
- nRemainingTokenLength -= ( nActualTokenLength + nElementLength );
-
- // Token data should skip past the element length now
- pbTokenData += nElementLength;
-
- } // IF Token found
- else if ( SPNEGO_E_TOKEN_NOT_FOUND == nReturn ) {
- // For now, this is a benign error (remember, all elements are optional, so
- // if we don't find one, it's okay).
-
- nReturn = SPNEGO_E_SUCCESS;
- }
-
- } // FOR enum elements
+ for (nCtr = 0L;
+ SPNEGO_E_SUCCESS == nReturn &&
+ nCtr < MAX_NUM_TOKEN_ELEMENTS && nRemainingTokenLength > 0L; nCtr++) {
+
+ // Check if the token exists
+ if ((nReturn = ASNDerCheckToken(pbTokenData, pbElements[nCtr],
+ 0L, nRemainingTokenLength,
+ &nElementLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+
+ // Token data should skip over the sequence token and then
+ // call the appropriate function to initialize the element
+ pbTokenData += nActualTokenLength;
+
+ // Lengths in the elements should NOT go beyond the element
+ // length
+
+ // Different tokens mean different elements
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+
+ // Handle each element as appropriate
+ switch (pbElements[nCtr]) {
+
+ case SPNEGO_NEGINIT_ELEMENT_MECHTYPES:
+ {
+ //
+ // This is a Mech List that specifies which OIDs the
+ // originator of the Init Token supports.
+ //
+
+ nReturn =
+ GetSpnegoInitTokenMechList(pbTokenData,
+ nElementLength, &pSpnegoToken->aElementArray[nCtr]);
+
+ }
+ break;
+
+ case SPNEGO_NEGINIT_ELEMENT_REQFLAGS:
+ {
+ //
+ // This is a BITSTRING which specifies the flags that the receiver
+ // pass to the gss_accept_sec_context() function.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, BITSTRING, spnego_init_reqFlags,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGINIT_ELEMENT_MECHTOKEN:
+ {
+ //
+ // This is an OCTETSTRING which contains a GSSAPI token corresponding
+ // to the first OID in the MechList.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, OCTETSTRING, spnego_init_mechToken,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC:
+ {
+ //
+ // This is an OCTETSTRING which contains a message integrity BLOB.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, OCTETSTRING,
+ spnego_init_mechListMIC,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ } // SWITCH Element
+ } else {
+
+ switch (pbElements[nCtr]) {
+
+ case SPNEGO_NEGTARG_ELEMENT_NEGRESULT:
+ {
+ //
+ // This is an ENUMERATION which specifies result of the last GSS
+ // token negotiation call.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, ENUMERATED, spnego_targ_negResult,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH:
+ {
+ //
+ // This is an OID which specifies a supported mechanism.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromOID(pbTokenData,
+ nElementLength, spnego_targ_mechListMIC,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN:
+ {
+ //
+ // This is an OCTETSTRING which specifies results of the last GSS
+ // token negotiation call.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, OCTETSTRING,
+ spnego_targ_responseToken,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC:
+ {
+ //
+ // This is an OCTETSTRING which specifies a message integrity BLOB.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, OCTETSTRING,
+ spnego_targ_mechListMIC,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ } // SWITCH Element
+
+ } // ELSE !NegTokenInit
+
+ // Account for the entire token and following data
+ nRemainingTokenLength -= (nActualTokenLength + nElementLength);
+
+ // Token data should skip past the element length now
+ pbTokenData += nElementLength;
+
+ } // IF Token found
+ else if (SPNEGO_E_TOKEN_NOT_FOUND == nReturn) {
+ // For now, this is a benign error (remember, all elements are optional, so
+ // if we don't find one, it's okay).
+
+ nReturn = SPNEGO_E_SUCCESS;
+ }
+
+ } // FOR enum elements
//
// We should always run down to 0 remaining bytes in the token. If not, we've got
// a bad token.
//
- if ( SPNEGO_E_SUCCESS == nReturn && nRemainingTokenLength != 0L ) {
- nReturn = SPNEGO_E_INVALID_TOKEN;
+ if (SPNEGO_E_SUCCESS == nReturn && nRemainingTokenLength != 0L) {
+ nReturn = SPNEGO_E_INVALID_TOKEN;
}
- LOG(("InitSpnegoTokenElements returned %d\n",nReturn));
+ LOG(("InitSpnegoTokenElements returned %d\n", nReturn));
return nReturn;
}
@@ -1420,31 +1479,33 @@
//
////////////////////////////////////////////////////////////////////////////
-int FindMechOIDInMechList( SPNEGO_ELEMENT* pSpnegoElement, SPNEGO_MECH_OID MechOID,
- int * piMechTypeIndex )
+int
+FindMechOIDInMechList(SPNEGO_ELEMENT * pSpnegoElement, SPNEGO_MECH_OID MechOID,
+ int *piMechTypeIndex)
{
- int nReturn = SPNEGO_E_NOT_FOUND;
- int nCtr = 0;
- long nLength = 0L;
- long nBoundaryLength = pSpnegoElement->nDatalength;
- unsigned char* pbMechListData = pSpnegoElement->pbData;
-
- while ( SPNEGO_E_SUCCESS != nReturn && nBoundaryLength > 0L ) {
-
- // Use the helper function to check the OID
- if ( ( nReturn = ASNDerCheckOID( pbMechListData, MechOID, nBoundaryLength, &nLength ) )
- == SPNEGO_E_SUCCESS ) {
- *piMechTypeIndex = nCtr;
- }
-
- // Adjust for the current OID
- pbMechListData += nLength;
- nBoundaryLength -= nLength;
- nCtr++;
-
- } // WHILE enuming OIDs
-
- LOG(("FindMechOIDInMechList returned %d\n",nReturn));
+ int nReturn = SPNEGO_E_NOT_FOUND;
+ int nCtr = 0;
+ long nLength = 0L;
+ long nBoundaryLength = pSpnegoElement->nDatalength;
+ unsigned char *pbMechListData = pSpnegoElement->pbData;
+
+ while (SPNEGO_E_SUCCESS != nReturn && nBoundaryLength > 0L) {
+
+ // Use the helper function to check the OID
+ if ((nReturn =
+ ASNDerCheckOID(pbMechListData, MechOID, nBoundaryLength,
+ &nLength))
+ == SPNEGO_E_SUCCESS) {
+ *piMechTypeIndex = nCtr;
+ }
+ // Adjust for the current OID
+ pbMechListData += nLength;
+ nBoundaryLength -= nLength;
+ nCtr++;
+
+ } // WHILE enuming OIDs
+
+ LOG(("FindMechOIDInMechList returned %d\n", nReturn));
return nReturn;
}
@@ -1470,26 +1531,27 @@
//
////////////////////////////////////////////////////////////////////////////
-int ValidateMechList( unsigned char* pbMechListData, long nBoundaryLength )
+int
+ValidateMechList(unsigned char *pbMechListData, long nBoundaryLength)
{
- int nReturn = SPNEGO_E_SUCCESS;
- long nLength = 0L;
- long nTokenLength = 0L;
-
- while ( SPNEGO_E_SUCCESS == nReturn && nBoundaryLength > 0L ) {
- // Verify that we have something that at least *looks* like an OID - in other
- // words it has an OID identifier and specifies a length that doesn't go beyond
- // the size of the list.
- nReturn = ASNDerCheckToken( pbMechListData, OID, 0L, nBoundaryLength,
- &nLength, &nTokenLength );
-
- // Adjust for the current OID
- pbMechListData += ( nLength + nTokenLength );
- nBoundaryLength -= ( nLength + nTokenLength );
-
- } // WHILE enuming OIDs
-
- LOG(("ValidateMechList returned %d\n",nReturn));
+ int nReturn = SPNEGO_E_SUCCESS;
+ long nLength = 0L;
+ long nTokenLength = 0L;
+
+ while (SPNEGO_E_SUCCESS == nReturn && nBoundaryLength > 0L) {
+ // Verify that we have something that at least *looks* like an OID - in other
+ // words it has an OID identifier and specifies a length that doesn't go beyond
+ // the size of the list.
+ nReturn = ASNDerCheckToken(pbMechListData, OID, 0L, nBoundaryLength,
+ &nLength, &nTokenLength);
+
+ // Adjust for the current OID
+ pbMechListData += (nLength + nTokenLength);
+ nBoundaryLength -= (nLength + nTokenLength);
+
+ } // WHILE enuming OIDs
+
+ LOG(("ValidateMechList returned %d\n", nReturn));
return nReturn;
}
@@ -1511,12 +1573,14 @@
//
////////////////////////////////////////////////////////////////////////////
-int IsValidMechOid( SPNEGO_MECH_OID mechOid )
+int
+IsValidMechOid(SPNEGO_MECH_OID mechOid)
{
- LOG(("IsValidMechOid returned %d\n",mechOid >= spnego_mech_oid_Kerberos_V5_Legacy &&
- mechOid <= spnego_mech_oid_Spnego));
- return ( mechOid >= spnego_mech_oid_Kerberos_V5_Legacy &&
- mechOid <= spnego_mech_oid_Spnego );
+ LOG(("IsValidMechOid returned %d\n",
+ mechOid >= spnego_mech_oid_Kerberos_V5_Legacy
+ && mechOid <= spnego_mech_oid_Spnego));
+ return (mechOid >= spnego_mech_oid_Kerberos_V5_Legacy
+ && mechOid <= spnego_mech_oid_Spnego);
}
/////////////////////////////////////////////////////////////////////////////
@@ -1536,12 +1600,14 @@
//
////////////////////////////////////////////////////////////////////////////
-int IsValidContextFlags( unsigned char ucContextFlags )
+int
+IsValidContextFlags(unsigned char ucContextFlags)
{
// Mask out our valid bits. If there is anything leftover, this
// is not a valid value for Context Flags
- LOG(("IsValidContextFlags returned %d\n",(( ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK ) == 0)));
- return ( ( ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK ) == 0 );
+ LOG(("IsValidContextFlags returned %d\n",
+ ((ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK) == 0)));
+ return ((ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK) == 0);
}
/////////////////////////////////////////////////////////////////////////////
@@ -1561,12 +1627,13 @@
//
////////////////////////////////////////////////////////////////////////////
-int IsValidNegResult( SPNEGO_NEGRESULT negResult )
+int
+IsValidNegResult(SPNEGO_NEGRESULT negResult)
{
- LOG(("IsValidNegResult returned %d\n",negResult >= spnego_negresult_success &&
- negResult <= spnego_negresult_rejected ));
- return ( negResult >= spnego_negresult_success &&
- negResult <= spnego_negresult_rejected );
+ LOG(("IsValidNegResult returned %d\n", negResult >= spnego_negresult_success
+ && negResult <= spnego_negresult_rejected));
+ return (negResult >= spnego_negresult_success
+ && negResult <= spnego_negresult_rejected);
}
/////////////////////////////////////////////////////////////////////////////
@@ -1586,29 +1653,30 @@
//
////////////////////////////////////////////////////////////////////////////
-int IsValidSpnegoToken( SPNEGO_TOKEN* pSpnegoToken )
+int
+IsValidSpnegoToken(SPNEGO_TOKEN * pSpnegoToken)
{
- int nReturn = 0;
+ int nReturn = 0;
// Parameter should be non-NULL
- if ( NULL != pSpnegoToken ) {
- // Length should be at least the size defined in the header
- if ( pSpnegoToken->nStructSize >= SPNEGO_TOKEN_SIZE ) {
- // Number of elements should be >= our maximum - if it's greater, that's
- // okay, since we'll only be accessing the elements up to MAX_NUM_TOKEN_ELEMENTS
- if ( pSpnegoToken->nNumElements >= MAX_NUM_TOKEN_ELEMENTS ) {
- // Check for proper token type
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) {
- nReturn = 1;
- }
- }
-
- } // IF struct size makes sense
-
- } // IF non-NULL spnego Token
-
- LOG(("IsValidSpnegoToken returned %d\n",nReturn));
+ if (NULL != pSpnegoToken) {
+ // Length should be at least the size defined in the header
+ if (pSpnegoToken->nStructSize >= SPNEGO_TOKEN_SIZE) {
+ // Number of elements should be >= our maximum - if it's greater, that's
+ // okay, since we'll only be accessing the elements up to MAX_NUM_TOKEN_ELEMENTS
+ if (pSpnegoToken->nNumElements >= MAX_NUM_TOKEN_ELEMENTS) {
+ // Check for proper token type
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
+ SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
+ nReturn = 1;
+ }
+ }
+
+ } // IF struct size makes sense
+
+ } // IF non-NULL spnego Token
+
+ LOG(("IsValidSpnegoToken returned %d\n", nReturn));
return nReturn;
}
@@ -1631,26 +1699,28 @@
//
////////////////////////////////////////////////////////////////////////////
-int IsValidSpnegoElement( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement )
+int
+IsValidSpnegoElement(SPNEGO_TOKEN * pSpnegoToken,
+ SPNEGO_ELEMENT_TYPE spnegoElement)
{
- int nReturn = 0;
+ int nReturn = 0;
// Check boundaries
- if ( spnegoElement > spnego_element_min &&
- spnegoElement < spnego_element_max ) {
-
- // Check for appropriateness to token type
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) {
- nReturn = ( spnegoElement >= spnego_init_mechtypes &&
- spnegoElement <= spnego_init_mechListMIC );
- } else {
- nReturn = ( spnegoElement >= spnego_targ_negResult &&
- spnegoElement <= spnego_targ_mechListMIC );
- }
-
- } // IF boundary conditions are met
-
- LOG(("IsValidSpnegoElement returned %d\n",nReturn));
+ if (spnegoElement > spnego_element_min &&
+ spnegoElement < spnego_element_max) {
+
+ // Check for appropriateness to token type
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+ nReturn = (spnegoElement >= spnego_init_mechtypes &&
+ spnegoElement <= spnego_init_mechListMIC);
+ } else {
+ nReturn = (spnegoElement >= spnego_targ_negResult &&
+ spnegoElement <= spnego_targ_mechListMIC);
+ }
+
+ } // IF boundary conditions are met
+
+ LOG(("IsValidSpnegoElement returned %d\n", nReturn));
return nReturn;
}
@@ -1673,20 +1743,22 @@
//
////////////////////////////////////////////////////////////////////////////
-int CalculateElementArrayIndex( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement )
+int
+CalculateElementArrayIndex(SPNEGO_TOKEN * pSpnegoToken,
+ SPNEGO_ELEMENT_TYPE spnegoElement)
{
- int nReturn = 0;
+ int nReturn = 0;
// Offset is difference between value and initial element identifier
// (these differ based on ucTokenType)
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) {
- nReturn = spnegoElement - spnego_init_mechtypes;
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+ nReturn = spnegoElement - spnego_init_mechtypes;
} else {
- nReturn = spnegoElement - spnego_targ_negResult;
+ nReturn = spnegoElement - spnego_targ_negResult;
}
- LOG(("CalculateElementArrayIndex returned %d\n",nReturn));
+ LOG(("CalculateElementArrayIndex returned %d\n", nReturn));
return nReturn;
}
@@ -1715,59 +1787,60 @@
// Initializes SPNEGO_TOKEN structure from DER encoded binary data
-int InitTokenFromBinary( unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char* pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN** ppSpnegoToken )
+int
+InitTokenFromBinary(unsigned char ucCopyData, unsigned long ulFlags,
+ unsigned char *pbTokenData, unsigned long ulLength,
+ SPNEGO_TOKEN ** ppSpnegoToken)
{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = NULL;
- unsigned char* pbFirstElement = NULL;
- long nTokenLength = 0L;
- long nRemainingTokenLength = 0L;
+ int nReturn = SPNEGO_E_INVALID_PARAMETER;
+ SPNEGO_TOKEN *pSpnegoToken = NULL;
+ unsigned char *pbFirstElement = NULL;
+ long nTokenLength = 0L;
+ long nRemainingTokenLength = 0L;
// Basic Parameter Validation
- if ( NULL != pbTokenData &&
- NULL != ppSpnegoToken &&
- 0L != ulLength ) {
-
- //
- // Allocate the empty token, then initialize the data structure.
- //
-
- pSpnegoToken = AllocEmptySpnegoToken( ucCopyData, ulFlags, pbTokenData, ulLength );
-
- if ( NULL != pSpnegoToken ) {
-
- // Copy the binary data locally
-
-
- // Initialize the token type
- if ( ( nReturn = InitSpnegoTokenType( pSpnegoToken, &nTokenLength,
- &nRemainingTokenLength, &pbFirstElement ) )
- == SPNEGO_E_SUCCESS ) {
-
- // Initialize the element array
- if ( ( nReturn = InitSpnegoTokenElements( pSpnegoToken, pbFirstElement,
- nRemainingTokenLength ) )
- == SPNEGO_E_SUCCESS ) {
- *ppSpnegoToken = pSpnegoToken;
- }
-
- } // IF Init Token Type
-
- // Cleanup on error condition
- if ( SPNEGO_E_SUCCESS != nReturn ) {
- spnegoFreeData( pSpnegoToken );
- }
-
- } else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // IF Valid parameters
-
-
- LOG(("InitTokenFromBinary returned %d\n",nReturn));
+ if (NULL != pbTokenData && NULL != ppSpnegoToken && 0L != ulLength) {
+
+ //
+ // Allocate the empty token, then initialize the data structure.
+ //
+
+ pSpnegoToken =
+ AllocEmptySpnegoToken(ucCopyData, ulFlags, pbTokenData, ulLength);
+
+ if (NULL != pSpnegoToken) {
+
+ // Copy the binary data locally
+
+
+ // Initialize the token type
+ if ((nReturn = InitSpnegoTokenType(pSpnegoToken, &nTokenLength,
+ &nRemainingTokenLength, &pbFirstElement))
+ == SPNEGO_E_SUCCESS) {
+
+ // Initialize the element array
+ if ((nReturn =
+ InitSpnegoTokenElements(pSpnegoToken, pbFirstElement,
+ nRemainingTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ *ppSpnegoToken = pSpnegoToken;
+ }
+
+ } // IF Init Token Type
+
+ // Cleanup on error condition
+ if (SPNEGO_E_SUCCESS != nReturn) {
+ spnegoFreeData(pSpnegoToken);
+ }
+
+ } else {
+ nReturn = SPNEGO_E_OUT_OF_MEMORY;
+ }
+
+ } // IF Valid parameters
+
+
+ LOG(("InitTokenFromBinary returned %d\n", nReturn));
return nReturn;
}
=== modified file 'helpers/negotiate_auth/kerberos/spnegohelp/spnegoparse.h'
--- helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.h 2009-08-23 09:30:49 +0000
+++ helpers/negotiate_auth/kerberos/spnegohelp/spnegoparse.h 2009-09-04 12:59:38 +0000
@@ -26,7 +26,8 @@
// C++ Specific
#if defined(__cplusplus)
-extern "C" {
+extern "C"
+{
#endif
// Indicates if we copy data when creating a SPNEGO_TOKEN structure or not
@@ -64,19 +65,20 @@
// Defines an individual SPNEGO Token Element.
//
- typedef struct SpnegoElement {
- size_t nStructSize; // Size of the element structure
- int iElementPresent; // Is the field present? Must be either
- // SPNEGO_TOKEN_ELEMENT_UNAVAILABLE or
- // SPNEGO_TOKEN_ELEMENT_AVAILABLE
-
- SPNEGO_ELEMENT_TYPE eElementType; // The Element Type
-
- unsigned char type; // Data Type
-
- unsigned char* pbData; // Points to actual Data
-
- unsigned long nDatalength; // Actual Data Length
+ typedef struct SpnegoElement
+ {
+ size_t nStructSize; // Size of the element structure
+ int iElementPresent; // Is the field present? Must be either
+ // SPNEGO_TOKEN_ELEMENT_UNAVAILABLE or
+ // SPNEGO_TOKEN_ELEMENT_AVAILABLE
+
+ SPNEGO_ELEMENT_TYPE eElementType; // The Element Type
+
+ unsigned char type; // Data Type
+
+ unsigned char *pbData; // Points to actual Data
+
+ unsigned long nDatalength; // Actual Data Length
} SPNEGO_ELEMENT;
@@ -89,18 +91,19 @@
// contain up to four distinct, optional elements.
//
- typedef struct SpnegoToken {
- size_t nStructSize; // Size of the Token structure
- unsigned long ulFlags; // Internal Structure Flags - Reserved!
- int ucTokenType; // Token Type - Must be
- // SPNEGO_TOKEN_INIT or
- // SPNEGO_TOKEN_TARG
-
- unsigned char* pbBinaryData; // Points to binary token data
-
- unsigned long ulBinaryDataLen; // Length of the actual binary data
- int nNumElements; // Number of elements
- SPNEGO_ELEMENT aElementArray [MAX_NUM_TOKEN_ELEMENTS]; // Holds the elements for the token
+ typedef struct SpnegoToken
+ {
+ size_t nStructSize; // Size of the Token structure
+ unsigned long ulFlags; // Internal Structure Flags - Reserved!
+ int ucTokenType; // Token Type - Must be
+ // SPNEGO_TOKEN_INIT or
+ // SPNEGO_TOKEN_TARG
+
+ unsigned char *pbBinaryData; // Points to binary token data
+
+ unsigned long ulBinaryDataLen; // Length of the actual binary data
+ int nNumElements; // Number of elements
+ SPNEGO_ELEMENT aElementArray[MAX_NUM_TOKEN_ELEMENTS]; // Holds the elements for the token
} SPNEGO_TOKEN;
// Structure size in case we later choose to extend the structure
@@ -110,52 +113,53 @@
// Function definitions
//
- SPNEGO_TOKEN* AllocEmptySpnegoToken( unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char * pbTokenData, unsigned long ulTokenSize );
- void FreeSpnegoToken( SPNEGO_TOKEN* pSpnegoToken );
- void InitSpnegoTokenElementArray( SPNEGO_TOKEN* pSpnegoToken );
- int InitSpnegoTokenType( SPNEGO_TOKEN* pSpnegoToken, long* pnTokenLength,
- long* pnRemainingTokenLength, unsigned char** ppbFirstElement );
- int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenData,
- long nRemainingTokenLength );
- int GetSpnegoInitTokenMechList( unsigned char* pbTokenData, int nMechListLength,
- SPNEGO_ELEMENT* pSpnegoElement );
- int InitSpnegoTokenElementFromBasicType( unsigned char* pbTokenData, int nElementLength,
- unsigned char ucExpectedType,
- SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT* pSpnegoElement );
- int InitSpnegoTokenElementFromOID( unsigned char* pbTokenData, int nElementLength,
- SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT* pSpnegoElement );
- int FindMechOIDInMechList( SPNEGO_ELEMENT* pSpnegoElement, SPNEGO_MECH_OID MechOID,
- int * piMechTypeIndex );
- int ValidateMechList( unsigned char* pbMechListData, long nBoundaryLength );
- int CalculateMinSpnegoInitTokenSize( long nMechTokenLength, long nMechListMICLength,
- SPNEGO_MECH_OID mechOid, int nReqFlagsAvailable,
- long* plTokenSize, long* plInternalLength );
- int CalculateMinSpnegoTargTokenSize( SPNEGO_MECH_OID MechType, SPNEGO_NEGRESULT spnegoNegResult,
- long nMechTokenLen,
- long nMechTokenMIC, long* pnTokenSize,
- long* pnInternalTokenLength );
- int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char* pbTokenData,
- long nTokenLength, long nInternalTokenLength );
- int CreateSpnegoTargToken( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT eNegResult, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char* pbTokenData,
- long nTokenLength, long nInternalTokenLength );
- int IsValidMechOid( SPNEGO_MECH_OID mechOid );
- int IsValidContextFlags( unsigned char ucContextFlags );
- int IsValidNegResult( SPNEGO_NEGRESULT negResult );
- int IsValidSpnegoToken( SPNEGO_TOKEN* pSpnegoToken );
- int IsValidSpnegoElement( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement );
- int CalculateElementArrayIndex( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement );
- int InitTokenFromBinary( unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char* pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN** ppSpnegoToken );
+ SPNEGO_TOKEN *AllocEmptySpnegoToken(unsigned char ucCopyData,
+ unsigned long ulFlags, unsigned char *pbTokenData,
+ unsigned long ulTokenSize);
+ void FreeSpnegoToken(SPNEGO_TOKEN * pSpnegoToken);
+ void InitSpnegoTokenElementArray(SPNEGO_TOKEN * pSpnegoToken);
+ int InitSpnegoTokenType(SPNEGO_TOKEN * pSpnegoToken, long *pnTokenLength,
+ long *pnRemainingTokenLength, unsigned char **ppbFirstElement);
+ int InitSpnegoTokenElements(SPNEGO_TOKEN * pSpnegoToken,
+ unsigned char *pbTokenData, long nRemainingTokenLength);
+ int GetSpnegoInitTokenMechList(unsigned char *pbTokenData,
+ int nMechListLength, SPNEGO_ELEMENT * pSpnegoElement);
+ int InitSpnegoTokenElementFromBasicType(unsigned char *pbTokenData,
+ int nElementLength, unsigned char ucExpectedType,
+ SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement);
+ int InitSpnegoTokenElementFromOID(unsigned char *pbTokenData,
+ int nElementLength, SPNEGO_ELEMENT_TYPE spnegoElementType,
+ SPNEGO_ELEMENT * pSpnegoElement);
+ int FindMechOIDInMechList(SPNEGO_ELEMENT * pSpnegoElement,
+ SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
+ int ValidateMechList(unsigned char *pbMechListData, long nBoundaryLength);
+ int CalculateMinSpnegoInitTokenSize(long nMechTokenLength,
+ long nMechListMICLength, SPNEGO_MECH_OID mechOid,
+ int nReqFlagsAvailable, long *plTokenSize, long *plInternalLength);
+ int CalculateMinSpnegoTargTokenSize(SPNEGO_MECH_OID MechType,
+ SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
+ long nMechTokenMIC, long *pnTokenSize, long *pnInternalTokenLength);
+ int CreateSpnegoInitToken(SPNEGO_MECH_OID MechType,
+ unsigned char ucContextFlags, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, unsigned char *pbTokenData,
+ long nTokenLength, long nInternalTokenLength);
+ int CreateSpnegoTargToken(SPNEGO_MECH_OID MechType,
+ SPNEGO_NEGRESULT eNegResult, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, unsigned char *pbTokenData,
+ long nTokenLength, long nInternalTokenLength);
+ int IsValidMechOid(SPNEGO_MECH_OID mechOid);
+ int IsValidContextFlags(unsigned char ucContextFlags);
+ int IsValidNegResult(SPNEGO_NEGRESULT negResult);
+ int IsValidSpnegoToken(SPNEGO_TOKEN * pSpnegoToken);
+ int IsValidSpnegoElement(SPNEGO_TOKEN * pSpnegoToken,
+ SPNEGO_ELEMENT_TYPE spnegoElement);
+ int CalculateElementArrayIndex(SPNEGO_TOKEN * pSpnegoToken,
+ SPNEGO_ELEMENT_TYPE spnegoElement);
+ int InitTokenFromBinary(unsigned char ucCopyData, unsigned long ulFlags,
+ unsigned char *pbTokenData, unsigned long ulLength,
+ SPNEGO_TOKEN ** ppSpnegoToken);
// C++ Specific
#if defined(__cplusplus)
@@ -163,4 +167,3 @@
#endif
#endif
-
=== removed file 'helpers/negotiate_auth/squid_kerb_auth/AUTHORS'
=== removed file 'helpers/negotiate_auth/squid_kerb_auth/ChangeLog'
=== removed file 'helpers/negotiate_auth/squid_kerb_auth/INSTALL'
=== removed file 'helpers/negotiate_auth/squid_kerb_auth/NEWS'
=== removed file 'helpers/negotiate_auth/squid_kerb_auth/config.test'
--- helpers/negotiate_auth/squid_kerb_auth/config.test 2008-11-09 11:25:31 +0000
+++ helpers/negotiate_auth/squid_kerb_auth/config.test 1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-#!/bin/sh
-# Don't build without gssapi.h
-if test -f /usr/include/gssapi/gssapi.h || test -f /usr/include/gssapi.h ; then
- exit 0
-fi
-exit 1
=== removed file 'helpers/negotiate_auth/squid_kerb_auth/configure.in'
--- helpers/negotiate_auth/squid_kerb_auth/configure.in 2009-04-23 08:08:14 +0000
+++ helpers/negotiate_auth/squid_kerb_auth/configure.in 1970-01-01 00:00:00 +0000
@@ -1,552 +0,0 @@
-dnl This program is free software; you can redistribute it and/or modify
-dnl it under the terms of the GNU General Public License as published by
-dnl the Free Software Foundation; either version 2 of the License, or
-dnl (at your option) any later version.
-dnl
-dnl This program is distributed in the hope that it will be useful,
-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-dnl GNU General Public License for more details.
-dnl
-dnl You should have received a copy of the GNU General Public License
-dnl along with this program; if not, write to the Free Software
-dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-dnl
-dnl Process this file with autoconf to produce a configure script.
-
-
-AC_INIT([squid_kerb_auth],[1.0.5],[markus_moeller_at_compuserve.com])
-AM_INIT_AUTOMAKE(squid_kerb_auth,1.0.5)
-AC_CONFIG_SRCDIR([squid_kerb_auth.c])
-
-AC_PROG_CC
-AC_PROG_CPP
-
-AC_TRY_COMPILE([int main()
- {
- return;
- }
-])
-
-SPARCV9=""
-sys=`uname`
-case $sys in
- Linux) w_flag="-Wl,-R"
- w_flag_2=""
- ;;
- AIX) w_flag="-Wl,-blibpath:"
- w_flag_2=":/usr/lib:/lib"
- ;;
- SunOS) w_flag="-R"
- w_flag_2=""
- rel=`uname -r`
- case $rel in
- 5.10|5.11) AC_DEFINE(HAVE_NEW_SEAM_KERBEROS,1,[Define to 1 if you have New Solaris 10/OpenSolaris Kerberos])
- ;;
- *) ;;
- esac
- ;;
- FreeBSD) w_flag="-Wl,-R"
- w_flag_2=""
- ;;
- *) w_flag="-Wl,-rpath"
- w_flag_2=""
- ;;
-esac
-
-
-enable_arg="no"
-check_mit() {
- if test "x$ac_krb5_config" = "xyes" ; then
- ac_heimdal=`krb5-config --version 2>/dev/null | grep heimdal`
- if test "x$ac_heimdal" != "x" ; then
- check_heimdal
- return
- fi
- fi
- AC_DEFINE(HAVE_MIT_KERBEROS,1,[Define to 1 if you have MIT Kerberos])
- ac_gss_libs="resolv com_err des425 k5crypto krb5 gssapi_krb5"
- ac_includedir=""
- ac_libdir=""
- case $sys in
- Linux) if test "x$enableval" != "xyes" -a "x$enableval" != "x" ; then
- ac_libdir=$enableval/lib
- ac_includedir=$enableval/include
- else
- ac_libdir=`rpm -q -l krb5 2>/dev/null | grep "/libgssapi_krb5" | sed -e 's/\/libgssapi_krb5.*//' | head -1`
- ac_includedir=`rpm -q -l krb5-devel 2>/dev/null | grep /krb5.h$ | sed -e 's/\/krb5.h//' | head -1`
- fi
- if test "x$ac_includedir" != "x" ; then
- CPPFLAGS="$CPPFLAGS -I$ac_includedir"
- else
- ac_gssapi_cflags=`krb5-config --cflags gssapi 2>/dev/null`
- if test "x$ac_gssapi_cflags" != "x" ; then
- CPPFLAGS="$CPPFLAGS $ac_gssapi_cflags"
- fi
- fi
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_krb5.h gssapi/gssapi_generic.h)
- if test "x$ac_libdir" != "x" ; then
- LDFLAGS="$LDFLAGS -L$ac_libdir $w_flag$ac_libdir$w_flag_2"
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- else
- ac_gssapi_libs=`krb5-config --libs gssapi 2>/dev/null`
- if test "x$ac_gssapi_libs" != "x" ; then
- LDFLAGS="$LDFLAGS $ac_gssapi_libs"
- else
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- fi
- fi
- ;;
- *) if test "x$enableval" != "xyes" -a "x$enableval" != "x" ; then
- ac_libdir=$enableval/lib
- ac_includedir=$enableval/include
- CPPFLAGS="$CPPFLAGS -I$ac_includedir"
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_krb5.h gssapi/gssapi_generic.h)
- LDFLAGS="$LDFLAGS -L$ac_libdir $w_flag$ac_libdir$w_flag_2"
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- else
- ac_gssapi_cflags=`krb5-config --cflags gssapi 2>/dev/null`
- if test "x$ac_gssapi_cflags" != "x" ; then
- CPPFLAGS="$CPPFLAGS $ac_gssapi_cflags"
- fi
- ac_gssapi_libs=`krb5-config --libs gssapi 2>/dev/null`
- if test "x$ac_gssapi_libs" != "x" ; then
- LDFLAGS="$LDFLAGS $ac_gssapi_libs"
- else
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- fi
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_krb5.h gssapi/gssapi_generic.h)
- fi
- ;;
- esac
- enable_arg="mit"
-}
-check_heimdal(){
- if test "x$ac_krb5_config" = "xyes" ; then
- ac_heimdal=`krb5-config --version 2>/dev/null | grep heimdal`
- if test "x$ac_heimdal" = "x" ; then
- check_mit
- return
- fi
- fi
- AC_DEFINE(HAVE_HEIMDAL_KERBEROS,1,[Define to 1 if you have Heimdal Kerberos])
- ac_gss_libs="resolv crypto des crypt roken com_err asn1 krb5 gssapi"
- ac_includedir=""
- ac_libdir=""
- case $sys in
- Linux) if test "x$enableval" != "xyes" -a "x$enableval" != "x" ; then
- ac_libdir=$enableval/lib
- ac_includedir=$enableval/include
- else
- ac_libdir=`rpm -q -l heimdal-devel 2>/dev/null | grep "/libroken" | sed -e 's/\/libroken.*//' | head -1`
- ac_includedir=`rpm -q -l heimdal-devel 2>/dev/null | grep /krb5.h$ | sed -e 's/\/krb5.h//' | head -1`
- fi
- if test "x$ac_includedir" != "x" ; then
- CPPFLAGS="$CPPFLAGS -I$ac_includedir"
- else
- ac_gssapi_cflags=`krb5-config --cflags gssapi 2>/dev/null`
- if test "x$ac_gssapi_cflags" != "x" ; then
- CPPFLAGS="$CPPFLAGS $ac_gssapi_cflags"
- fi
- fi
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h)
- if test "x$ac_libdir" != "x" ; then
- LDFLAGS="$LDFLAGS -L$ac_libdir $w_flag$ac_libdir$w_flag_2"
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- else
- ac_gssapi_libs=`krb5-config --libs gssapi 2>/dev/null`
- if test "x$ac_gssapi_libs" != "x" ; then
- ac_libdir=`echo $ac_gssapi_libs | grep "\-L"`
- if test "x$ac_libdir" != "x" ; then
- ac_libdir=`echo $ac_gssapi_libs | sed -e 's/.*-L//' | sed -e 's/ .*//'`
- LDFLAGS="$LDFLAGS $w_flag$ac_libdir$w_flag_2"
- fi
- LDFLAGS="$LDFLAGS $ac_gssapi_libs"
- else
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- fi
- fi
- ;;
- *) if test "x$enableval" != "xyes" -a "x$enableval" != "x" ; then
- ac_libdir=$enableval/lib
- ac_includedir=$enableval/include
- CPPFLAGS="$CPPFLAGS -I$ac_includedir"
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h)
- LDFLAGS="$LDFLAGS -L$ac_libdir $w_flag$ac_libdir$w_flag_2"
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- else
- ac_gssapi_cflags=`krb5-config --cflags gssapi 2>/dev/null`
- if test "x$ac_gssapi_cflags" != "x" ; then
- CPPFLAGS="$CPPFLAGS $ac_gssapi_cflags"
- fi
- ac_gssapi_libs=`krb5-config --libs gssapi 2>/dev/null`
- if test "x$ac_gssapi_libs" != "x" ; then
- ac_libdir=`echo $ac_gssapi_libs | grep "\-L"`
- if test "x$ac_libdir" != "x" ; then
- ac_libdir=`echo $ac_gssapi_libs | sed -e 's/.*-L//' | sed -e 's/ .*//'`
- LDFLAGS="$LDFLAGS $w_flag$ac_libdir$w_flag_2"
- fi
- LDFLAGS="$LDFLAGS $ac_gssapi_libs"
- else
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- fi
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h)
- fi
- ;;
- esac
- enable_arg="heimdal"
-}
-check_nas(){
- AC_DEFINE(HAVE_NAS_KERBEROS,1,[Define to 1 if you have NAS Kerberos])
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_krb5.h gssapi/gssapi_generic.h)
- LDFLAGS="$LDFLAGS -L/usr/lib"
- ac_gss_libs="krb5 gssapi_krb5 ksvc";
- for lib in $ac_gss_libs; do
- AC_CHECK_LIB($lib,main)
- done
- enable_arg="nas"
-}
-
-check_seam_64(){
- SPARCV9s="/sparcv9"
- check_seam
- enable_arg="seam64"
-}
-
-check_seam(){
- AC_DEFINE(HAVE_SEAM_KERBEROS,1,[Define to 1 if you have SEAM Kerberos])
- AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_ext.h)
- ac_sol_libs="nsl socket resolv gss"
- for lib in $ac_sol_libs; do
- AC_CHECK_LIB($lib,main)
- done
- enable_arg="seam"
-}
-
-dnl Define MIT libraries
-AC_ARG_ENABLE(mit,
- [ --enable-mit[=DIR] enable use of MIT package (default=yes) ],
- [
- if test "x$enableval" != "xno" ; then
- check_mit
- fi ])
-
-dnl Define Heimdal libraries
-AC_ARG_ENABLE(heimdal,
- [ --enable-heimdal[=DIR] enable use of Heimdal package (default=no) ],
- [
- if test "x$enableval" != "xno" ; then
- check_heimdal
- fi ])
-
-dnl Define NAS libraries
-AC_ARG_ENABLE(nas,
- [ --enable-nas enable use of NAS(AIX) package (default=no) ],
- [
- if test "x$enableval" != "xno" ; then
- check_nas
- fi ])
-
-dnl Define SEAM libraries
-AC_ARG_ENABLE(seam,
- [ --enable-seam[=SRC] enable use of SEAM(Solaris) package (default=no) ],
- [
- if test "x$enableval" != "xno" ; then
- check_seam
- fi ])
-
-dnl Define SEAM libraries
-AC_ARG_ENABLE(seam-64,
- [ --enable-seam-64[=SRC] enable use of 64bit SEAM(Solaris) package (default=no) ],
- [
- if test "x$enableval" != "xno" ; then
- check_seam_64
- fi ])
-
-dnl Define system default
-if test "$enable_arg" = "no"; then
- dnl Autodetect system
- dnl Check krb5-config first
- AC_CHECK_PROG(ac_krb5_config,krb5-config,yes,no)
- case $sys in
- Linux) rpm -q heimdal-lib >/dev/null 2>&1
- if test $? = 0 ; then
- check_heimdal
- else
- check_mit
- fi
- ;;
- AIX) lslpp -L krb5.client.rte >/dev/null 2>&1
- if test $? = 0 ; then
- check_nas
- else
- check_mit
- fi
- ;;
- SunOS) pkginfo SUNWgss >/dev/null 2>&1
- if test $? = 0 ; then
- check_seam
- else
- check_mit
- fi
- ;;
- FreeBSD) check_heimdal
- ;;
- *) check_mit
- ;;
- esac
-fi
-
-old_LIBS=$LIBS
-AC_CACHE_CHECK([for SPNEGO support],ac_cv_have_spnego,[
- AC_TRY_RUN([
-#ifdef HAVE_HEIMDAL_KERBEROS
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#endif
-#else
-#ifdef HAVE_SEAM_KERBEROS
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
-#include <gssapi/gssapi_ext.h>
-#endif
-#else /*MIT*/
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H
-#include <gssapi/gssapi_krb5.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
-#include <gssapi/gssapi_generic.h>
-#endif
-#endif
-#endif
-
-int main(int argc, char *argv[]) {
- OM_uint32 major_status,minor_status;
- gss_OID_set gss_mech_set;
- int i;
-
-static gss_OID_desc _gss_mech_spnego = {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
-gss_OID gss_mech_spnego = &_gss_mech_spnego;
-
- major_status = gss_indicate_mechs( &minor_status, &gss_mech_set);
-
- for (i=0;i<gss_mech_set->count;i++) {
- if (!memcmp(gss_mech_set->elements[i].elements,gss_mech_spnego->elements,gss_mech_set->elements[i].length)) {
- return 0;
- }
- }
-
- return 1;
-}],
- ac_cv_have_spnego=yes,
- ac_cv_have_spnego=no)])
-if test x"$ac_cv_have_spnego" = x"yes"; then
- AC_DEFINE(HAVE_SPNEGO,1, [Define to 1 if you have SPNEGO support])
-fi
-LIBS=$old_LIBS
-
-AC_C_BIGENDIAN
-
-AC_CHECK_HEADERS( \
- errno.h \
- netdb.h \
- stdio.h \
- stdlib.h \
- string.h \
- sys/time.h\
- time.h \
- unistd.h \
-)
-
-AC_CONFIG_HEADER(ska_config.h)
-
-AH_TOP([/*
- * -----------------------------------------------------------------------------
- *
- * Author: Markus Moeller (|MAIL|)
- *
- * Copyright (C) 2007 Markus Moeller. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- * As a special exemption, M Moeller gives permission to link this program
- * with MIT, Heimdal or other GSS/Kerberos libraries, and distribute
- * the resulting executable, without including the source code for
- * the Libraries in the source distribution.
- *
- * -----------------------------------------------------------------------------
- */
-])
-
-squid_dir=
-AC_ARG_WITH([squid],
- AC_HELP_STRING([--with-squid=PATH],
- [Special option for building bundled inside Squid. Do not define manually.]),
- [ squid_dir=$withval ]
-)
-
-eval ac_p_include=$includedir
-CPPFLAGS="$CPPFLAGS -I$ac_p_include -I../../../ -I../../../include/ -I$squid_dir/include -I$squid_dir/src -I$squid_dir"
-AC_CACHE_CHECK([for SQUID at '$squid_dir' ],ac_cv_have_squid,[
-AC_TRY_RUN([
-#include <config.h>
-int main(int argc, char *argv[]) {
-#ifdef SQUID_CONFIG_H
-return 0;
-#else
-return 1;
-#endif
-}],
- ac_cv_have_squid=yes,
- ac_cv_have_squid=no)
-])
-eval ac_p_lib=$libdir
-LDFLAGS="$LDFLAGS -L../../../lib -L$ac_p_lib $w_flag$ac_p_lib$w_flag_2"
-if test "x$ac_cv_have_squid" = "xyes"; then
- AC_DEFINE(HAVE_SQUID,1, [Define to 1 if you have SQUID])
- AC_CHECK_HEADERS(getaddrinfo.h getnameinfo.h util.h)
- AC_CHECK_DECLS([xgetaddrinfo], [], [], [[#include <getaddrinfo.h>]])
- AC_CHECK_DECLS([xfreeaddrinfo], [], [], [[#include <getaddrinfo.h>]])
- AC_CHECK_DECLS([xgai_strerror], [], [], [[#include <getaddrinfo.h>]])
- AC_CHECK_DECLS([xgetnameinfo], [], [], [[#include <getnameinfo.h>]])
- AC_CHECK_DECLS([xstrdup], [], [], [[#include <util.h>]])
- AC_CHECK_DECLS([xmalloc], [], [], [[#include <util.h>]])
- AC_CHECK_DECLS([xfree], [], [], [[#include <util.h>]])
- AC_CHECK_LIB(m,main)
- AC_CHECK_LIB(mw,main)
- LIBS="-lmiscutil $LIBS"
-AH_TOP([ /* This is building inside Squid. We need their config as well. */
-/* bit of autoconf magic hack */
-#undef HAVE_SQUID
-
-#if HAVE_SQUID
-#include "squid_compat.h"
-#endif /* HAVE_SQUID */
-])
-AH_BOTTOM([
-/* Squid provides a few compat libraries */
-#ifdef HAVE_SQUID
-#ifdef HAVE_GETADDRINFO_H
-#include "getaddrinfo.h"
-#endif
-#ifdef HAVE_GETNAMEINFO_H
-#include "getnameinfo.h"
-#endif
-#ifdef HAVE_UTIL_H
-#include "util.h"
-#endif
-#endif /* HAVE_SQUID */
-])
-
-fi
-
-
-AH_BOTTOM([
-#ifdef HAVE_HEIMDAL_KERBEROS
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#else
-#error "GSSAPI header required"
-#endif
-#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
-#else
-#ifdef HAVE_SEAM_KERBEROS
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#else
-#error "GSSAPI header required"
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
-#include <gssapi/gssapi_ext.h>
-#endif
-#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
-#else /*MIT*/
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#else
-#error "GSSAPI header required"
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H
-#include <gssapi/gssapi_krb5.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
-#include <gssapi/gssapi_generic.h>
-#endif
-#endif
-#endif
-
-])
-
-echo "configure: ## -----------------------------##"
-echo "configure: ##"
-echo "configure: ## $enable_arg has been selected"
-echo "configure: ##"
-echo "configure: ## -----------------------------##"
-
-dnl set variable for use in automakefile(s)
-AM_CONDITIONAL(HAVE_SPNEGO, test x"$ac_cv_have_spnego" = x"yes" )
-
-MY_CFLAGS="-Wall -Wextra -Werror -Wcomment -Wpointer-arith -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement -Wshadow"
-for ac_cv_my_cflag in $MY_CFLAGS; do
-echo "int main()
- {
- return 0;
- };" > conftest.c
-${CC} $ac_cv_my_cflag -c conftest.c 2>/dev/null
-res=$?
-rm -f conftest.*
-if test "$res" = "0"; then
- CFLAGS="$CFLAGS $ac_cv_my_cflag"
-fi
-done
-
-AC_OUTPUT(Makefile)
-
-echo "configure: updating ska_config.h"
-sed -e "s/|MAIL|/"$PACKAGE_BUGREPORT"/" ska_config.h > .ska_config.h.tmp
-mv .ska_config.h.tmp ska_config.h
=== removed file 'helpers/negotiate_auth/squid_kerb_auth/squid_compat.h'
--- helpers/negotiate_auth/squid_kerb_auth/squid_compat.h 2008-12-12 00:17:10 +0000
+++ helpers/negotiate_auth/squid_kerb_auth/squid_compat.h 1970-01-01 00:00:00 +0000
@@ -1,25 +0,0 @@
-#ifndef SQUID__HELPERS_NEGOTIATE_AUTH_SQUID_KERB_AUTH_SQUID_COMPAT_H
-#define SQUID__HELPERS_NEGOTIATE_AUTH_SQUID_KERB_AUTH_SQUID_COMPAT_H
-
-/*
- * We use a HAVE_SQUID define to override ther Squid-specific package
- * definitions for their includes.
- * AYJ: This whole bit needs re-working when compat.h exists.
- * We will only need the compat.h and its library from squid.
- */
-
-#if HAVE_SQUID
-
-#include "config.h"
-
-/* We want the Squid type and library definitions without the package ones */
-#undef VERSION
-#undef PACKAGE
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_NAME
-#undef PACKAGE_STRING
-#undef PACKAGE_TARNAME
-#undef PACKAGE_VERSION
-#endif /* HAVE_SQUID */
-
-#endif /* SQUID__HELPERS_NEGOTIATE_AUTH_SQUID_KERB_AUTH_SQUID_COMPAT_H */
# Begin bundle
IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWdbs8xwAesNfgH98f///////
//+/////YJo8AAnMB7e8+t9DPWeT7zyuxS0ozzvW+33feXFC77wHu56Ptzrm5s+L3w9AUCgA+jes
9tHNMKd7Onk3t0emlUZ73eWR9N9jxV3br3vue+2jj5XrPrfPl6n26gKKS++erj1ettn3Y9316eNf
fe99Q7R56zK30bVbYtuqxO6cLqqoGrprkUo1B2BoFI9Y9lpaVJRoGkKQl1pTQAYpIKSqHTQkmnu3
R3Gr33lEoz55vJyXtr28azo9h05KXuc8nu0EZZZ7b28uRF7OFry3YPb1dltwHpR98aX219cm+H0B
9733a5LdffBe+4n2+j576XN9950MeB69FH319HRbV7ge32d121dbofYaHte+TuKJ9eeqs+9rPnJN
LVgLs4711Ze73N2Gqm5uNnW5vvue9hZ827c5Da2w5rSy66jhM7aUMU7Owyvd4uHQGUvtHnu8G3UH
fGy418FOt10EvU9u9p7NRVyZ9aD2132Dq8fCSIENACCaATTQEyNGoyNEw0o2jyKnqe1NqAmEae1A
SmgQQQhE000UxT01T1P9VGxMm1TZHpPVGTTQ2o2kAAGg9QJNJERFPJinpTaZU9PI0TBFPyU2U09B
PUZN6o0NB6gB6g9Jo0wKmpShE0Jo1T2Sj0jYp6eqe1T9UP1Q09Q/Sj0mgANNAADTQACJJCAE01PQ
0ACGk1PMpgUzTITTFPTEFPSeRPUNNAARJEBAAmk0NJkwqeT1TaNU/TVP0Tao2U9T1NigAA0DRoN8
gz9uzfCZqYlrNrbUJGbUMMrZmP2LN5Njxjb5P9H/1h2NkxK2N5bIWtasKQtW1aQLEkWlZKIqLbai
SWUmTalUPPyeB5slelQpufZ3K3nS7QtppVYpVUskkWzUZlZCKZW0qtCm2iy1orFrVqSllhQUKlml
a2liJkKpSJRFbVosQjSxWRWmKJUzJBWGrIs1LUyVrW1NKs0mkSSFbJKatJFqWlrKSRrNYmyy2yyV
bLSUgGBhmZkyZmQzAePo8vT5+r1+z24H1fJ61rWta1rWv1/PE0y3hBmNGHAcYBj3raBM9rEoTdCh
CDQTMgMLZKixrAKiotKl6POp5Hw8mBzxBOPPjQbBNlLpxMVQEr/WmKt5dUVlJa0b8T+348mmtrUt
oli2sySTQWKqqhCRVaSytStqtVI1siCKotJWrRYtNaVtoTKzayYrCrSWVVSFWKytrUzKrRVJUsVT
CmWiskiNWFKS1DIRWCxAiRQDGD6mRCHrJyQXvivUn9gftz+rAOAOtf0Af8v3f9PQfF6J2kO7qmsy
BlDsTM3FzEJUk3/yRgLZxj+70fUCCgNaFnuKihk+JWBXMfXGgQVT9IK5WsAzROz8dYF4fa7zFcWM
v+eeMo8mTjEm8qObjDjsOMHpfwa4/tdsbh3hjFrxuG8DDYpiWuDAtG9+OAXWDkRwCBHrey6uhXAk
zgf2YLLR/GxQOowdSBhdjNH4VvmcL0PhLNX1PgsgCGYy3H2dm2hW2BWTe5NKqtaUsj4v/Hvfgv4M
73j8IfGaQcIGjt5OWLCHcQ346HpB070FOwkfIQyETh2oIGbUUEDuIk9B8T/n9/Zct6IW4bbOxhA7
pg7p2JEKMfbdLH9mJhB0g82DleVZB1P/n8WUmbw4604fe0A3sqUmh8XZ+V0Bdba/qjoyhxKEo/VI
IEM2Ui0LVBkMRZJGbAoPj+/y6dnVhA63C4OmWRtFmxLd5ECLMyyhnDuYEvv+XZm+lxS0Pcep1M1b
91qpzTgPhO4PxdfZfLiLpfLffu4ihCvIUEbHEfHJ1Bl7mAmNrKVo3HkQmqBOztZU3Pj+DiPPWcj/
KpUnHB6JZiQZHR9nHO3MZ+P1a+dNPhfp+j6qoCyJSBI628P+z7NJP1WLRMwtpa8yYwlcMMd/J7T9
cyPl20uJqW4Ym0h6IBz9nsxvHWHCGrC6wP/K7W11qV/Ziaci9bEm5M7BqY4EfQ0w4QInu4IHJ1Ls
s5Juz4X3O7NCdH/l+KDaNnt9/wUtZ4EA7uzuP7JDGboPKdRgJZVZDfiSFUypDdDADIVielKaSnES
osfS+jRonw92+HXD2MMVJ146dE4do8ICMjKJUGR9tKPfar8uMxWl08WicXSq3qiDlzM6U6Ea/43H
cZyrpczBBoN6ZR7Mh1ni1E7QGGcZwePpal59NeEZWjH8wLDqPxiJzSKduqlYFDnAKnYJbSGTQUXH
JKf7/UeEe2PupWRL2rwaxvuY90oRieUL4U9lv82/PPqP9Quf9v2+vntc9+OfFbxdO7OsRFRb9uoy
qjDb/wn+tSAvzZ6fL48ydX25fWl8WxVU9T0T5/k38mvUnttNZYa9H0bxNHana4MiqoooKL3WwT+u
3LWLOyl/JfguCyd2rFXVN5U/PmYKO7+EwX+qO6pH4zEfwOXDlJyzh5/tn+26+Ihsu4KcN2tClpRt
LH7LiH77ri/J2XT4vT7y9X1NpCsWRYo20QtWfiW3yT1OZSdEhMkkNyn8Z5lvh/47mEOj5RELl2Z0
cp12n45hBiDu93KF1mVKSH6OOyLndat1wH8PDVfdPz9jTnb4Tv/IL5n/0/7LfeN3/Fx/twkf4Nbf
SI//BOlgfqleZSbPgR/MYuHP7rX/2V/IQT7lF34X8j3K9vEZhOzi4T4ecSLylOTNPh29PtYQRYYT
AzFtaQQosWe7oMkJuLdgj82v6yG6GfKPPCwQzeNu1ksKHNVIsJ45fzdRwipeF14cknPIRmmahMQw
c8E81WHEdYbKGY5gT2meE7O7WgQGTWsu8GeqcddJNmQ6Mzt7JZBQ5GBVEUKIUTRuLpJbCgUSPMhd
IwXlma7/y9DeUNMqz4F61rHAcgokqiopRRMj4/l8/lP0djicfjobIq7E8IpUD9p9x8zDfNMdRlXH
M0IWoKCPp/19cEfUX6h7RxOcDyCUPKVBkGLHH04UaDI/Zx/DH6e7r8XFOnttVrYLugz/WluIyqtB
1eUOYxdv0mTvk5D6cEL2RLQKnjhcU76Ez9wwPOImGFZ7CIZYbH6qK+4HnbOqxmU9EoJD2YogdLFT
GVB6zlWyKUrzc4q2yzD22y2ZnF6T7zvZkMx4xKTzZhjrfDreN/OJjbG0aFsVZFtL/fw5JkJt0LUz
F63S3jw08Vrc+JtmDtingoLfOSCW+/y5G3hh7iuVc9NmWSAFRWQWQebAku7CFahJ5MCBisgsixVg
worVs8XWZ5bpR+CdFZKiVFbU1G9bM9ZjyYfCY4nHJo6CaJJD66HB5coLFVj2JA6IrCXWaxawIi4j
34IbUcxSXbuIErTA7o1FYLVPJCfESSzLTxDrS1GiIxjUZwPbtqnSaplKNWPM5maGE11W2Zi8ZTYU
tJeMIottqzEyHLc1mad5WM6c5nDTesMnVnSGFTMgbLg8K4GZ9uYp6ipzkxiqiEOrlKJh7eCFGFqV
ZrDsXeIW3hBCRsfMzmB2JDI1G8xvZb62lFJPt6u08WCrTbZ0Dk21OLNUkp2meFKMQqiafD7ybqqJ
IO98U9IcSnBSsclRHyfX2FOTcKxL3Eih2W2wcUp/JlSV234cNRZA3VXa8jIhnqY1zsuMni4wzBR0
zQKooej3cssZPSUKqKH+m6l+/PomxLbWlmtm38H7X/R4D0mVYLZW1iyJrbVo+q2zhQtqNKTbJYTU
1mkWW0oKllrUiW2lstq202sUtFprJtsmQ2hWZTUFtktGyysQmUpkS2LO7dtbLNoW0ZNshtBTCZkk
f6HcSM/u/Zj8/Q4X+d/v/on/LU5luXzm8Q2HjAGmeFh9Jwz12S4DyPf/Ap02VzcUqBPm/8qDySHD
hhchg3hCDqWLA/89XQH1G7n7Txl50nri6LtwcqpXirhTl/yDL8FQ8RF5IKaAjdH9xAKHcFEEn7Sy
p9EDSp/EWK2Tuw/UrN/UOsbQsGUoQPyC8seXeECjhJqleOjt8lxnDRKPtZUJurksYplnNVBfK9RN
pLGSPLkuOc6Kz8GnHuB26VSlCyyMUS/LNyWD4QKQhZHI7wcGF0YwZAmnGDMk0BmPxPZxqSPvoBh4
UA0xYdkgkNp+QZneDChKU3gE/7Y0hzNcutrpxiFcay1q7RQnAh2Ii4wwwv1LqfxIBaQimEUwIjR9
dabqd0TgZDZs1UuzcWcyeYQ8ecKVfb7aOaIe6ZiEMp1gZBb/WNijeh6Qg7U76ULnIhFt1KhEGyGB
kx7lq0whqO3jH4jF4w7C5XTk9X/aeiZO8e7tjhdCV2Y7NHX02dc39/3wjY1ig2IsBje/EUxg/Owc
/2yriHDCi24xiXC7iEgDCABgOdDP20kozUZ/JGWB4B2H0nnfbH3mZMMBME9aaKJSCinpBASU3E0G
iZPRrRkRSkUEMZJOMHF3/V+uFwcWwZrv39fo9PmYmH4P8vuA6g1I7Fi6j8pCJN68cYG0PvHcPRjL
sWHGDR9qAnha5ynAiHsTukirtsI1FQkQabVtqyWoU1CsUagVtSq1ZRJqKSpq2USNlZRWYUzUymys
ytlEA39x6e3syHZS0RIWkYzjvNJcqHfiqKTEAgCVc+ufjimWplgxuf4hHlAAIQVg/zfu/nIGj2n4
HRXx+qn/ZH8TqP4h1Fxqb2ROEslLFbqMjungu5MPavaSxjF3vTPh84zLZJsvMXnROIfVvN4xMGL1
E6Kxi8Zw93JmqVy6p6fFKSS31FYFF3UrbMdc/4T72owmZhM6TuzA6YYZur1ebc+7ofaIvrKADjDH
Ln2eUPUO+oZ8DXqY+06/gnoX1S07fb6u/Do088H1yVc3Rb4ZodvpybhtnXyOeaFqIOfs/2Q6Ok0d
ctg+ZNdeOYbhMuXSdN0I63w8WmwZdnR1tzK2sU+UzabXEAs7e5jLs0axBbVKgpaVJoWhEGrypNS4
Zh2dGcbUQtYdwrcfcnVXrM4TolKnYSQh0Og333wVRhdLaiHhZTcKEVb2m655uo1N0jSDOOeC6zrC
1qieH4xVSDohPvk4bNcpc7jhfkdRBW3dRw30ZhdTjnCCzSEu0ZIM83M2Sw3ltCG+vxcW6maU6kV4
S1F5w/vJeFrENZUEid84WIqal7WZsqlcTRKxVWXjBKeVthmzx0fLyx9yPTw0DGA8Hjx3zPbdfn+s
2T5w4bRjM+rKC1Vpz59HPvqoULahGO3tGcsa3vHHDzxp0Yp3T4cJ1puLlVK3w/CtThzVOQtZLjjQ
ogygnW/o2Ma0+jXK2i4fjJyQxm3vlTgeQwpFenM5i2iiDSuKEIjF83GaDD2vyORucLkHEYSMMq3k
8TT8+eokfvzNG1WK2+Z2A33+uJr3byyZsRxXfb8pkYH7Rxp+BArepbeYlupc2mtYR7HL6WPDkpbc
HWFCNS5qLxLorLm1KeXEhLhXiMy8uxKwCajOoCtvKwiMONSvg9aYbmc6fC442W/KV8zdbG83hc/d
49dcWyXK9C1PiCO+1B4EVly15QqfPnOM5vSIGMvwwIYSgp3EK33bOEQO29PszkgStUmwjahGMbis
OWmnL3O9KXBUJoWqcbCTvD3q8WYzojapD+j39dMxfCOOutTtHC5FkUVej7Kb8a2jxeohHKOEMPbn
ExE7iZNxmMU5apRLnNWQaTZVJ1GDMB9Cq3mpXjx0xq831OTjeT5ThIp3+p/i79SWu5L4pc77JWfz
vf23jx8sHbvIPhSV6tt49PjNVxcc7L+N5xH4+Klsrax8RFO/jh2pK5qXcw/NKvCympZRD6ghePs/
FYMKNTR+WP7Pn8qz33HmX88u0dOQkvKxkcPEQ9SZXn4+GPbeMZ12RvCfDpcIe3MGv5m24u79sAXl
BiJAS6+r2NAJuR6DLtAIq4G0b6DtstjEDV1qsOYPN7D0hBbLp9BX641MJZkEsIUcpN8UwyC/B3Mi
f6sRfYUwZomAwaVz+gim4O/G8/83EK2P55ggaU2UxpDSoEJ3AfBi6jZ7mAPKGyzJhB0I22oBQCd2
M6d5zDDEuYYFo31+5KsKntiSJXTFp+WpmjfBK/neS6Rt2stYGGLZakr8348Zq0YDc+qqgWibI6gh
boobu79sEDsC9je9fcZb9ftnvg5k7K+ZQ5wkuP7KnQxLmDqqVkbsjeyrWA2wcaWG5ifwGSY/SpG+
W37Y3l2DuzJmTUb99m2opgqcrLGqRA7kxEa0ZSOTA1h7i45nyjJv0Fm5b4eFQGYkw7CagzfhUlpU
ZT8+ZX6/NQWDN5bWP8Tbxek95Y81+SxTjwNXa2Pm24vu6y7Y4Ha5EzFmpRFZENebQV/VTFnz0l9S
fGbhmpOy/8UeT0Yf9/Qn1nsdsq28FsL81rRsUVhQdH20N5MD0c7gZdzq3xkHbAyNg6rJ8T/YdRvh
rdVjhbiEIECEIMCC5Sui8JV0//GCkqUSF0ZIIQbgrKxkDJqD8uk5HCgaA0BGPNmYZM+pEZlgkjh+
YpbfyvtGayMrMe6JehrPaJj15S1SBrGH82OdOv9fBrzqMjBqiwPuw9UvRhiNYdDeGn0g10idBzRS
mIaRwNtzif3scv2049DrTjTh1LpAZFiO6RgPiNmWjslHlOK7pLrjvTJwahcFQGe6hZ0jLqaXb3vK
JlcoP7h6cgJBgWSOrLOX0kgoCPgcSkTnr4RRK3OQmRS/TJinHM8u9bcDN5fqe2V8OSG6RRSIZwvI
T/DVS+gTDNMzQaOzJGg3T7GZTM9HrzcOTyvsPEhBEgzMiUSP6O5+H6Hf9UX0KFkz2vnH7xkgzSZf
tzsNPPWH+0wPZC2W7r05SlHu7IOUlaUduzvtIL2SKhG6sWjA/7lFiDsMdnx/B6KHMTJyYfu48Jk2
cV1x3YqbMWGHZjxHOogP92PNm5tZY0QWb2sI7/nf+xiKC7qJ6F45bPiN4/TrswRGvbtY6DcMtUv2
fK7PvmupqO9rNUI/b3H+WbI8H2wP+v8N70gdmQqYo07Hopu8TiXJz+X89VYkMe9AWGU3K+mErX1Z
xxvIhfWGRCvl3vYRlCHu/M1Cz4q3pe+S8KnER9MVv+y9Qzp+5uezOK7yNBOAxj6XS79+xrmbG5Lj
eHfUjz0eEvJ1066zCai81mrEYGByms+/D+RmHsNFOhBkUjFzhSFAiSKvw4ea+fQxPeTuczycBW+w
8ww9d+KSJvzir+6kPQXA3Du6WYdRD2lvAKnHYiZ3met+Bb5w5XzpxQCcf/kQ801oRuvaeA9Tym5V
br2vwUKV3C32fockV/zj9K8efwPRZYNw4lSDNbkA5swolbF38pEW/mkkxTh3biuF48inXT7qriWf
6SSzPBfUXEMTEsixgmLuMVrYiyA9kinLgu3ei7csah/gmSRwYIsh5c1+CneX8WQ4Dp3Z984RLKUy
gUlGM4VSRRJF1ouN2xYFxf5N4YEdd8PykYmi7MbYBHZ+Bc3amPAbBxmyCdL/Cq8qTkOLhBQ7AwYA
YDUe3ksIJW+mP9NQJBN9knj5/d/W8HGuQcjyeV7O6v3vR2C6fVYfMj65lmLKm8LpPJQeDVT/xY6+
G66HPYYGSergToehl7bfQkjq1JfHWmikMKEjSDDo/QQ6nk/pKIsv8C7pKsXx8vRJJR+hEfe7N+wk
fGfDdunhPrbmdjU36wl3OM53880Hgy6xyS3P8RP8xkeawMfi/07umb4w4fimuKUcoRRcByo/DOft
s2sjrC3sa82MKMJqg6QMKV0AIMhMCX1kiA4e7y7MJ3bGl4QPkiXs232CmjG/9xwC34McIBg2dl4u
JM5Rs5DDByBhd2QQL9ihXdHSQMwk54idkEjH6vgibLmknFMDRoMPwCU5EwYRFGHt3BaZwfzYp5jD
ej/KU6Zp+c7OuX3yFrGARFiUi0WGyLrIUHUDowJYKKKKMaTaDiZdT6xDzVICFW6Jd+Pmby+HeU3x
OxxusxXMaph3iZFgW1ve1m8vBW+Jdar5GmbQeejIEk89ZTHt7HXIp7y6G/XVnZP8Be1px8W8K8fj
W/4Qye2ffyDv4ejNPwdV/f+6zyR+49y81yuhE/QQ1G4X8cuyvvu2UkviWKw7HHOTdghjxZESWY+u
UpVForeBz16geaqY/Xz136dQ4lvCuGhjAIpEiQsvpMPDhbUebmcjZhYupr+MCFCoajFIqMhmxiiZ
Kagkyr2lIkgl/A+jGZimMhzxXyqRtRwtZngMYS+zGMY5QZDMojpskK8IQ8fg84yYg5jV/3ttOPh5
xjFrGm0D65RKcu0SF2gylKUpSklKUpSlKMwzDMMwwweg2SkZJbBged04BqZejEmuhAnLuUeUJyNu
J95CVSQZezWFV/CYQRWxmJBeMla8ebaR2YHoImmdGW9LUWh52dXqBC9qhCKIk7PrDymtDr7Py/Dm
1PzXMKKjLYVc4/e75HIMmUGTMrPqkRa8mHQPiEQiFhee+I4wc5igR7178p15XEzqIxnO1uzrG2KF
ovW3VWgeICFtTxlw+UeQx6NIu04jsMQ0jFSqfMxQzGpKwhax9GHpNptHvn+jcE+T+M98bcwna0y3
uvatGMXzL4hdGHC7+7ZkstB7M2jO/d4RQTeXjqa4E9fiWzWUznviZ47weN9W2CMmyOYhxUuh3vfx
3/OzLlQkUKXRnwwIETvvNa8hJEzvjS8431JeTLKFNgtcXPntS2EsjcokPYyDm4k1YUJQ48RDR/Gq
t82Pf1wjHnQ0gUcj4Xk0TtLzAzjpuscXcyu/aQYr7NH06nHbDdbsdLVA6X6Gi/CiUnGVVFTdG0x8
mYmy0FgC02P30NDBgR9xSpA+I5285XhFiaM7iHp6nzKOGx1XkM3DhOhMieFsjE8unMrZbN7/KvRs
sdGlO/af3N9395z1ttFnt4HaBtDyaEKy2VpKR5Ec67zGSu3JF+gDMJmSZkc+ln4/jfefk2z401Nr
KmK2VLCEUkhIhCEFJBVkEcI9OvHDxyrErhNm0HA+c9du2u44shP4+8/HhVWpJJFhEyLhF/Zg/MH+
z7f4fwgfwIPk/5Efykp0d5fxg9GlGko/l6Kfy/WZ3/G7ofsbGkq+72/u/z3NDXDeOrD7kjG95v8q
21817UkXJIrHKZiDrMU7HJEQqrliA6oqiOiy+vJ9/zP88+GjcVQXGKIIm6VFeA6IL6PoTlgwzEY+
mIiIMQZMyGa/H0Nm1WzbrZm2a9rG9bQUq00LS2tr3SXwnX29/fv8FmQSXU/ad/Z6Tr2LxCLdN7oN
WcO2jnGfZ3yptXJ+cTnz4Qqxe1nGHIpdKcx1K20+Q4S3ONX4w6q4xnZpv1SpcdTVpLPlTltxy5vn
DlyG44tK96vNoXcKNQpA9CR/VkLzYE47OH/de4/SePgk+6I4FUjeQIQcOwqDXnzH8P9/61bEiYyK
uKGPylPqM6xACRFX3dvL07es7J2XcnV1dmzLlu7ert6c8VPsVNnSQ702qlKkoaIEYJKWm/kzy282
K2FrYoU0eibs8jbrKOm6dsg5bbbUMk/1EBKFD6xIvEMQ+IdZ8bjFeMYIFLHo/2Iv3t8PRh6abf+j
mH3Y3mLWYLCKDITvVk77ZLaoUZ6/VJCkzV2N72E3lvJ3dVKK2onVu3WoCWCy2QJFesjoNmg/h5u0
+74+Xynt9Hv+jVoDTGE1KlontJP2BWUCx/Kwf0ht20JwA4mANbQNQ11IWXgWKgVLfuBD+CHxgmuB
GPwMoLWepnQsYBispfcZ8tSOailAhcd8Lu2slU7R0/7ki+ZDm09j5X0ZkA8hYxkgC6/4XlRERkyW
iRDydCJ/Pp30Rz3lmPSP5izP7+ON0VMQVWGamR4G/pG20GsTpBeoLZiGGF/gG5gYlFmkwXRCEGGB
Fm5eQgMCVjFDk4als9GZ6tBSe/D5wYisTljKhYx8uhetAaQeDoRogbyAiBNSB0NQ8QVJJJAKRIC0
jB1gO0JseVFAacuVG/8ysCJc+8Z8C4TkksEYmxHpxogbnNWThLDJEqOe43lCbAY9DBo1IPAI6Qux
4QOfgJmomrAAvnCQNkTgExlibdaOAnFOcP+AcyHmogoTO/wE5HqUpnWtlk9HA7ixlB0tpjXZghoT
f0+kCYNOSEAzg4eoYpGTkgIr6Pz+igSJBJ1joWn7v8dfa/fA9DXj1cefx/V5xr4740v9a2PCHwoh
nXc07oKf2d3XCazGkOpmvsnGyB1PCBSL/HTXbGwyNx2XgKIpn/IOP3/gNdT9Zpo2Ybu4UmI5TRK1
ufORMNBWHY6KUYYiQBgIL5rwDP/zuBOHuNZkR2ZN+rkmIP+43HRMVpwwkcNTbsi0EEWERGElE8IB
YQYY9Fm5ifMxJlrcrQ3u8J0/C1aEO4Gri3svhC1uwI4MbDRZWuzMY2T0UmUUq8m5+fCUdGnw/K9T
tK21P8cj/pfPh/k9bvjbrpv1bU9F3PRLZH92Nbxy+AGwzfRa5C57dqa30mS2/B/EY39K+u5/DQYj
7ofhHHPCqlEajr9AEDP5BwGG8yjnaMLmxXXDCzkO1IUidpfGnCakRYd+52p3fosD1NsyCjAMyU/s
+GxwRLi4tGTWuCLR+5iwwRb3tuMcTQoHFKZKY1xzDRb+r9KgxsRgyrEJ0dCxQwYbDY5Xfvk2QKHN
B730YOBEcvVrMBy1jnLHGJvfjlo1OrTD4jEb56ThCG25lDQMdKN7sW7+Ftu5XODLYr4zXok8knFq
yq3KLkhh7XJRLYwimHteHhvLxB+D/XUtS1+CeRKdxGszF8ce/6KNbw6WdxE0JdPczDx+EEC2phsu
s4mXHelDqBRx+Me6Zbm6wYGZlY0IRjHGIYsXIzuXPG3t9bGyXb+no8yHy8IRZBEiH0VTAiBJIkJL
bucN07TVpJFT1sx6J4sftsia/mKmN6a2z9hTW2e6amyySTSQNt9Z+rA5N6yXeG9GzekzaEy3xrbe
WzWmHkUeLaTSXSFpbmFYGamUplRDCyQh9bJBD3dfmYbrPweDHpioskxXhYgtBIYS/quXT6K9uEuD
Y4sS/v6WCJMdLZv+pNYWkpB7b7l4IvPV/uI/GVMy1KGE5W+r3xCYmJ+berYlpu2pgW4gyiTHMbtb
q09VT31PfUdc6ncA/UtlBn/H3f9uc+fNfQR2jlfmIj5lwJFIvBXZnNjlrqno0Vwg7ROKrpF6vkN1
fjWMuydbKwC7HRB7tAJ0Rv3+/WCndnZzII8Qa5lpseWrNMRiqNxmCwch+hQ5jkEDW5UTAo8LSN0c
f+7kZ0Hx36eG48hTM4efUBBQSWSfHxZZ+LFLWdRxD6QYHlgfMWZoEj53ZfY36Zv77d4EX2VyiQ16
TgMDSQP7n1V7Try5jLU19IVt0mRQj5ekq49Po4zEr7O5bbpTxWf4fwIklv0n7R+msMAw7FkWasBx
hTbBnYtLWoZHoPb3RwcqHX7JDBaN6KGXezOdhYDkQdsD8bB+WjNfG/HxO9QDEoKn4S8O3EcDptlM
HRrw1C11q4TiSBzIQbmzyMLJRCsJKq2tF5yxYtosuB2hso/rDm2mDqkeMyzcge2MizMDG8Ytm8jC
03OmvpORSMy6Gm2h9Q+h6teWJajh7sOS3Di1URa4cDPizDMzp2C6SkO4lSkmfylYzED7fkCX397g
OBJgNRGi2QSOPP+mHu/Rl1qCQmj9JQjIwXoJWLFix5CdU0Op+bv+syWfLCc6ZgUC/cDcKIEIJE9W
zjkb12f4s/PVrEYbkRCMQfzaCnXiHYT5+CSJQmAUMPn1bBYGIW4tijtBdppRKBiEUfSO8YAYqF7m
S7toPoU4BkPndf3/sMkDAujhhzQ8kbdRL2ENlhMhKE/KJm9BDxVKE3USAKiKFatKACFFWhgCY8Hx
FHGuEhH2fZy3934DdXdNBj6honFhe9MfH8hoaH1YHYZEIO30NaVIxY95fE6zYJL6zOc7oQtrfZng
WwqL1DODJeAvL6x+wG4Q6Ofq6OidHYyQ6qvC+ijr5VvAJLBdcQozWzslGbRZgGjr8e426zgJB0nQ
90V7xxyTwaCKqYkKCAcJCQak5FU7u5NU7iEvueSAQ9W/r99OVmFOp1KW59GeycXN0Xha6WxYosfz
5BvIHUtlNQMldTgNMKIjAgW8gYKgJepZ6s7iXvC8vDGlSFwRpEW/ZH7uyRMjYtvwTfxEGKIMIiBv
RR+O08UMm8f3Prf4/ahGCFSSQh0fG287zqVbqzn7RozxG8jVa2lhWUVQlVJalUVVtLSkoSSlNNNI
pIlq1MUaSTJaTS2KAoxUEWMRUDu9HEAh3/fr4PP1+w1/Ld09fZ4ezPlcPlSVlPz4etJA6QN44R6s
Zv+B/KaNPzc2P+7IeEPzlCSHs+E7uyhfqClyhUbQrr8S+YBbS220LbbbbbbaW2Ftttttpbbbbbbb
S22rfV4/a+r0dfTrb4a7vD5D8v5unm3rr989z9t/y1/Ka/2H6eCMEOP/L0PEPir/m1VvnsGCaw4w
kaZ8uPTMFjMwREYHm7jGb1eVOMgzaTDjgUphEdIDIMgDeK3grpEaimKGfTxGVxe97RlsIGdYQCQB
KZq24MlhknYmutnCAsUkxAFJWGxgHRIdUhtgB1SaThCdUkNJOxOEIKAbg1BdZIKZwqCOEsQkkyrZ
hnrkj/Tf14eeV8d9tFT+tDaCfrZJD62niQOSFBtrW3IMPnoeYnDvi8rzlcskKQRGp3mSFPxngbxL
o3EOhpUIWBm2II5FgpA6kEZmCtxESljmeMOcDn94O7xLFmYT77lpYtBiX4RUOs3l3MC4356XGRMg
hOaGEAziSNAcP2n+4NwWd353Rp/VBTkHuZGLZjkt2ogM+SyrsNHkO+DkmjG2pXebl2GiGYNDt7En
Le56wZQM52O48g5Ydc8lc8mhAwNTMC/q/2UaCYII7cupmUC2x4npEvmjYeJicOGJbgZYMQejl4i4
EcBuVoiAVKCJKoUL5kjTSw96OfDYbiuFrVVtFKOpvN/Y49NEEcjEHkVpqXoRQvvITugakIhiLXWZ
uZnA1pjhXVi8Yjr1nQsJc6WboI1bVExoQyMUMSCGwsnuHBbR2eA7mUC6vTvJLDbYQx0MIY6JiAQS
CAihERC8xIqsz0X1sVtMba3tcmZCBmwoSoCRUUMqAAMIjmQFzG4QtVTC1am82GRc589prfTIEdyw
Qt3doMUoiDtIq/liCfi5nA4kMw5nE7HgbToX7ETiaERy8oQJB/cIiSNTEJGxablCTrAwILMGgcsR
/x+j9PtgX5EIye9mw4PBI5ydH5f1CdS5c1OxvDFdF6vZDIT9ME+YdxN5wE+z1/+//X7qX+a/Tv93
9X+33nOuNa67enTc3rnXB1qwxk6//OMhsE+9Hqh39PxMRfhAb1V/hO2GQH6SHusGc89IHW2dUADa
GkgAuPHX3erUDEhM5sD1wQM4EiIYY0AYEVahrFNkHTLZMEcZqKzUVgGbESbniScTkvhqNxFRmljO
53Eq4rCt5tkZm7ksmMF71e8DsBe3ak+MZKgxDVOsF2t6mkYjWz7BpA2caTN1+XbYTCGQjuvtvWUy
R/LNSqAzoprEs2NWxuDgIbx+aGKEvry1wQzm2Zy6O/WziJsq6lkdQbhEM5Ayh74nke4hFRMmvEFX
LqiKUi+4iQgv360Qvnk0irQZyQGaQORgYCZR+DFh6zE2hbIozu+zGBhIbGUtkrHLBtUkOIYQTVNi
RcSEUyiqITTsrAzjGHlYbBOIUE7OOzbG0EWLgRaNG3QrJMn3HR5vsbwOZRvjlZsoOmGMAgYb3jpA
lgNubZpQznxTh3DMwgBnoGVICS37I2xvOuXifXv1Pgn3ePDzSzOX08c1Tvxo9vh1EG+OfW6r8/Bx
jGo5jqWGWWWKtSRuQC4fbfcLcB1cxs8XjIkD7l4K5g0o3wZMg3A8XW5QmJR2vlYterFIQHKkATrU
GFmeaW5gWQNzTMramZmmMs2WTG7F4KjabxQMSwSeAkL9il4wOZOkHAQwD0JjGR0zvoGJk8CzJAhQ
iyYawq4QCPgdyizC9V1JUtcxRtiM4EcidCGJHwgPalp9HIzC8xJmRyAFrqVAm2Vo+G8Zp4nMgZCR
7kYhQUhnG0R2hx40HMzL33Z7MwsYgzX1vIm1BwOZEsIC4sknYXMYsswhI3HRmXBjeYSVBlcGGt0K
HGlgjgImFqAsGkxyBlipP9zFeBjhEW9xlSBxylGWL2XxlwaZGF0BBeIHxZx4og4yJl5UgKwuBahD
YJHM2IlrW653KKQzMyxGqkINUW4BE6I5GpgfmAQuJkSHxLjiaheKJzNiwzCYOWBEwJkgyN9XLIEb
PmfU8l9H2yYHNmjkyHRj6kiIImZAzOattBkHYXgsV8+2ijjf1HUcmgxJ1V8YLhHJVKwwXa95GCJH
GG5EzMUmIqoCUBiSfEw3tsCpJNCYrICJLuwxkZr+rA8SVrjMTS1D9EsDxfF5dzEEPWAWFmrjEWsX
ixYV1lxipz5V2RFu+HxE5oeDhhr76gmHHjS7CMBtYGO71xbIIWF+AJkkRyQrxgXYx3pwNHk8aZsD
CL4dozrkm6k8ktlmT0lWrcQQyheAijCx66MOxRlAzjDbQxEpKNpYKvCgRgbCVORkZnrL6ZUGeenh
3cpsDAqg5PqRGQr4+WuuOBDGWsET4djwKxMekzc8gIdtKAa70XRtE4GH7GMDnRxmKZjoHHEHkwfQ
iw9Gjs5MGcThxlvwrKphDIxjpBvZLmK0eBHeWpg8eIm+5mJqXAvR5EOFCY09w/E7ndLX76M3aPEO
LwYOmlrNk+0EsdHo9HBOiTkwYN5xIhuUpd6rfcvS1qDmgjiJQBtC+IJqGwKehu6NcIKAGwc9noPR
HKYV9RkWq8ezgw4xgG8s1NeCLDGDZvDJasjS817kOwqdrdk3BBqWJOWCbEDmSDkl2MY5PVcnp9E/
h7lnudHgmLAMrxs4KCzzcRC0yKZR0CjlmczOZdQxM5+DUUjSDrJPcjdy9448sxwMEks5XJdnB9qC
QX7GdY4Fg9p8RFwTDuAFJQa4EkREkh12OZFvi5QGKkg2NgkMdhmUkIIh0Cw3OhIsKDkS4kZBUqTL
iJy6QKFDA2EOYl65kDtgHEdZkywkjEyOosGMsq4hcWiC8XRC+wR8xFQXig8NOPI6w4MGXDeE2LAO
QyhpQ3OzrTGKE2imJ1eopTejQVplOULp0gdMzN6ZgQfWpxf3ziELdFmJctTjW0PgVizjNUammqc5
l7QbvL5ytXvUKnRmSiNEmIvW95mJFVp96l1zgfkGX3SfTXB8TmdR0w0jN2fT8KxbNzhM+EHriyw3
WOhOK0DSdEuzGgejwN9MmQApww+BqE8mRHoxNCOE/M8bclF3dvIeyYbAwUfj4IKLxwudyW2zkcho
0cxD6mZYGhYXBgN9KztWDF7aM+rlY+lDc/SZZmLLaesjENLNL0HsbJJydHo0ZMls8ao09FFVXj3n
xgIYUSe5ySfAq8Hg6Oz9J4wNilTwNMEoG6iEwMNJS8DnYXLbF1+N8lV7D/MjwL057nUiV9+MPw1M
6v3tmIpmWk4wjkkLyE835PmZEU2cvx7HR1Nqkb+CryUeAgYftNwI2Udjg0YRtQbdIVM7OmPfQOXD
bbaFx9YCFeHpSoaNBr4TTEDAAWZpBmuJegRlvLs7g7nl38HoiFwW0KGNl59MEvk6zRXRp/Zujk0W
dknec7Oj41wfqs5XyAYGNFAvOJdoWEiAVNDIKES4+z7EDoV6W4wYBQ3DEwLiJNhG45QWBqSMtihm
XFSBcQmVNCBeNifNrhoFwYjGZeYl8DylUoS8EUMCJh5AB9gOYBHS1kXJ1huEgnSJqUNni4wrnCaZ
uoa4bfSXOlso7EEOMNHmyG0jJkzs5YM6ZHLjOkIwpEzaR+YotaSfD4wt3p7zi6t8WOYNxES7/V7x
mZeh8vLzFZqM4kjLxvGYl6LEYNbl8ViXMxA8ORvWswTp7g7XfY3LZ1dRnXPb3x8r5551la254lwZ
iJmG/OCGbnJ23Ki0rm0LXCzQDsIL0UccgiRYXjoki1vHOmpGDakwEGBiI1li0tb2jR4yxg6GZNsW
IVWAHbnfhutlaYqhc2Uh8gddUEdCribArGBr8Xb/K5s+CbTHhKOJ1UKJYaoBsHtIQDFEVsY4ysza
by4XvTQmAmgcC6GETESqciOzKisC1qI6kOipTliXdktsQRpM47g0YJOBwg+T32ra495nXOBQ80Ud
8jEtPSmkKIYA1mPlDAaLExA1sMzwMCOOlKMNJnEWx8e8+Tvv2NVexEM7aJ7NGCvJXssS/pY0nfA5
4Pl5Nmym8qxHnzwO/R1d2s9Oh0tTZd8Cb1n0XzJWCK6ncIuIGRsU0MHuUDERDERFsoPndC+2D+EJ
N2MEsx8iN61phoJ6Bcir4PoWDmRhcssXsMzAWe3DIss3Ct2I1uasGC8odyCZRsxIBnN0ASHMziaG
pCzczXIIlhvuzVVxefH3H3cEnJ7Em9/MkRJM0dnJ0QbPJsRwBgcc8Enos+R59jRkj8NbOCLTLjVn
v6NB0SUJi0xLQ9iA9QjPkLwFog7xHbsIkltrZ0Rpj7U/HGFgmBz78+iGd0OBNOMaeEQkJllFMsWv
krd4hzdw6iSY9zdId71W5fOFqnKHqdD1QgVXnFlWwpyngzBrCIj/RqxfVmY6OShc4h4+Jfblr/Y8
N8XGhMSgEfO0x9JzqGBzRHfnTBqsflwDwfYeZYNDCYGGjnsqJGMOj1+LxwnEJxn0MCsA9g6LgOgz
7WvGTDHk47PkVwhxWvODZ6N7xg6lmBzXHg5Y9U1R2eSQgXI4XHBDM6yTD/ezFJIAOsjgwfZH0EaD
g1n1l9P5J8HNDGgz+jTUMfMlvyN1G18HrIR9xxaO5ziTsUSjfZW3gKyKJ5MN8islS4hw4HYSLS82
pG2tS7EQ97BRUniGIiRHJZF5Q50Wdm3jq2Gnydu/048FsLg1DeGNkBBnOG0d0OlnD5E1ib0QW2zv
RBk44weAyOFaZXlzZc21ga0c1qblpChLcGoWjOtC87jYlJrnXCDXDl40gZJtCZvsAK8gFg2EMCiA
YmaGhYI4RtNQ7KA4dYqXmRaEzUgPIIGpqHtEETINihYGhqQJnA1OUAUyAYBAY3KtQdng4NGiyizk
IM9HBySeAgOAk8lFDEkWhAKkREQBeoKiOgg7UglHuFehcGs1xIYNCcjmyZmXA3xpEk0RiTJzJotA
dk0NNvuMQUqrLxnSVaxUzUcYjOE0kZe5eq3d5lVCzETsiFSiCafe3xcm81ptXrBJeFCN7nWa3JVc
S3trnPOc8nCLYBuWGTUMVj8FlI4+n6njD61xMHAqPAxJZDjqBwr8mbs7PxGOOENM7ai/lGJDSF2d
pgaRLBHMugVC46Fxhir9Mr8XTNM6yCBChURqPg53d9x0GsLt72e25isMI2jStLIkHORR78A0G6NE
meN8bwWbGCLPIagIKLyxgSUJmQin5YwAuN8vCxlMZiPOhN3XAiDMRjo2SXfkj3I5DPJ5D5B1G16t
9ziO5pcluMoTJQgqF02HLzvC26xV3Lu8rqQ3cGMzRqm+9/Sscw/OeedbWPF+pkh+OdDxwJ/Y9wk9
IMnR5+5/WjzHBN+TJOyeo8C5wPgXuIvsgPgvIEwzMrNaJICELhXrgWEBzMMSQwXCxJHZZPo4CzRk
R+5hvXv1kPBscc4MnVFnR9ww57GvBkQfB6OT0QYD4OzBQOUI2clFli8y3FHiNiPgcwmMHydzqQ7U
OIH0o8x5lPHjfsePEQ58rv5u8/KYPsydzFOamtSEgh7+Up7FuQqU81qG3pyle8tjCxozcbWc4ySt
p87KRl3nJFY2pyXgInWKtVjet6hWbjNGKlkZijGBzI7A4xTbHxtPVD/M4/JQ1H4BiWSlgYZ7Ij8f
xk4OBVjS6nmTaw+AYWHs6xHdlnbn1IHOROWMEmSNKtPBuqJ7h+Qnk8HBFY8R+JOgVsDnZ4LyZPsb
DyI8X5Z35El5gQ/gR+SXoemc9j7MtU+qi9P32+ASLYsY4d8nk+rHfyKPgttt7OvHFDB8FXzYUYKL
NnRQObGKaseRzd9F+0O3ZgtC9zYiCwgjI4eBKuecnKXHgg8hySaPb20ex0eQRjfLw06g51yNBk/A
0BwYndmaHUuM1WlNMMyI5ttA3GiRjCV5aaFg8azJDRjJCSOKobFxcbmBgbl5kbGJmYnA3LreA7zL
C02tKhcWHhIvL6jlgs89DQDDbPJ2TkgyIsPBsbJJ5Rk0exYdGypMoObWmRUtLChaa3Hs+Ij4holi
u5e34XCEL1+y06xG/LrvMjPnCEIkmy3baB2Td5tUB3JswwgRDf31ZscxfCVFVjUaHOHyUafGuFmn
eNSa1jNEF1LXWJvAqLax0+7mcwszFXMabbLc6cYusl1S6bZzuGSMBGQAnEXoGCzC/NtDuga1VWsa
kTUg80KoXDosLyyAjoeDiI93CAi9y0rEwKmpDTJirypbfRJYkHpebb4YTEaDIJYZFCpwXmg6W36a
l2sM84ndK95Fog0N++zawmOg0OVKdwi7iUOqD6ZYDDYRNSHExpsi0M0jkDcLbF6ufiR1P0A6Ilhn
CYOD7z5B2IRZByXnCxZYrHiYkNDEyqMceORcZmhaYmiAmXETB5GFrZYOMQZUq0pQ2LQzMsphS3Is
N1wMirZFueqMmjZovBD6DJ2ejRwDnk1mcu5LwRo54IOSjxbcFk6+ONy3HfsdRk2PgwcHg3BWa5Zk
RIRoOQMS0iMduZeSLsjIoHhuULi0c4Hin9yieSQ2ex7HqewUP3ohjk8FmDRs4MG0QBy4s2Li4wKG
BU4egFXyEaiJFi9aUxd9Nefx6NawNZ9MBcCpocTS8tDpRfZq1RjzUNQ7G2d59lL3k1JhXrOsanWR
1NMkKLis3aow95geZVzWtRicZeszrCLyUZqdK8il8cMaXy1v30XhbN9Hk0MdDdM/DAhg1rtGcY+V
k9y1kUuQEHEmMRNxBNEgKIQwNtw4ITVTzwSzMNRQOMMFHjisc2DQQdGDoklMGIhPHKJJD7HOmZm5
ZvlyTzPAwOfMg1ZQGPFUEHakDZYWF1tbxXkolkySiAJqGpQJOhbrWtwn8zLRC4ILNnB7mX9ZYffE
bj4D7XWPHg7J0dnJBCzyczHIxYj4LOTJsyhI2Tg8HIRJIUfsYbhn6QtJ/K6Ech5R6POSzg3z7c94
2er4WijZ2fAiyDvYpHIKPY8ddNyUqRbCXotHBMRGDAgKBpsHwEGBK7AoUrscCgOSLy8xNg6hFMsR
5mpU2MioxikF4iBk6HESOB0WaN8nuiy8CBzggr9NmgoMDBZoJOQ8DH3DHZ0SHYaPJ7EDg+6AFuls
gwSOnYEqSv/ce/+X9w38/54MF1t13xu/n6CBr9b1fl4DnxPcUPazQMu3p4xzi525S2j12uKRBh1O
dsO0pnbTWu2lNs/dZTxP5GYDjFEkEyVMMqL0KAvQkhyVwkBUQkieX4WeZ1nDfP8cuq4fzJB/O8UG
LRhN3Ol8wYUGEzAj8z37OFMN6EWKtDPb7L6NzXN1OtFAiwDR4mwch0ZUpjSh/K89vbO1dR23gSJt
aRyj9HJ/ZgKB2Rzz+s2jNT/EeN2MjCwjBm/pGBxI/0/ncHqPfQOaExJuf+r1aiRqJcm9Dyi10rV8
S4/qmZA8+WoWPX6znD4TfFiK8R7hoSdjm75Jc+vv6jmzEOuziijNQn490692jcPFnnpQ1NHZvOP6
4nYKTDEm7YidLRuphLxZ2RvJ2ZMk2ByeDGjFmacvccPJgP6Ztye0plO8TfS/NnOXupTLXtc1TXd+
bNv609Cdzia7bOz9NmH2/tzITTt2mhM6ZsohUj4WZfEfOPFOf4EaQa/3f44MqU6zFw6Df3PPs46S
lHXMT8noSb7PKhqQ9zPibsIl0mSB/ycjTmBZTfrr6c8/ff1O9lh/QTMsW40flFwrNvIaYhQ8tJ6S
lY27cFCIQXamYWydTlRYn0Job9CGdT9IPSPWrK9N80MskVj6fjBVlXSNGaPHAhD7xsbPrS9Z2lUk
iCQHln0s7K+OO/+nRd8ML8n3YzvsX5BUipFTOv8oQi0KaNG2fw7ZMbtsfLVRsv9P/DzUafn06wJN
FoSlglAhw4IEOQzVyBnBmhmoYMWAgIQ2IGgYbuAwzZqHJsW7CKjsyVluv4fTiE2ihp2hD9nTaxIi
PTUqOJZs4RjkmiTQVclA5Q3hSUjYRI2hQpQYChkJUYTDGnGqmsCi5DYW3qnrBz+Mfex+XbJuISyp
aQ0Vn0tsuLVFJTKLPn2wklgewEvkI2WskLBKMEmGGYK4ed4m1bUVMqSzUlSW3BKrVotWrUVpay1a
tWlq1atWlqas262R+v8W/PnxsmufzJUpJCVKKlIJ6zbqfEnzim5AJDsVipyqnGqUoXKmpUsqWkgE
iMnJUx2KHikjFC6pFAxRNBGEc1SIAX7fDrbI8wp6G24esP6sFPiqAn0+X4n0fEtTBedX9SDkdlA9
Ygb/1H/UXyEfJEKMNOgAN+QgvvpeRQL5TWKJfspKdbUF4oggdJgUY9YGP1gBYwJjCuZojEQrWOo/
uDqVD+wp/oDxgfSTv6kohUWLJPOfUazWrmqVozTrVyktVFFmnLC55SfD4T8F7Q9PM8ENsWL4hB0g
m9kBwD6npUDyFldf+uuy7FSeRQI4Typ1vV1dAf4L0csYqMJIBJAgxBeAEqKQEmfqfd/b1yHgoY4F
l7hYNbqGzBC4UIYKWa9Ul3/X+kT39LlusIRhA/QT8QLl3KsDCelFwb1qEgjwZ06E20mwIfxIZIqf
zIHi4UR8ll6+AoYFD76GIjA7bUj4lilF2TXIMxHENoRHsmJG+Xvr9h7Plb4k0/Hm+T0fFIRiacwx
B9wiZs3PVV3WlrQBN14pSeqB7Rn2+YQLKWSAQ+9daNKorQV3gcidIVHqEloCkitiqRqLI1J6BOwb
g+MNpuIfiDFv/bruiVBdQf2wKkxu3oLS0tCaQpjpd6XC0+y42IpYgMEgQn4dfe9vk0whGh7EBZN6
I0MZclhuZfJ+uGSk3yUy3LSpBMbCNpN82KaRBBYspswyNsDTN6oraFjMyWGXVwHPyEYwGYTBAUEw
BYgxEAmPayKo9fr4Xr5N26+ciOaMKYzp56Kwh67gGpwQ5Dg/1Jkx+QIZ6OWeTlnQyF25/MtvK6q3
TF1IegfVDMLBpDCDqwuPQu2oEBftH1gKTqWJvAU0N41+RIKO8v6jYC9HKjFEMQWwBQiwiRCN+e0A
3Ln0Teh2GO82hsQY0FhOY8OyauiaJOu4d4UzelkNhwoFIWFMDMwLpuBsG5G6wePYaDepvRvcTdjd
vnePC2WZp05p8h7j6g87Go9AESxAkkVeRs/ci0AeVAgJ7FKbm8JDoe/AJj/GS5y42eAr7yksn/2j
t5jtncnQAH8iKyxh5OlM9yOFTcpYsX3AzA/8HWdYFC8o3BEPQ13+uuvgWvbuPRG0/ztRUKJCoyyq
DUtkyE/HD+HpmyHtRiItcHld1BtsO8CEEsXmsNvDAAsMVFTBUKoUxo4pIFj3kXEEYKEXYSGmUkh1
IForiLmqZgbAYWpT6hiGCvBOQf30imuuHO60blH5fOFIQoQgf/j5oXKNgvQD70gNh8XN4fExKY3A
YUkdI47KJZqo4juAjUQpGi48A8UBPB5IoFED8zgNCPf7bFiwcRAd6ajlZUzPkwEqMG5yqRVPIasy
nTwXunlEIWOccB1dIXL+uuj6LyRXQQuR07kGpJCMSGhulkNSIPapCZYTg9d1h9p1EqUp4Q8k4lUW
yJkgmTQIuvcvUeoEcmAMxFoMvkfnTI8oZGQRkh7gQny58/uPeTNW3LdZmPAZQzAKQ4hD6WECyHbq
HGHDefe/Fve2uZcsqwH37eO5U1gbE90ClUDlHJkGQCnL9H0hYMgYQ+qWQ4jxsVPjE8vPT++DcJCM
kdrSZFb1jclPsax01RZKaql53SwpVK+dj8wPsfA30flMLygShZPF5gFL1NT/uhOCGBzJeFIQfmch
cakHzqZynQqSIwgqQiyAPxT1W1PP6VA4l5DIQ6xPELFyK3TgP60PfxEpP48oYUzImUQyCgiMBDMC
TYeEvX8UPKwqjzFRvKCmKFwsCCDDR/HZK5WUNpiKYMywcKQcZE2MXra8ycOBLIIiwYT7LBEvR2h1
6Fk0gHTCSqQDhCgaqMW7pRinFsMtTCrB3EwuYymDcErBQXAKcYUlNm9RPwpDNlHVYnGUZzQljlFl
rQhKBstoESrixcWa+Sr70CznU9/2LUEE5laNT3FC8XESqhRUKpkIHATgTyWEC3uIehNyJR8YE5Ok
DSmNYGAD7mKG/MpHIBTzCxMgcwj7Q8lDtBooxKPALiNFseWj8UPbQ6u0csbAfXuTNG8fO+lHusP2
kDWckCDCt9aPsSBYNjcw+Y0JFikYfKbHnrbmlQ6h1kmaXWpGdYdQm+sERZBC26Dc61RUSCv8qdy8
gXZSPWEKAg/nag4d+TbRUBTlLWOm9RDr3E9AniBdfSD6rQhToo+wQHEQNioqRFPvMxzLG50DREwA
hRFRYtPtlMQVYDAKJgViFQgkQQQQmNaBBLyAuDBE+kcR4+FPHArHRUKqBT69hYS5AwiBRFkhFXRN
AqkzQdTngqG9fxX4/uieW1Tx93cpEsPyO3asKNfS8l6GgSHQCdQQGnanLFe0sL3hibBA9ckDeyfY
n23gy0krKylSgfclqomnwlo7m90ULCli5cMkgjQ+1A6lUDozoch0BeFHNzDyhgqfNkTsslewPU4h
73sNFhy9sQxfEAudG53GLAFd1UqEWIATmlAq8k6o+RGNHkQ4j8ZqDY1hXwB0+0KHfA8YI4JSXiqp
A8RtAvO5YGvMZobk3FNVQEIFRohZzcWfg0lw4GRNIdFkepSPOpB+WYA7jFS527ato67bUciWLXIq
eQIYAx7EsFwf0AUg9gCG4engHmNImYpdNVQxThqoTOabsBNt1QobmRXbFpOFBc0Fu2YpqnkidpXf
Zj6Wz6wbokIKQBGoIENO015sw9YojEIiIi08utUD70xam1ObOV+Z4loFRg2FQkKMQxiptDCMpCqp
Wxdw8DYYKJj4vm8TuHO6EnvDoPLVu4oRIIDb7j5BclKXoMMlD7xNA+9gp86YYZjRLS0CGA2yhILD
8sB1q2miGFpQRiz+0dLqwqOjeExdDotXFFbaI4UFNQOcAmt2UkdogVHKUwgfzsblwpkpoLkTkkK7
lkEiEViCm0W+i1WQRBT29nEhD8P0+fWgLSoLneryIkK4SIvFI5cHyLLEQwsyAUvmYgfWwIw9ocnH
1PfnfU36dZj+ie49xxHr6Yfant61UP1b03otGRWWWSytJJAjJICBFMgHPTNXRIl3w7zhx6gQGMxS
1QdRGRvNyTB59CEFztesXhgPAuKLySs1vsnjJ6oAqCghZ39YPaUwnXAx7cU9AUJsuDtpCyPCkNQN
ux1INzAdClMvz7gsbXOk3CbWxu/PkikqSSgONqEAjACua5CUZA0q8DQ0hNJAkZElfZquNy5qDcdB
sIXCCR5hAeLZ3BtbpYkCEYRho08nK9mLAwwpsRCoB2B3wUPaB1+psCp7AvdcFfSCEDEEOWFJPn+i
/ciMEZvYIyPvufo92+uzk4zarQ2Ie492ybpzmz23yc5alKY9fWURMZHTmaYUGGtUwLQK0SQDtetn
yZvbaySQ1tGolpUJYyCFAmYxNBE96GYppaH4SkpQTrw61NNjHRS71QnoAOMzazLcQnGrrIxciphp
srjxbUMuYGAgmiYkLEYXc0wCNwuxsoma/hoTTKxRTLWDU+G3vGL7xyR7b4Z3quiRwuzBSdLVGXTZ
oSsqGS1uhNaANvkOwUeoHhCHrW4t86lnsLkBcBTloTpA52LmvWwB6ekuPnuKMaFPbY7ocs2CR8mc
qLjENCDXWEbCDsbztgc6rMvV32ONYjxQ2pDyv10nI7CvsF5hYr0ABpRDWDkU32D5Rge24DgNx7Th
aOZghDhcNh8146y3GHhYPMkDX/w+MKr+5JsbvX1hYpDCIVRj9F+IIWYY6kphG8xASqId8U4yXmYT
1IcpfiCYTh62l9n+Uvle/hfT4Wv6rf8oQUHfb9hCGl5BtE5pjaQcdsALABHEfqf8T6KJ9JCG+dTe
/kf2LWf7chMlvo+HvD+jn8XzlWw/Gl4LqMV956dtsg3yPKY4sNFHmUbmN9ztaQioEY+6ns2Zas/+
haE7zxz37Q1x+/6i4PivqaE/aaDvH2p9RY+sie0LKYnLcY3wAvLIh7RpTkNiXZclEhJVStV0in2X
kkgxjHFGIW0DLxqygOYcHEPuC8IEBIDgZx5H4q5SqYJAs/M8wQQOcsw1DcNTQwkw5oRC6DtHRyDz
Q7+0hGMyMAJqHIdo8+N+mNENzcLLIkm+KcCkX9zQ0tnAoAMcaEouSWCypcoblYIPgnA3sJDG7QA3
bE1me2Vsjp7/smTTIQkkXVGftcQl7zVOwcC+xSREcwpp9C8RzXNC95KRTR6pSoZ5yShTEiG9LiYk
AuNuCHRvuZsHqhzneUSep6WyLJIDYeDZ+F98b2pqlo0K19ux4Hg9cz5MXZ7toPqTAKpPvFoxGHO4
FAftS6lA0Bmbj5gfflV5oreMjEgMGgEJQjFP1PVoFzU1UtdQDEFXUiFgxN0kkmtGRIaKR2fBMCyJ
5CiGKzIyqiCUqqu4ZBBc7D6xTAebvUc3AUhmdbZf0Bh70b5JWSarVRUSVqKahKjPwrbN6v63wx/t
EyR82PcTA7Vd5tEdEtsSiciISPFTa+kkIg4Ir7EeoUnI0OxYNkQDtEGJISBCSCCMTvSjBRnHHFb+
c/v6zVt2QkDMhkH2n+f1mB2nv/QQKHAY+4yD85QLSGbWhwEgO87goEEhB+g/4GRUxLjHIzFUqZFB
BEzJkz7nNB7ga8sMTEqXFpaYMPman+CXpQMxUVhobkTkGZaRC6ZcVMDLLAiULA2LDU1JMG5AdF4E
fB7BRBwShz/wMgMNFickMGxFhMiQLBioXmmAQJloRDSoWnUkdP4H97I/ewMzMzCIgIzOaQOXhx44
FTpmGo4xPkSLDiaah/xEf1zIFvMKl5wRwG1qcigf6WEC3dz3oLGRVvaxAKpL1iNTA2HMRjcn/EGg
Q2uVhHBI+jlavUXAvUKhzOh3lQtHOwn4DGBxOovMWOM2UHSIIGWPl6uJbicShiDFlGsHgSMw0OQw
WncTLy8sNRiQMjTYz5LZken1pAuYkkNn13gYQEex4DgQOFDJgUx9KjC1CcAkQewgfUNCQAgr9HUQ
4a+eVYQtCvkmo8OTH8b9tTDJy+vnU67m3vkA1GTAQEGJbW2md2xZCSSa1sed+phMhFIXgGZ/JhIs
VZEmYTPPNqd2NYUsZBsD9fdi99YamHUOxCKESMAVjb8M0gQUIaVVCKd3mCDqVMPTBcobKDfY4mNt
FTARK+7P1GhQPZctRuUePOiyoaawI+4T2IYDoA3T6xDYgKYwRN32EAzbjEQiNqIIqe9U34CEU+De
sZ+kmg1hvZC8yKpjed3EMdMiOsIIWVeGQ9VTqB9Yg+dCligbWNhqUd23sLWE6+jvA7cWAx5QoqB5
DoA2SQ7v4FbbbUqEIgkYRbGiQUkBBAKB7Pb4njONHcWmVpkwEDuZmhmYPFASJoclCqRSbZtEvB9x
EauEElOGMshFEJI8j4kgZIQmQswsDEY4Byz5BJes7kKEAAiB8YfMFHrmVNhP6/hwgxKGsYDYCKBC
HwOocPgWHuPAv9JM8wp9I4SVhIPiZh9JeED3wMTEKC8ShiOWg+JQoORKFRhzAsJEjAyCRkYSLDgQ
JF44XBgFExmWGBn7+zs8notvJs36pujRYhGBijyKyjwcEnAe1UXaBAQesACtDooBieBwLmB7Owal
Gz+ZCiQIVKQ6lD2Hda/GbQ4DYQycOo2mBkfcI8NQ1Kl6OsMDYXXcRLy06FpEtMCIWFp1l5cMVLxF
2ySOiGS0LMD7H03NzIOw6GJf5ywHEdiSSIwGGKhgcDctCBoEN0BaCs3foU589Df+FBzH7TnLiFz8
TShjiv7fQBZ0idO7emQcbSpg6ADQrCXA+f/PTjYPoGA0OHDpUPqCQ/Pg7Nvg32s+DPrAuYKSEiZq
UhzSQIDl938fntMkOyk1EGzfcfKCWLgopcYqxaeuaO7u2TgGJDCD5wgzTQG1oRGvwvRC4QGp+WBZ
Jq+z2jJggeo8z3HrOZuI+AiogckNZwoHieHtzEGRcCDEoeRE+hC9kRiRgakTIR7ShabMM9BzQzIk
NZ+YQYIJPYyYOQ0QQSSzHR8B0cGjssODAUIRYQcHI5wQwxskgcybEdHJ0ZCjSGIzGU+XLoMm+8KD
60CPQxKTyqwKAgBBDuJEyqLwOJwOxA3jyLn2qczTdvKwID2Incay5G9YcLqDgDgNQ7tZynKbukUv
6hOcrIGQo4DCxuLJEJeYFGB+Dxm4OJwARxhRmeJQXuck7IHukkPAg0RogDJiQziU8alAeDeATmgJ
HeeBzpAxNC+qXncBMRAGRkMVNiw6urvNC8sJMW3W0KMSOA9Q4aAy1SWN4q2xUiiAVDoYMPLDyQ2S
bWWix+WGzpHdVH5nO2kwCpcfWATtkKQ4V2AnaR6Af3jkofYE2RXaBLADBXWLIt1SKhWQf+IIGp/a
UTMQPfsoI5nxf50T4KgJbMJI4EhchRSyB5VLy9BxS4woeh5WiPfKiUkT5ljtwSg7had5JcJcDRJF
IUt6APKJe96MMCrS+B9ofETeJ+Hcu9eq6Jx40nJDx9emR6xYJXfwQLBb6oBBQjgugB7Ufmr0cg2j
795oNzZAy31ZShoOI/lKEByUXRZSJPyN42GGBtIu9hcIwKJJIFhZacYbzQHIwkMM0mTEwzIDJaJU
K8JhDUFhq2GJ9u+6f06DmA1wziZhWjJDq0957TtPdAkZZ+893cbJZ+jZzZ3GLzEYxDrLjEvCATNT
A9gKw+EiZQwLzdJAIn8D7kLffIvAQpfEagOZmpdEvLCQSJlkomJIkI45hQzMgTmBuDkxQvLTkkgM
SBifBBxoKBIwOSEkXGJmFxgXFxXG4tKnAyLBjJJGpaTDAoctLDYsOwmalpMK6rgzmubZlZOO27Wx
wdk2lfjywwAdIgKDCQHALTcfm9pcYTNonngCDuQ+Y8xVJAlFHhpGEvDSZDfOMOQo4DQesSxMMhiW
ZuQOosPNSOgx1sdpg5ayR5iXqQwAzMgYxMymRIQXnA93ISHHYb3j+wUcDPkW9pCJEZMwXGJ516v7
IQsCzA6/xGOHuYJDu571mhCSBJPUolxjQyKYK5gw7eM6DeOc7TDDYgwj2XIQeQkBeHUadNQJxNRm
77YS1QFv/IbJtwPwdm6xlf2MEDySxYYYYX6RG0jBMROh6rkfBkpoS4pX+1MBhva4OFRB28LonyBY
wqftZtf4vp49n2Ykh/v/ksnx7vNk+iIcNZ/nTy8DlDk1t9OTWRtMTGu1itRcewsSYYJmHAhcjCsi
98HTHUz3s8oMiDQBrWcEDPpCTqUDOddPgneId7ZQog9IlRixGIrOpQ6E0cPyMLsKdIsmyAk1jhnN
26A8h/jGqoqe7/tKDg8Y1rrLeChuoRKPXm6MFvgl2DWrKm+J3VAHk1LQyYBnduEP530e7dhFXpr3
UWVEMYaxgWjMQDEaKRRBIvZBBgE0qPEwJefTg8A2ygxGdYmRSRDAgsTi5l5clqbyz8NpQ7weuXby
Zcbxl2LRxvQ4ZaDbMs4fQOFSzUUXEScpBRpjOH5TNpdONzAQiSZOUZs84GCSWJyx+j4HwPXYi5BM
OLuMgh5zsniqYbDDN61sw0xImGYZrAEYIUITV4kb4l0kHyVJgg9QpCMYcC5d3FqWmrbbDW6FQ2M2
4Cy2JrZrnjljoDyIzgp4DD5vHszlk/toZglmD5pm2hIMSuDtUylCX6TGqmwPR5jiPEHceI7yxuPU
cZ0hWUI08Ms51w/N9t9nn09N1Ne3azqwntwG2CZA+wgKFRjQPd8ZFQoyqYlp9JHg4VBzDIvmRqNI
wKCxLS06ypywpK+pL0e3Peccd6WcOPPLElbZC3bnGuNl905SOVLtJaNPqrjrIftnCHdXs4nDHfXH
GJCYNmcziGx1XuUCJb4CBXC1LTmHcplCw6yZHAzKDluRUiZdvddVtCZaYGhgZFAsGLywxKBmVIHn
6esY4sEqLIew6+gugHkqRQpFD1OYqZp3EM0EDlkCQWQIrSUp535r1s4MWx+t+jvBZ+ydS2h9hUtS
w+LecaIAHiHOBJDeawk2BjihBDmcBRsK4iqZoc0xCA3OQaEQhLHU7CHQ9B6gcgMXHeRF1m+a6jf1
gfxUV4+PrKhEQEr2dGzhBSlgpCOcpA2HSHWbDe2nWbTrDSgHrVGXWeb2EdhjodDoexAWlrJVDrNS
YXmyXmen7ob+LltJtqxkW1kKKxCQVICwgPUAX84gn7859ptWL5zERMigZhMJjIvEB5EoDMM8WPLT
6CbqWBMXNkFUK14u8uuJiqUqFZTq7ix6c+OxNAQwamIRUC3xPQeB3jHgZFyze5IgM4yr3m2QcUoo
M4j/Eib4r7isvdobyYocDknchmbHsYqgIzEyQmDwGKGw5oYHieRxHKGtCBE/3pI51PAb+VBIAvGa
zYB/CQCESMkAkymVlptaSFNZJC2/eb6ScthUQLoqkYAURHV2docvcFy7ngrqLClwD7UinbrPx+Af
7D07z5wMSit4/HIh8iFQAkDOd6Jvr6YJbjVBhABCxYC67SiD6MXa4+MTuE5x1QAiwbkNawKZxQhh
oLCHyEUZSyWhGbQIouzfzXt2eT21aNNLazaxGre1JtJVU1JNTJFplvbpydjoqttWxW3jXFTeZ25b
zjrRaplIza1JyOmpsZrEQFw0ewdLF4lND0kXGbUA4z9QPaXby4Z8x81iWsmsGozVEaJKTW2rVLWp
C2bJYU20qsttKhStsrKzFDRNiJaaKLagJbGifk9R0HkBy2h5gXe6FkihIxhAjyIE30tbKAOq8oRI
QAW5VIF4EsZA6AzzRAmArkKkSIqa2XxQ/Mie3Pbm5ujYovQD82GZML3LI+kTDKIEUxnxPfZwbHdv
qG4OyZMfOxv1obAG3NIWcKSdYcjhmclI2Qa4A3GMD2OQbIh2oJPY1LAcGxjdjjRkW7uXSSR8hAKh
eiwBgVQIG/MEB/UTAwwzAIZAwksgzaxH43+kLbS4r+RofARvOSKIY9iql6B3c87AfsuUS5HjdbQB
opqYFUq7hYCpsBXm/AmCSF/JUoqKax+t54OffRcQxlQwzua2MQwqcvKgt+LSm2SOl9S5e5XrwQW4
CVYOCB6qUPOGm8oLEOozk12o41BiGYA0uegWkgFXKmYOMRIEQiA1f6PiSBJOpqoglgQxMw4GA7Ur
RSu1YKfy2pmARQGBIEECAhCdTuVIqo/ZurYnCJImJiJ/v+PPaPh4FjGhmmZSKSKKGIf33mszHNvq
nL74PIQX4QFAP0eUSgbQAPCJfUah70n4RNRbpTIFwkmQMkxCVy5mvd4lt9oaUiKZGCMagr9R3nGH
tM58C89ReSSHDnoR+0R/WaP3f1iWCzBZ6JLEf1lk6DIjB0Tg+8LDwUOfv/fJ2ByejQtEHAOcno0K
1zIDFxuItDz0C0zMDUsMxhzY1NCwgYFnJQe4j+oo4OUDmSDYe4QI4L7OzB2E7ShM4I4IcztJ7BcZ
Dh3gqmTEhi0Li8qcFj/wMN4H9nEbB9EaKbs9DzQzASWeDZaPJJB9Zl1VyLjILjc1J5DMdgkBuIBk
MbV2gJo0lauvFULyKcojefgCMVDBVL1FoBYPsAhITWjicSlwHckUDlW2z7Xp2Pj2+v20rUkWstKt
kQ/dZRfsSqD9P18hPiDYpuUMOhAGEweYQ+l+3fOfp1lD57jfDL5VSAf5E3pRPGY0Pbz+qeoh9Hx9
6AoSHu6eBbdGgyIBURAdNmSzydbC29MeQ9E63PPNOb0Oiju3oLN7PS0LaPX4t92t9ubUTLEiJyVD
UEKChEsiUFKJrtFsJ7Th5R5xhC+a5jHyLLYT3LTxMCqVSmAA9JyjhddsMfoMp1y1ijG37w8lrLwi
bKPIJiHNnT2iXgIOkvYqohs2KRYrCEYkCEYECV60Jns2LkXALor2s8TSQdC5Vz+QU3DAuHUGFNWu
3ChoZGQhJK6x8gSAQMQDvCiKcT5Rrcb4BAP2PY96B95CHPApMYwQffakBC0l20bkrPzW3WejW27P
Tc5NLUBoCQG/yfncCo3xUS4vpVgllShA9GL0+oO28VTEAQAcSghtOM7ipRtPPNeZasSOTU9Xq2Ub
FnzTKQYi7kBCXsf52CAtWTlASg+Y3BvM/vTZW2rBQyjWRtu2XTpClySQVhFSC5lvaqsX/4DEPSHO
Q/gqefMj1mc/wFg9yBFNRrp1FUeRH8Nr+l6HNAcDEETGSLCBFgQM2JcoN6GszQwdfrlG4P8S9LUU
Q7q4lbglLkDRdkxcswMeWr8A3hyBlH/5k5hTyBh3Iel4UPcxfnOUBRcmrLwnd1XHnAAuWAJhQJ5B
2ahPWJ5gfh0iH0lGkTiDR8xJ5HmCFrBJpU/i4p6iwRx6gfD1kqRRJF5FKWE6Cj84WHkobrcaxS0I
bRCyna7oZV/kXygrsA1E12eSp/R16E+Nmf5AuhZpgJmTKSqIKscICJpt7xUS9VvAb1ALNl4D8s20
zl5Cx4rAWCFlSmQJrFSKb6J+icZ3RkhJLWtpFIqTKNaXx9dtylkrUtQmRX9rs7VKx5u7KW1i2ttF
UpahVtVqy0SATAG2CmgQApSh+mi4iH8drsCLRRKqCP4mAikv5TPYy82j1c0kArADiHTFBQPeJzoL
AfQgYpihkKMYCgWQkvkpaH9rjBY/cp6vnMZAQhaKpl+ImjhJzhv9LmyJxhIlSR+SUHVMI2E+4+kC
HRDAXxFjcyCtivJpDeA5UeaAGn6Cb5m+wVTjDyRIiIFyGDFrqroMMzT3gmGSmOUMZ6h2Sdpcg9iy
6yFs+Ddw1luAKxhKSEURXokjcS11h3X74oWT2p4/H3l0haBLWP9IZjiVS/BIQmg+w52am45LvKMH
C21YskCgyGEtcfgjyxcRgUqhRRfOx1E2/sVNipltnzvp9s7WtsimVmlbZazYmAgxC248wGfBAv0F
BEniTnXkMijIDJBISIQSBFhCE7NI8jwnn51TTAEH1DtQ35npzJCJckgNSEBEofindyvtY4fRk0Pl
u40spWgMiCxNgIlQQTSN5sAtBBLC/S9YUNwOUdHtEzLnYp5ZeZUQwVIYl9QmAlvv3+K4NAyYmsQO
jRuxecOUf1YEJDhEg0rCSMQggFRUkO3sCkr1v7kCxmQ5gB4zxibBOYmL4nVpTcJ3chP00JSDO6IW
Qim4DNBTOtZqVZAJAHDSJwCfuRyiBiGoZKnIgPzR3qH3/UYiZjIJiRBLKgq+hQDSP2eBR6Pjxw+R
OUheQkPnhRLqtakxmgrsSu/dC4qno5nMT9/QMxPDAT1ibNDt2+CXEPavn+5DhfcRyJQREsQgxYsF
FYCoKDHKMn1lELcNHX4O52bP0e3vFsJi1s/T2Y62oRCkYswt1vi8fL8WH7++tn1itpYSQQrh0fE1
VoNiGqC4XXRjUArYSFE8iFkMCijQm6lRtLqEpETVTQo6w+9IIGnMKaHZghRZP7LEIARZCKjIALFI
EJGKY+i4ekd82juhIkJrem3TH6mvXvo0RPM2m5bpu5DKkskjY12jzgbrnMwJPiJ6n6RzeFZff8Cj
mOu8UYdgNDaJjuJkdCiSZg/eJMf2ZLkZ+9Zcf2CZuJaFEExgDFkSfJIkHFUpfeESugNh07Km0ILP
HxaA6hB9Nnp1y7tWziW01znovBFtVDGm0sWLWbQGiLQLlPJiV82pRXwv1lhE1CpUfMAxWhgAYlSX
k5BJxCBZVb4PuE8js4fMKExDwnl8coxtX0GepLjRy5k/XslK1ThEWmdihBimGQOYIYGjAP6Ej8uw
RuvaOIiVEQX8MKlwIwBBe6aIPMHCqcgcwcoQo5glhsBA7JhHtsRSKUmRh7lM+96bkyWVSgI+OpHu
wQ070QPw/DfO5bPTStnETClmP0O4zEjnoBDltoJYqAMWp+ZsGAa3/GfnMuzpGNwGCKLzDA1EA8Gm
44FT4qlOpUmhTXZU6dj+bhvncDRwucobQSIm/yja/LuVOhoTRm+CFCObJ3ZTR+WYsbRPSqbFKDJj
kQqypAAcp+QoFGmzFo6G2ssGU5A5Q7Bb2gYCUaR/qsJx/Ch2QkGSRXfW1JZ3v7jWN07eJ6TxNlhL
WtCkRNobTJA88enh6N4bt5ZY6gRrB0ln5tZlCsu1EqAiIfw5LwbmyGMMR1DhmCKCaiSw8v/0hCXD
4/EmIriEQAvAKKKc2MjILYpNrs2eW3Rutgst2s5aRviRCwkUAskYRRKKVPoR+APC9rhfEc4MjSqG
v0dE7CRQqd/jISgtAqA41xRlXLPqJOkJJLDf9E4EONWGwDMJzZKxDCACH3k0BSlOJMgGKmHc9Nm9
yxo87Kzxoo2VKt3pJ6c5JeN0zju9LzzceQqSRq3SRSaF1azJopDECsEUQio6LQ/1gzjAdVVUOpaI
ix62UY6p0XFOmB11b0LcJZU1hN4ds5oZQGQ4UwHMAsoyMcIFYlQYhS1pSCBkIcgP06ly4g4JiOQt
A0NxoO2dtt8UokaLfC7dVlx4niTdaMBaqEpKq7RSRIDYCGIqaGoQIyQTvBbaW0JJ832sgm+LkIsI
rKK2q7bYl6Xm8PYZ9rPvvc8vpgJKdCgllSwiaBcX22PJAwxi0wwlDBL2oC8RsKpZYGArbABLni52
DEqRYQxKMEAyHIo/mELFwUvFP42X8gxU4BtEDzFUMYAksvE60Sc4USzO2ftIbaLQCWKheKiBDxr6
QoqRPBaKkCh9pYvMgvcjq33xCapzhFQExg+72zb1zREQjEVmrazMskBYQgA/ITENJgKIpO0BHhVL
WVLj6BSiACRAgFL5f1nrEtgXTUd2Mbx0J+F1efGKH1ByF3XHnGAZRi3iQHshXmDGK7HzoYgIOk1J
pMCUXrIMbjeFAaFekS79JFckRihgQZCECT7GTzGtZaZV47bpjWjS2UqwilumnjO3QPM1yw2tFF8R
l8QopDKBFFsilKoWAhSF6d8h7dmoQB3SVIIySQNxpB2hF16WMFQwxEMxKRAoOy+ImCFA1xqgJw7P
H7zy1PJEkGE4IgtQOMIOFv5lm8Dc/kpTFoMrFoo6Bo6DhwNLI3CNu6oCYYhP5AD7vkJ3zIZcqoC+
UTn9qp+EWRTMpzaRA2kDDUbORD/IwhIfo3JjQLwIKRGcH4BD5IaDSxSIhnXeVXVzdnwbcOzP7u/n
ifK9s3+RS0Vq20tZNLFrULEsq1tZMlljFVStpaKVJNlqjZSLK1atgm2Q221UzUy26OAzRDI7v0uW
h1vaJZHAijLbJJx2AfxIPUIGmBGA7jr47AbxA54HMQVBzctOR9h32pbWL9qpe6L60ATTBMyoGAYI
BwIiQFilCEDc5c+T6rwXuXABxOVP1cPcKHacQYxINNyJ8XDDMLGMr/nTHzlBVii+1IesylCZTGAZ
mAXoXkIqwIQCZCqa97B3LlB9SmzYiOWjzFzDGgMGKlgpUgvIhEUKUl2dB/Izf1gnnGDBMvUAhzaR
6uFQXOpTzn/IyjuTUhIB1OnkQZxjFXxDEXclYUalesOF2UIGSPQixflyCRTWWPYBcBT7YXlqT8OP
J+yq61v2p59N1iliByEAtcQa2Dwh4B374PuExc3NQfA3jYd1dd9e7tqUF5GwSEgXK80kFvYC9IZk
PYAPv3jIg6IhlUF4rQofIGGAUiMf5KWDGM9EzUCy26U8AGCUUaAou6a9suOnNUqgcFXc2VXBhK3L
WZS9/lfIBgdjJIfbJD8JE+5FThcWyUkCQkYEjDAPlPlFMm4T7QPJ8CUln3eLTWlBEQQ8s3vNJs6Z
5zzcyagc04dOnQ0TAZEGAw1pBcEjxRejyZ48ym4lrT0WePGWIELLRCyNlnEJ9Zw6BQPmX6zqETYR
RToAPitLyiFxnJvWCxC0oiAUCpcfm3Q/oPd966oUCX6PSFRsGhZ7FzFDi3yz1+nvk3sei2tqKjKa
kn0u7Knu33ZDVk1prWrbazEaCxpUqTEhpbFY1GzWaJsxXC/BH99j3nwZ6/Lb3lkfTbgEjq0bHEtS
zPqJAnmNAw4kQLA9ip2CpFTS2NPK/bbizPJl0JpSOyHjoMbmVjGvm33LVK1VkTWqomqiz8TPx+YT
IpBIZUCKdSG09i/MAj9iG4T9irBJqCNb9vSLD32KvaIOuNx7OVEJhgNPQmQhB1LJeB0khFjGIRkZ
IaqrCKhElGT0iP2jBpMjGL8rQ3MLDHEyxMxbaQriGQxDDCxQtkrg3E7bZMQUVYxBDTJgQ7qBqDf9
NAMg+0woCJRZ9Y5DcML2ulLQGoXkESybo4RwHSUcje+Jf4A+dxrlYYhVYFC5ksg2UWxahVKLAbVu
U9ip+280n6FPxvKmNvRDFuLCAn6A/w83phDkonmhwXFFhqJQXIQsNo2Rs5y9A5A8gA2OJDnDgKBI
MgZkMQOzIgxETRHIMMhuuNYoDmgkz4GBe+w6+AQMoXaFh9qvIUubIt6WIvjOUOqhJFaAm+qAnnBH
A4MZWx5SG+IqWT1YigcbmE0J+9SSXJkwO23oDmeYJAjsQ+V6BSR0XheRikbURQMvzqnvVLCj6lSI
IWUc/o2G+bBXjUgA2CCTK7gLxsGL7dyDiIpc+DnMvYBmQ4BzAhxWVQ0fAD5oMAF4S/SnbjUMmkzk
EigwbwIqLCIpAQLhQge/1U7rxZwXkjQfQqdcFAcgQ0VU5b1NDAG4FDSHlUDOabhH8SA1BJCRMIH3
ddCOaqRaB/CgsYg0KlUUKnFA5kH7gxuCviP72ns5mhaimIOdANAMQG1IvKJiLZcx57jHffagtJW6
g+/h76KLrpmxFf6gn5ENKTMxsRLRuCECiDloYkm2d4d0eq9XaaL5SrrfRy1wbKlrhcC/6Lms3xva
eMhj0nJTNGIgN/nfg5cY5CrUDFNGJeRLOeNM1T5qLGO3T8nl2zxZDf0nPK5K4thtn6rKOXVEB6kg
OZrvy3j/TTYWfAmZ39ySTWbbpUSmtFydvlIeL0DrOBHgLfuCMxEFO4Soo8em8ybva8W6BECatDXa
JSGCw6n8E0P8jOFCcjhk4WvBmEMg6hBcgZYiAjSlrFFGXOVgqRUwFSKmuOTZSnYlOQIUq0iFnBKv
ENJghBgrFUsEM8Vb6EafqiA5XqWgWBy4kM/E0hQ8xvnIMOJIQQpKSs0XPZVuMHOAF4gwGzSp2qQs
YOIDRVGhog5lCBYsBIL9jC5ue87532PUWShjdcyWbvvk0euNmF1TZPgxAWRiFegl8v2LMSAqkINi
4A/ET27o+FbRQHEaIkN7iA1RQCDZM4kZAEO/yWCbMMco2HgTL+sJ7JDP06rRrG2JULNzUT1IqbBs
9TLGSw6Qux4fRKDqIAwOkDvwfM/woisRTO+2s7Z3ykMcmrjW21K221pUttYaQ7kdvxW6NT4+byzj
jfE1pF0v+M1MzVVYraXGlLmEqYXEwUylMtFtOoZ0CNKiKxi0xUFWKoIxwxEVir6IbHo8mL9FP5qn
IhkhI5CmiilCAFKQpJ2nFydtHZOLtOLtOLjpzi7TsnE4WdpxdpxdpxcnZOJxdpxdpxdpxcnYSglB
pUpZSli7LZCVpEj3zKlkqWKJ0F2gTX/Qc3fjNScEDyAKcFKDQDAtA3d99rivASxmQgWuoCUUabHP
S2XXtMwNZALTRowjTeayTA3IbmBGSRiwC6xFChdAcClTDYZgPIO7SFggo+QNC0rzUSiD+oIi7h2K
+AqmvscMnoenUhxGhHDBIQCR9VT5hZ4TUIGJNlGNInhsABq0NOJPd5UNLmhwHs+GSfvE+wQNTiTw
jWcohOHxojH7yfZxxsqniXNP2mb18MYCJyN+CZwLckRyiUQjYkma8M7N6wGG0SOiATAYFCYblOJ0
MbERqKo21ls1iaeYf+jWCzAITQh8I6dmcV9RWhnYBzPK1MthESJSEZGWGJu7pUIcQUFYKhpuwxUT
wk1kBc4aGhxDiPoKTouS4qYkhmFNis/yGwwvktSCaMrEmzRl9+7dmWYt3t9dDiuHeCHB00KDuHvI
2zaHYhnMsw+WILc4iCvKwnGC6aWlA5aAgQ5yJ4ZNGiOrRYMqW1YGrKttIoMkqeiFkYbAHiyGuiww
jAyvhw8dma4tAxlkWTStVosZ3XBUBNoB6AEcEfwEsh3j9a8wh+5cubHvFNraaqwaPKA3AOAqYAhv
QwFxMgW4lBG8vCVGgIMKgjLjaIFYsqxYWQJkhhJ5pQXAYwQgWE5CYIZsGAxLcrDYYEaROmJgqmBD
JCOL3CFEGEjduYkhYdQRuIQEYmBmCt9igIfoqwah6iG24QBDEAyAdfQpR+6KuJEVMhiu4cgKBE2F
GyFzCkuS1XLFlmFGiywoaZhnpkO+SFAyMRjCICDAQEJBkgbPC+FKR6DmBZrIWEs6vB96IaF3ywL2
ohCUqYGcMQMAAXmz3/Ibe5VsUMnzfpnvE7nclCQiuHPLQxCKJAEeipSqGwTqBj76wxffu23cjm6c
ui1uuRTbra1jMW20TbTbDtZ22C2AGb9LhOhacco/sg/YSVTMQhraGkIyGNgYoPBdgdBUgckNAN70
NuwVLmJvmkOnY+CCDIh8QlLYc3IabZpzZfsExic7cDh2mY3KG+FAGsViQCA4SQFoR1Eimyyhl18A
qv71VzwFCBCYJIVAohQxRKr5oucjbPry3iqcpqNQqSKmxAP3CvKZsUI78H1qgJFMgkQ3vTOyynqe
brPU0TUvo76nhu30QlHjRiEFGoip4N0QwipwE4KDhFuIg2RUy8w8hubTEA9TgaIbFTKbKVI4ktwU
n4sDiXeD8DWET3o/juN5HAfhwA+SEOY9f3IaHwC8VT9WnQ/aPY/MvtaJ2qpW2IWim4O3tt28YBUi
c6mV4IcyJ0gCcrDeWSBvqwSAe4BfzYI2yUgHQPKJggoPOFwPSjYDsOcdYa48QhCpEevc8SFqjCBR
RGNA1D6Fd4JmA8EOyIhIgP5w4drzx/MEOihonSSo8vGbs4B+/egPE5E9YSkQinWhJ1KLWtYsAU2W
KCGJllqmYWNUrG4JShmJjHJMQzBmDEQpYjEErsk7YZO0oQK785IxwAPUcx5XS1rK0J+uwiD3Ihj+
4KDDTWWFG16EbLufbDg2alSBRXJmOLwA42qWQfA6XVBxNFEIE3o0QVbArYLJzIi/U2H5GBfEA85x
hv7RD2iHafQI6tKfIJiOuSVoeCXwBlqg1A5+CbrbMRF86EYCQj3BTrNQM8Uhl9xVNgrfoY/YVNUQ
Kuty9UgZ3YnpMQtdEPc5KqPuQ+KajJ1liW0nvHMvQ+dD09YmtA0QSRAwE4l1g39InvOsT20DtG8T
rE8Ym3pGLxa0fODouROCA68RVE+xztA9IbglPnEN8SkfGhjHE0NgT1fkhf5kIP5aDANYdFA8u5DE
Gz8OAO3fOQxtpnGOIx4YDIS5Lwwpcemffz98prRTWltIItvxX6yWK+Ang0H5IXDnRzFYGpxE6djq
HiCvPe2NUb6+hDSZzk5JGE1B5NY9fFlVvfvJJIa3q8cD+A/0qa7xOvt1yFNIpICoZ2oaI5+CDtDw
vBX9Ozr1bsPaM8G7jc7iDGpP1EXZig/skmmPYe1SECAabD+GSTJlmYstzA6JCg7mqXLQpvgHywy0
+JqG4NccyLKWghswgXhvcAtgY2VLI8xLoF/xEiHT3ZZblTKzJIyQIJZirZpFpdWgpUgYe/LMv9rv
z+18nkDyO3sRtsE59zzDiPNPqYSBJGEGESEQQkFIBCO16CdXnydPFfwisJEYJAkEG9DeMAfQIeI3
ec4CSSQnVUBKr6/YHdDMQxxPZqXPXYLvtRXViqno6ENS6NyPiVMa5hNonV1fMDzKxi1ht9iN1s2i
psfbWVaueI/7M9zD041NZt5mPS1axR8vDtrC2LZC1trYtsntzu6rufstEIkBO7v+bDoH9wu5Ipwo
SGt2eY4A
Received on Fri Sep 25 2009 - 11:30:03 MDT
This archive was generated by hypermail 2.2.0 : Fri Sep 25 2009 - 12:00:06 MDT