From: Amos Jeffries Date: Fri, 4 Sep 2009 12:59:38 +0000 (+1200) Subject: New squid_kerb_auth from Markus Moeller X-Git-Tag: SQUID_3_2_0_1~612^2~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3ad12bdabcfe9732e94fdce1ea44f2c75a94fb58;p=thirdparty%2Fsquid.git New squid_kerb_auth from Markus Moeller --- diff --git a/bootstrap.sh b/bootstrap.sh index 8066529b71..c76c3950b9 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -141,8 +141,7 @@ echo "libtool ($ltversion) : libtool$ltver" for dir in \ "" \ - lib/libTrie \ - helpers/negotiate_auth/squid_kerb_auth + lib/libTrie do if [ -z "$dir" ] || [ -d $dir ]; then if ( diff --git a/configure.in b/configure.in index 4a6b16d538..b03c2c5e74 100644 --- a/configure.in +++ b/configure.in @@ -1761,7 +1761,6 @@ if test -n "$NEGOTIATE_AUTH_HELPERS"; then 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 @@ -4105,6 +4104,7 @@ AC_CONFIG_FILES([\ helpers/ntlm_auth/smb_lm/smbval/Makefile \ helpers/ntlm_auth/mswin_sspi/Makefile \ helpers/negotiate_auth/Makefile \ + helpers/negotiate_auth/squid_kerb_auth/Makefile \ helpers/negotiate_auth/mswin_sspi/Makefile \ helpers/external_acl/Makefile \ helpers/external_acl/ip_user/Makefile \ diff --git a/helpers/negotiate_auth/Makefile.am b/helpers/negotiate_auth/Makefile.am index bc2f5ebe1f..d636c7142c 100644 --- a/helpers/negotiate_auth/Makefile.am +++ b/helpers/negotiate_auth/Makefile.am @@ -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@ diff --git a/helpers/negotiate_auth/squid_kerb_auth/AUTHORS b/helpers/negotiate_auth/squid_kerb_auth/AUTHORS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helpers/negotiate_auth/squid_kerb_auth/ChangeLog b/helpers/negotiate_auth/squid_kerb_auth/ChangeLog deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helpers/negotiate_auth/squid_kerb_auth/INSTALL b/helpers/negotiate_auth/squid_kerb_auth/INSTALL deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helpers/negotiate_auth/squid_kerb_auth/Makefile.am b/helpers/negotiate_auth/squid_kerb_auth/Makefile.am index 35e8efaf4c..77556de3a0 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/Makefile.am +++ b/helpers/negotiate_auth/squid_kerb_auth/Makefile.am @@ -1,41 +1,25 @@ EXTRA_DIST = configure README NEWS ChangeLog AUTHORS INSTALL 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) +bin_PROGRAMS = squid_kerb_auth squid_kerb_auth_test +SOURCE = squid_kerb_auth.c base64.c base64.h +SOURCE_test = squid_kerb_auth_test.c base64.c base64.h +SPNEGO = spnegohelp/derparse.c spnegohelp/derparse.h spnegohelp/Makefile spnegohelp/spnego.c spnegohelp/spnego.h spnegohelp/spnegohelp.c spnegohelp/spnegohelp.h spnegohelp/spnegop 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 +squid_kerb_auth_SOURCES = $(SOURCE) +AM_CPPFLAGS = $(KERBINCS) -I. 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 +squid_kerb_auth_SOURCES = $(SOURCE) $(SPNEGO) +AM_CPPFLAGS = $(KERBINCS) -I$(srcdir)/spnegohelp -I. endif +squid_kerb_auth_test_SOURCES = $(SOURCE_test) squid_kerb_auth_LDFLAGS = -squid_kerb_auth_LDADD = +squid_kerb_auth_LDADD = -L../../../lib -lmiscutil -lm $(KERBLIBS) 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 - +squid_kerb_auth_test_LDADD = -L../../../lib -lmiscutil -lm $(KERBLIBS) +KERBINCS = @KRB5INCS@ +KERBLIBS = @KRB5LIBS@ diff --git a/helpers/negotiate_auth/squid_kerb_auth/NEWS b/helpers/negotiate_auth/squid_kerb_auth/NEWS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/helpers/negotiate_auth/squid_kerb_auth/base64.c b/helpers/negotiate_auth/squid_kerb_auth/base64.c index 39dda27573..c4593cdb94 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/base64.c +++ b/helpers/negotiate_auth/squid_kerb_auth/base64.c @@ -13,7 +13,8 @@ static void ska_base64_init(void); static int base64_initialized = 0; #define BASE64_VALUE_SZ 256 int base64_value[BASE64_VALUE_SZ]; -const char base64_code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +const char base64_code[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static void @@ -22,131 +23,138 @@ ska_base64_init(void) 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; - - j=0; - for (i=strlen(data)-1; i>=0; i--) { - if (data[i] == '=') j++; - if (data[i] != '=') break; + int i, j; + + j = 0; + for (i = strlen(data) - 1; i >= 0; i--) { + if (data[i] == '=') + j++; + if (data[i] != '=') + break; } - return strlen(data)/4*3-j; + return strlen(data) / 4 * 3 - j; } diff --git a/helpers/negotiate_auth/squid_kerb_auth/base64.h b/helpers/negotiate_auth/squid_kerb_auth/base64.h index 3e3961e6bd..ece76e7532 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/base64.h +++ b/helpers/negotiate_auth/squid_kerb_auth/base64.h @@ -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); diff --git a/helpers/negotiate_auth/squid_kerb_auth/config.test b/helpers/negotiate_auth/squid_kerb_auth/config.test deleted file mode 100755 index 00546481d5..0000000000 --- a/helpers/negotiate_auth/squid_kerb_auth/config.test +++ /dev/null @@ -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 diff --git a/helpers/negotiate_auth/squid_kerb_auth/configure.in b/helpers/negotiate_auth/squid_kerb_auth/configure.in deleted file mode 100644 index c92cc120ed..0000000000 --- a/helpers/negotiate_auth/squid_kerb_auth/configure.in +++ /dev/null @@ -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@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 -#elif defined(HAVE_GSSAPI_H) -#include -#endif -#else -#ifdef HAVE_SEAM_KERBEROS -#ifdef HAVE_GSSAPI_GSSAPI_H -#include -#elif defined(HAVE_GSSAPI_H) -#include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_EXT_H -#include -#endif -#else /*MIT*/ -#ifdef HAVE_GSSAPI_GSSAPI_H -#include -#elif defined(HAVE_GSSAPI_H) -#include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H -#include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H -#include -#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;icount;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 -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 ]]) - AC_CHECK_DECLS([xfreeaddrinfo], [], [], [[#include ]]) - AC_CHECK_DECLS([xgai_strerror], [], [], [[#include ]]) - AC_CHECK_DECLS([xgetnameinfo], [], [], [[#include ]]) - AC_CHECK_DECLS([xstrdup], [], [], [[#include ]]) - AC_CHECK_DECLS([xmalloc], [], [], [[#include ]]) - AC_CHECK_DECLS([xfree], [], [], [[#include ]]) - 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 -#elif defined(HAVE_GSSAPI_H) -#include -#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 -#elif defined(HAVE_GSSAPI_H) -#include -#else -#error "GSSAPI header required" -#endif -#ifdef HAVE_GSSAPI_GSSAPI_EXT_H -#include -#endif -#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE -#else /*MIT*/ -#ifdef HAVE_GSSAPI_GSSAPI_H -#include -#elif defined(HAVE_GSSAPI_H) -#include -#else -#error "GSSAPI header required" -#endif -#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H -#include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H -#include -#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 diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c index 668c4b58aa..f4fb626ed2 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c @@ -22,6 +22,7 @@ // ///////////////////////////////////////////////////////////// +#include "config.h" #include #include #include @@ -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 @@ MECH_OID g_stcMechOIDList [] = { // //////////////////////////////////////////////////////////////////////////// -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; + 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 + // Check that the number of bytes we are about to read is within our boundary + // constraints - if ( nNumLengthBytes <= nBoundaryLength - 1 ) { + 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; + // 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++; + // 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; + // Account for the initial length byte + *pnNumLengthBytes = nNumLengthBytes + 1; + nReturn = SPNEGO_E_SUCCESS; - } // IF Valid Length + } // IF Valid Length - } // IF num bytes to read is within the boundary length + } // IF num bytes to read is within the boundary length - } // IF xtended 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 @@ int ASNDerGetLength( unsigned char* pbLengthData, long nBoundaryLength, long* pn // [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 ASNDerGetLength( unsigned char* pbLengthData, long nBoundaryLength, long* pn // //////////////////////////////////////////////////////////////////////////// -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 ) ) { + if (nBoundaryLength >= 2) { + // The first byte of the token data MUST match the specified token + if (*pbTokenData == nToken) { + // Next byte indicates the length + pbTokenData++; - nReturn = SPNEGO_E_INVALID_LENGTH; + // 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 ) { + } + // 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 ) { + // Check that the expected length matches + if ((nLengthWithToken - (nNumLengthBytes + 1)) != *pnLength) { - nReturn = SPNEGO_E_INVALID_LENGTH; + nReturn = SPNEGO_E_INVALID_LENGTH; - } + } - } // IF need to validate length + } // IF need to validate length - if ( SPNEGO_E_SUCCESS == nReturn ) { - *pnTokenLength = nNumLengthBytes + 1; - } + if (SPNEGO_E_SUCCESS == nReturn) { + *pnTokenLength = nNumLengthBytes + 1; + } - } // IF ASNDerGetLength + } // IF ASNDerGetLength - } // IF token matches - else { - nReturn = SPNEGO_E_TOKEN_NOT_FOUND; - } + } // IF token matches + else { + nReturn = SPNEGO_E_TOKEN_NOT_FOUND; + } - } // IF Boundary Length is at least 2 bytes + } // IF Boundary Length is at least 2 bytes - LOG(("ASNDerCheckToken returned %d\n",nReturn)); + LOG(("ASNDerCheckToken returned %d\n", nReturn)); return nReturn; } @@ -256,34 +266,36 @@ int ASNDerCheckToken( unsigned char* pbTokenData, unsigned char nToken, // //////////////////////////////////////////////////////////////////////////// -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 ASNDerCheckOID( unsigned char* pbTokenData, SPNEGO_MECH_OID nMechOID, long n // //////////////////////////////////////////////////////////////////////////// -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 @@ int ASNDerCalcNumLengthBytes( long nLength ) // //////////////////////////////////////////////////////////////////////////// -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 ASNDerCalcTokenLength( long nLength, long nDataLength ) // //////////////////////////////////////////////////////////////////////////// -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 ASNDerCalcElementLength( long nDataLength, long* pnInternalLength ) // //////////////////////////////////////////////////////////////////////////// -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 @@ long ASNDerCalcMechListLength( SPNEGO_MECH_OID mechoid, long* pnInternalLength ) // //////////////////////////////////////////////////////////////////////////// -int ASNDerWriteLength( unsigned char* pbData, long nLength ) +int +ASNDerWriteLength(unsigned char *pbData, long nLength) { - int nNumBytesRequired = ASNDerCalcNumLengthBytes( nLength ); - int nNumLengthBytes = nNumBytesRequired - 1; + int nNumBytesRequired = ASNDerCalcNumLengthBytes(nLength); + int nNumLengthBytes = nNumBytesRequired - 1; - if ( nNumBytesRequired > 1 ) { + if (nNumBytesRequired > 1) { - // Write out the number of bytes following which will be used - *pbData = (unsigned char ) ( LEN_XTND | nNumLengthBytes ); + // 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++; + // 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 ASNDerWriteLength( unsigned char* pbData, long nLength ) // //////////////////////////////////////////////////////////////////////////// -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 @@ int ASNDerWriteToken( unsigned char* pbData, unsigned char ucType, 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 @@ int ASNDerWriteToken( unsigned char* pbData, unsigned char ucType, // 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 ASNDerWriteToken( unsigned char* pbData, unsigned char ucType, // //////////////////////////////////////////////////////////////////////////// -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 @@ int ASNDerWriteOID( unsigned char* pbData, SPNEGO_MECH_OID eMechOID ) // //////////////////////////////////////////////////////////////////////////// -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 @@ long ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID mechoid ) // 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 @@ 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 +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; } - diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.h b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.h index bb3ad8f53a..349d34259c 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.h +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.h @@ -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 @@ extern "C" { #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 @@ extern "C" { 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 @@ extern "C" { 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 @@ extern "C" { // 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 @@ extern "C" { // 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 @@ extern "C" { #endif #endif - diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.c b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.c index 5f26261ddf..6b73a1579d 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.c +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.c @@ -32,7 +32,7 @@ // Defined in DERPARSE.C // -extern MECH_OID g_stcMechOIDList []; +extern MECH_OID g_stcMechOIDList[]; /**********************************************************************/ @@ -69,19 +69,21 @@ extern MECH_OID g_stcMechOIDList []; // //////////////////////////////////////////////////////////////////////////// -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 spnegoInitFromBinary( unsigned char* pbTokenData, unsigned long ulLength, SP // //////////////////////////////////////////////////////////////////////////// -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 spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType, // //////////////////////////////////////////////////////////////////////////// -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 @@ int spnegoCreateNegTokenTarg( SPNEGO_MECH_OID MechType, // 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 spnegoCreateNegTokenTarg( SPNEGO_MECH_OID MechType, // //////////////////////////////////////////////////////////////////////////// -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 @@ int spnegoTokenGetBinary( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTok // //////////////////////////////////////////////////////////////////////////// -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 @@ void spnegoFreeData( SPNEGO_TOKEN_HANDLE hSpnegoToken ) // //////////////////////////////////////////////////////////////////////////// -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) { + 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; - } + // 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 + } // IF parameters OK - LOG(("spnegoGetTokenType returned %d\n",nReturn)); + LOG(("spnegoGetTokenType returned %d\n", nReturn)); return nReturn; } @@ -411,31 +411,34 @@ int spnegoGetTokenType( SPNEGO_TOKEN_HANDLE hSpnegoToken, int * piTokenType ) //////////////////////////////////////////////////////////////////////////// // 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 spnegoIsMechTypeAvailable( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID // //////////////////////////////////////////////////////////////////////////// -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 spnegoGetContextFlags( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pucC // //////////////////////////////////////////////////////////////////////////// -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 spnegoGetNegotiationResult( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_NEGRESU // //////////////////////////////////////////////////////////////////////////// -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 ) { + 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 ) { + // 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++ ) { + 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; - } + 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 + } // For enum MechOIDs - } else { - nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; - } + } else { + nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; + } - } // IF parameters OK + } // IF parameters OK - LOG(("spnegoGetSupportedMechType returned %d\n",nReturn)); + LOG(("spnegoGetSupportedMechType returned %d\n", nReturn)); return nReturn;; } @@ -637,43 +655,47 @@ int spnegoGetSupportedMechType( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OI // //////////////////////////////////////////////////////////////////////////// -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 spnegoGetMechToken( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbToken // //////////////////////////////////////////////////////////////////////////// -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;; } - diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.h b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.h index b6c57f34f6..fbe4e1d3a5 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.h +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnego.h @@ -27,7 +27,8 @@ // C++ Specific #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif // Type Definitions @@ -36,30 +37,30 @@ extern "C" { // 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 + 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, + // 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 + // 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 @@ extern "C" { // 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 @@ extern "C" { // 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 @@ extern "C" { // 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) diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c index 465819510c..3aa3475992 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c @@ -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 - -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 + +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; +} diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h index c41d712d5f..56d357b04a 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h @@ -11,48 +11,47 @@ #define SPNEGOHELP_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #include - /* ----------------------------------------------------------------------------- - * 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 */ diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.c b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.c index 785b225b94..057a20c42c 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.c +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.c @@ -31,7 +31,7 @@ // Defined in DERPARSE.C // -extern MECH_OID g_stcMechOIDList []; +extern MECH_OID g_stcMechOIDList[]; /**********************************************************************/ /** **/ @@ -74,61 +74,59 @@ extern MECH_OID g_stcMechOIDList []; // //////////////////////////////////////////////////////////////////////////// -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 ); + if (nMechListMICLength > 0L) { + nTempLength = ASNDerCalcElementLength(nMechListMICLength, NULL); - // Check for rollover error - if ( nTempLength < nMechListMICLength ) { - goto xEndTokenInitLength; - } + // Check for rollover error + if (nTempLength < nMechListMICLength) { + goto xEndTokenInitLength; + } - nTotalLength += nTempLength; + nTotalLength += nTempLength; } - // Next is the MechToken - if ( nMechTokenLength > 0L ) { - nTempLength += ASNDerCalcElementLength( nMechTokenLength, NULL ); + if (nMechTokenLength > 0L) { + nTempLength += ASNDerCalcElementLength(nMechTokenLength, NULL); - // Check for rollover error - if ( nTempLength < nTotalLength ) { - goto xEndTokenInitLength; - } + // Check for rollover error + if (nTempLength < nTotalLength) { + goto xEndTokenInitLength; + } - nTotalLength = nTempLength; + nTotalLength = nTempLength; } - // Next is the ReqFlags - if ( nReqFlagsAvailable ) { - nTempLength += ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL ); + if (nReqFlagsAvailable) { + nTempLength += + ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL); - // Check for rollover error - if ( nTempLength < nTotalLength ) { - goto xEndTokenInitLength; - } + // Check for rollover error + if (nTempLength < nTotalLength) { + goto xEndTokenInitLength; + } - nTotalLength = nTempLength; + 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 @@ int CalculateMinSpnegoInitTokenSize( long nMechTokenLength, // 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 @@ int CalculateMinSpnegoInitTokenSize( long nMechTokenLength, 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 @@ int CalculateMinSpnegoInitTokenSize( long nMechTokenLength, *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 @@ xEndTokenInitLength: // //////////////////////////////////////////////////////////////////////////// -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 ); + if (ulMechListMICLen > 0L) { + nTempLength = + ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength); - // Decrease the pbWriteTokenData, now we know the length and - // write it out. + // Decrease the pbWriteTokenData, now we know the length and + // write it out. - pbWriteTokenData -= nTempLength; - nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC, - OCTETSTRING, pbMechListMIC, ulMechListMICLen ); + pbWriteTokenData -= nTempLength; + nTempLength = + ASNDerWriteElement(pbWriteTokenData, + SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC, + ulMechListMICLen); - // Adjust Values and sanity check - nTotalBytesWritten += nTempLength; - nInternalTokenLength -= nTempLength; + // Adjust Values and sanity check + nTotalBytesWritten += nTempLength; + nInternalTokenLength -= nTempLength; - if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { - goto xEndWriteNegTokenInit; - } + if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) { + goto xEndWriteNegTokenInit; + } - } // IF MechListMIC is present + } // 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 ) { + if (ucContextFlags > 0L) { - nTempLength = ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, &nInternalLength ); + 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) + // 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; + 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 ); + // 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; + // Adjust Values and sanity check + nTotalBytesWritten += nTempLength; + nInternalTokenLength -= nTempLength; - if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { - goto xEndWriteNegTokenInit; - } + if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) { + goto xEndWriteNegTokenInit; + } - } // IF ContextFlags + } // 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 @@ int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType, // 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 @@ xEndWriteNegTokenInit: // //////////////////////////////////////////////////////////////////////////// -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 ); + if (nMechListMICLen > 0L) { + nTempLength = ASNDerCalcElementLength(nMechListMICLen, NULL); - // Check for rollover error - if ( nTempLength < nMechListMICLen ) { - goto xEndTokenTargLength; - } + // Check for rollover error + if (nTempLength < nMechListMICLen) { + goto xEndTokenTargLength; + } - nTotalLength += nTempLength; + nTotalLength += nTempLength; } - // Next is the MechToken - if ( nMechTokenLen > 0L ) { - nTempLength += ASNDerCalcElementLength( nMechTokenLen, NULL ); + if (nMechTokenLen > 0L) { + nTempLength += ASNDerCalcElementLength(nMechTokenLen, NULL); - // Check for rollover error - if ( nTempLength < nTotalLength ) { - goto xEndTokenTargLength; - } + // Check for rollover error + if (nTempLength < nTotalLength) { + goto xEndTokenTargLength; + } - nTotalLength = nTempLength; + 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 ); + 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; - } + // Check for rollover error + if (nTempLength < nTotalLength) { + goto xEndTokenTargLength; + } - nTotalLength = nTempLength; + nTotalLength = nTempLength; - } // IF MechType is available + } // IF MechType is available // NegResult Element - if ( spnego_negresult_NotUsed != spnegoNegResult ) { - nTempLength += ASNDerCalcElementLength( SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL ); + if (spnego_negresult_NotUsed != spnegoNegResult) { + nTempLength += + ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL); - // Check for rollover error - if ( nTempLength < nTotalLength ) { - goto xEndTokenTargLength; - } + // Check for rollover error + if (nTempLength < nTotalLength) { + goto xEndTokenTargLength; + } - nTotalLength = nTempLength; + nTotalLength = nTempLength; - } // IF negResult is available + } // 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 @@ int CalculateMinSpnegoTargTokenSize( SPNEGO_MECH_OID MechType, *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 @@ xEndTokenTargLength: // //////////////////////////////////////////////////////////////////////////// -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 ); + if (ulMechListMICLen > 0L) { + nTempLength = + ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength); - // Decrease the pbWriteTokenData, now we know the length and - // write it out. + // Decrease the pbWriteTokenData, now we know the length and + // write it out. - pbWriteTokenData -= nTempLength; - nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC, - OCTETSTRING, pbMechListMIC, ulMechListMICLen ); + pbWriteTokenData -= nTempLength; + nTempLength = + ASNDerWriteElement(pbWriteTokenData, + SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC, + ulMechListMICLen); - // Adjust Values and sanity check - nTotalBytesWritten += nTempLength; - nInternalTokenLength -= nTempLength; + // Adjust Values and sanity check + nTotalBytesWritten += nTempLength; + nInternalTokenLength -= nTempLength; - if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { - goto xEndWriteNegTokenTarg; - } + if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) { + goto xEndWriteNegTokenTarg; + } - } // IF MechListMIC is present + } // 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 ) { + if (spnego_mech_oid_NotUsed != MechType) { - nTempLength = ASNDerCalcElementLength( g_stcMechOIDList[MechType].iActualDataLen, - &nInternalLength ); + 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 ); + // 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; + // Adjust Values and sanity check + nTotalBytesWritten += nTempLength; + nInternalTokenLength -= nTempLength; - if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { - goto xEndWriteNegTokenTarg; - } + if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) { + goto xEndWriteNegTokenTarg; + } - } // IF MechType is present + } // IF MechType is present // Neg Result // NegResult Element - if ( spnego_negresult_NotUsed != eNegResult ) { - ucTemp = (unsigned char) eNegResult; + if (spnego_negresult_NotUsed != eNegResult) { + ucTemp = (unsigned char) eNegResult; - nTempLength = ASNDerCalcElementLength( SPNEGO_NEGTARG_MAXLEN_NEGRESULT, &nInternalLength ); + 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 ); + // 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; + // Adjust Values and sanity check + nTotalBytesWritten += nTempLength; + nInternalTokenLength -= nTempLength; - if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { - goto xEndWriteNegTokenTarg; - } + if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) { + goto xEndWriteNegTokenTarg; + } - } // If eNegResult is available + } // 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 @@ int CreateSpnegoTargToken( SPNEGO_MECH_OID MechType, // 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 @@ xEndWriteNegTokenTarg: // //////////////////////////////////////////////////////////////////////////// -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 @@ SPNEGO_TOKEN* AllocEmptySpnegoToken( unsigned char ucCopyData, unsigned long ulF // //////////////////////////////////////////////////////////////////////////// -void FreeSpnegoToken( SPNEGO_TOKEN* pSpnegoToken ) +void +FreeSpnegoToken(SPNEGO_TOKEN * pSpnegoToken) { - if ( NULL != 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; - } + // 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 ); + free(pSpnegoToken); } } @@ -851,9 +873,10 @@ void FreeSpnegoToken( SPNEGO_TOKEN* pSpnegoToken ) // //////////////////////////////////////////////////////////////////////////// -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 @@ void InitSpnegoTokenElementArray( SPNEGO_TOKEN* pSpnegoToken ) // 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 @@ void InitSpnegoTokenElementArray( SPNEGO_TOKEN* pSpnegoToken ) // //////////////////////////////////////////////////////////////////////////// -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 InitSpnegoTokenType( SPNEGO_TOKEN* pSpnegoToken, long* pnTokenLength, // //////////////////////////////////////////////////////////////////////////// -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 @@ int GetSpnegoInitTokenMechList( unsigned char* pbTokenData, int nMechListLength, // // 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 InitSpnegoTokenElementFromBasicType( unsigned char* pbTokenData, int nElemen // //////////////////////////////////////////////////////////////////////////// -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 InitSpnegoTokenElementFromOID( unsigned char* pbTokenData, int nElementLengt // //////////////////////////////////////////////////////////////////////////// -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 @@ int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenD // 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 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 - }; + 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; + 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; + switch (pSpnegoToken->ucTokenType) { + case SPNEGO_TOKEN_INIT: + { + pbElements = abNegTokenInitElements; + } + break; - case SPNEGO_TOKEN_TARG: { - pbElements = abNegTokenTargElements; - } - break; + case SPNEGO_TOKEN_TARG: + { + pbElements = abNegTokenTargElements; + } + break; - } // SWITCH tokentype + } // 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 InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenD // //////////////////////////////////////////////////////////////////////////// -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 FindMechOIDInMechList( SPNEGO_ELEMENT* pSpnegoElement, SPNEGO_MECH_OID MechO // //////////////////////////////////////////////////////////////////////////// -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; + 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 ); + 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 ); + // Adjust for the current OID + pbMechListData += (nLength + nTokenLength); + nBoundaryLength -= (nLength + nTokenLength); - } // WHILE enuming OIDs + } // WHILE enuming OIDs - LOG(("ValidateMechList returned %d\n",nReturn)); + LOG(("ValidateMechList returned %d\n", nReturn)); return nReturn; } @@ -1511,12 +1573,14 @@ int ValidateMechList( unsigned char* pbMechListData, long nBoundaryLength ) // //////////////////////////////////////////////////////////////////////////// -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 IsValidMechOid( SPNEGO_MECH_OID mechOid ) // //////////////////////////////////////////////////////////////////////////// -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 IsValidContextFlags( unsigned char ucContextFlags ) // //////////////////////////////////////////////////////////////////////////// -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 IsValidNegResult( SPNEGO_NEGRESULT negResult ) // //////////////////////////////////////////////////////////////////////////// -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 IsValidSpnegoToken( SPNEGO_TOKEN* pSpnegoToken ) // //////////////////////////////////////////////////////////////////////////// -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 ) { + 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 ); - } + // 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 + } // IF boundary conditions are met - LOG(("IsValidSpnegoElement returned %d\n",nReturn)); + LOG(("IsValidSpnegoElement returned %d\n", nReturn)); return nReturn; } @@ -1673,20 +1743,22 @@ int IsValidSpnegoElement( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoE // //////////////////////////////////////////////////////////////////////////// -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 @@ int CalculateElementArrayIndex( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE s // 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 ) { + if (NULL != pbTokenData && NULL != ppSpnegoToken && 0L != ulLength) { - // - // Allocate the empty token, then initialize the data structure. - // + // + // Allocate the empty token, then initialize the data structure. + // - pSpnegoToken = AllocEmptySpnegoToken( ucCopyData, ulFlags, pbTokenData, ulLength ); + pSpnegoToken = + AllocEmptySpnegoToken(ucCopyData, ulFlags, pbTokenData, ulLength); - if ( NULL != pSpnegoToken ) { + if (NULL != pSpnegoToken) { - // Copy the binary data locally + // Copy the binary data locally - // Initialize the token type - if ( ( nReturn = InitSpnegoTokenType( pSpnegoToken, &nTokenLength, - &nRemainingTokenLength, &pbFirstElement ) ) - == SPNEGO_E_SUCCESS ) { + // 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; - } + // Initialize the element array + if ((nReturn = + InitSpnegoTokenElements(pSpnegoToken, pbFirstElement, + nRemainingTokenLength)) + == SPNEGO_E_SUCCESS) { + *ppSpnegoToken = pSpnegoToken; + } - } // IF Init Token Type + } // IF Init Token Type - // Cleanup on error condition - if ( SPNEGO_E_SUCCESS != nReturn ) { - spnegoFreeData( pSpnegoToken ); - } + // Cleanup on error condition + if (SPNEGO_E_SUCCESS != nReturn) { + spnegoFreeData(pSpnegoToken); + } - } else { - nReturn = SPNEGO_E_OUT_OF_MEMORY; - } + } else { + nReturn = SPNEGO_E_OUT_OF_MEMORY; + } - } // IF Valid parameters + } // IF Valid parameters - LOG(("InitTokenFromBinary returned %d\n",nReturn)); + LOG(("InitTokenFromBinary returned %d\n", nReturn)); return nReturn; } diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.h b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.h index 9308c1f8a9..3f9fed7f8d 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.h +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegoparse.h @@ -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 @@ extern "C" { // 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 + 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 + SPNEGO_ELEMENT_TYPE eElementType; // The Element Type - unsigned char type; // Data Type + unsigned char type; // Data Type - unsigned char* pbData; // Points to actual Data + unsigned char *pbData; // Points to actual Data - unsigned long nDatalength; // Actual Data Length + unsigned long nDatalength; // Actual Data Length } SPNEGO_ELEMENT; @@ -89,18 +91,19 @@ extern "C" { // 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 + 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 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 + 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 @@ extern "C" { // 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 @@ extern "C" { #endif #endif - diff --git a/helpers/negotiate_auth/squid_kerb_auth/squid_compat.h b/helpers/negotiate_auth/squid_kerb_auth/squid_compat.h deleted file mode 100644 index 03523350f2..0000000000 --- a/helpers/negotiate_auth/squid_kerb_auth/squid_compat.h +++ /dev/null @@ -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 */ diff --git a/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c b/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c index 1fd06da4a4..f12674e38c 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c +++ b/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c @@ -29,72 +29,66 @@ /* * Hosted at http://sourceforge.net/projects/squidkerbauth */ -#include "ska_config.h" +#include "config.h" -#if HAVE_STRING_H +#if HAVE_GSSAPI #include -#endif -#if HAVE_STDIO_H #include -#endif -#if HAVE_STDLIB_H #include -#endif -#if HAVE_NETDB_H #include -#endif -#if HAVE_UNISTD_H #include -#endif -#if HAVE_TIME_H #include -#endif -#if HAVE_SYS_TIME_H #include -#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 "getaddrinfo.h" +#include "getnameinfo.h" +#include "util.h" #include "base64.h" -#ifndef HAVE_SPNEGO -#include "spnegohelp/spnegohelp.h" +#if !HAVE_SPNEGO +#include "spnegohelp.h" #endif -#define PROGRAM "squid_kerb_auth" +#if HAVE_HEIMDAL_KERBEROS +#if HAVE_GSSAPI_GSSAPI_H +#include +#elif HAVE_GSSAPI_H +#include +#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 +#elif HAVE_GSSAPI_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_H */ +#if HAVE_GSSAPI_GSSAPI_KRB5_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */ +#if HAVE_GSSAPI_GSSAPI_GENERIC_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */ +#endif /* HAVE_HEIMDAL_KERBEROS */ +#define PROGRAM "squid_kerb_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 +97,551 @@ static const char *LogTime() 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; - - 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); + 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); } - 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; + const unsigned char *spnegoToken = NULL; + size_t spnegoTokenLength = 0; - setbuf(stdout,NULL); - setbuf(stdin,NULL); + 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@DEFAULT_REALM\n"); - exit(0); - default: - fprintf(stderr, "%s| %s: unknown option: -%c.\n", LogTime(), PROGRAM, opt); - } + 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@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); + 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 */ - } - 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; - } + 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 = 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); + + +#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; - } + 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; - } + 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 = output_token.value; - spnegoTokenLength = output_token.length; + 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; - } + 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'; + 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 = 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; } } +#endif /* HAVE_GSSAPI */ diff --git a/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth_test.c b/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth_test.c index 6d509e2f38..f60add2bad 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth_test.c +++ b/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth_test.c @@ -25,52 +25,54 @@ * Hosted at http://sourceforge.net/projects/squidkerbauth */ -#include "ska_config.h" +#include "config.h" -#if HAVE_STRING_H +#if HAVE_GSSAPI #include -#endif -#if HAVE_STDIO_H #include -#endif -#if HAVE_STDLIB_H #include -#endif -#if HAVE_NETDB_H #include -#endif -#if HAVE_UNISTD_H #include -#endif -#if HAVE_TIME_H #include -#endif -#if HAVE_SYS_TIME_H #include -#endif -#if HAVE_ERRNO_H #include -#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 "util.h" + +#if HAVE_HEIMDAL_KERBEROS +#if HAVE_GSSAPI_GSSAPI_H +#include +#elif HAVE_GSSAPI_H +#include +#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 +#elif HAVE_GSSAPI_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_H */ +#if HAVE_GSSAPI_GSSAPI_KRB5_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */ +#if HAVE_GSSAPI_GSSAPI_GENERIC_H +#include +#endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */ +#endif /* HAVE_HEIMDAL_KERBEROS */ #include "base64.h" 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" -static const char *LogTime() +static const char * +LogTime() { struct tm *tm; struct timeval now; @@ -79,132 +81,128 @@ static const char *LogTime() 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; - - 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); + 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); } - 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(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); - - if (check_gss_err(major_status,minor_status,"gss_init_sec_context()") ) - goto cleanup; + 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 (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 = 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 +212,31 @@ cleanup: 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); + 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"); } - Token = (const char *)squid_kerb_proxy_auth(argv[1]); - fprintf(stdout,"Token: %s\n",Token?Token:"NULL"); exit(0); } - +#endif /* HAVE_GSSAPI */