From: Amos Jeffries Date: Fri, 3 Oct 2008 02:25:50 +0000 (+1300) Subject: Import new helper code. X-Git-Tag: SQUID_3_1_0_1~45^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ba4fe07c9fd5f35cd2ca588b9e58ba685e2d2557;p=thirdparty%2Fsquid.git Import new helper code. --- diff --git a/helpers/negotiate_auth/squid_kerb_auth/AUTHORS b/helpers/negotiate_auth/squid_kerb_auth/AUTHORS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helpers/negotiate_auth/squid_kerb_auth/ChangeLog b/helpers/negotiate_auth/squid_kerb_auth/ChangeLog new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helpers/negotiate_auth/squid_kerb_auth/INSTALL b/helpers/negotiate_auth/squid_kerb_auth/INSTALL new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helpers/negotiate_auth/squid_kerb_auth/Makefile.am b/helpers/negotiate_auth/squid_kerb_auth/Makefile.am index c5cc19ba0b..0adff75897 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/Makefile.am +++ b/helpers/negotiate_auth/squid_kerb_auth/Makefile.am @@ -1,25 +1,19 @@ -# -# Makefile for the Squid Object Cache server -# -# $Id: Makefile.am,v 1.2 2008/01/07 15:25:14 hno Exp $ -# +EXTRA_DIST = reconf configure +SUBDIRS = -libexec_PROGRAMS = squid_kerb_auth +bin_PROGRAMS = squid_kerb_auth squid_kerb_auth_test -SPNEGO = spnegohelp/derparse.c spnegohelp/derparse.h spnegohelp/Makefile spnegohelp/spnego.c spnegohelp/spnego.h spnegohelp/spnegohelp.c spnegohelp/spnegohelp.h spnegohelp/spnegoparse.c spnegohelp/spnegoparse.h -SOURCE = squid_kerb_auth.c base64.c base64.h -EXTRA_DIST = readme.txt do.sh +if HAVE_SPNEGO +squid_kerb_auth_SOURCES = squid_kerb_auth.c base64.c +squid_kerb_auth_test_SOURCES = squid_kerb_auth_test.c base64.c +else +squid_kerb_auth_SOURCES = squid_kerb_auth.c base64.c spnegohelp/derparse.c spnegohelp/spnego.c spnegohelp/spnegohelp.c spnegohelp/spnegoparse.c +INCLUDES = -Ispnegohelp +squid_kerb_auth_test_SOURCES = squid_kerb_auth_test.c base64.c +endif -squid_kerb_auth_SOURCES = $(SOURCE) $(SPNEGO) - -CPPFLAGS = $(KERBINC) -I$(srcdir)/spnegohelp -I. -I$(top_srcdir)/include -LDADD = -L$(top_builddir)/lib -lmiscutil $(XTRA_LIBS) $(KERBLIBS) - -# HEIMDAL -#KERBINC = -DHEIMDAL -I/usr/include/heimdal -#KERBLIBS = -lgssapi -lkrb5 -lcom_err -lasn1 -lroken - -# MIT -KERBINC = -KERBLIBS = -lgssapi_krb5 -lkrb5 -lcom_err +squid_kerb_auth_LDFLAGS = +squid_kerb_auth_LDADD = +squid_kerb_auth_test_LDFLAGS = +squid_kerb_auth_test_LDADD = diff --git a/helpers/negotiate_auth/squid_kerb_auth/NEWS b/helpers/negotiate_auth/squid_kerb_auth/NEWS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helpers/negotiate_auth/squid_kerb_auth/readme.txt b/helpers/negotiate_auth/squid_kerb_auth/README similarity index 78% rename from helpers/negotiate_auth/squid_kerb_auth/readme.txt rename to helpers/negotiate_auth/squid_kerb_auth/README index 6af777e974..69c2a6c949 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/readme.txt +++ b/helpers/negotiate_auth/squid_kerb_auth/README @@ -23,24 +23,9 @@ squid_auth_kerb requires either MIT or Heimdal Kerberos libraries and header fil 2 Building and Installation -# Linux: -# -D__LITTLE_ENDIAN__ -# Solaris: -# -D__BIG_ENDIAN__ -# -#DEFINE_SPNEGO=-DHAVE_SPNEGO -#HEIMDAL -# DEFINE="-DHEIMDAL $DEFINE_SPNEGO -D__LITTLE_ENDIAN__" -# INCLUDE=-I/usr/include/heimdal -Ispnegohelp -# LIBS="-lgssapi -lkrb5 -lcom_err -lasn1 -lroken" -#MIT - DEFINE="$DEFINE_SPNEGO -D__LITTLE_ENDIAN__" - INCLUDE=-Ispnegohelp - LIBS="-lgssapi_krb5 -lkrb5 -lcom_err" -# -SPNEGO="spnegohelp/derparse.c spnegohelp/spnego.c spnegohelp/spnegohelp.c spnegohelp/spnegoparse.c" -SOURCE="squid_kerb_auth.c base64.c" -gcc -o squid_kerb_auth $DEFINE $INCLUDE $SOURCE $SPNEGO $LIBS +Run ./configure + +for help use ./configure --help Copy the helper squid_kerb_auth to an apropriate directory. @@ -76,8 +61,6 @@ export KRB5_CONFIG 4 Miscellaneous -The -i options creates informational messages whereas -d creates full debug output - If squid_kerb_auth doesn't determine for some reason the right service principal you can provide it with -s HTTP/fqdn. diff --git a/helpers/negotiate_auth/squid_kerb_auth/base64.c b/helpers/negotiate_auth/squid_kerb_auth/base64.c index 475bcc8ca1..97467e8f1e 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/base64.c +++ b/helpers/negotiate_auth/squid_kerb_auth/base64.c @@ -8,7 +8,7 @@ #include "base64.h" -static void base64_init(void); +static void ska_base64_init(void); static int base64_initialized = 0; #define BASE64_VALUE_SZ 256 @@ -17,7 +17,7 @@ const char base64_code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz static void -base64_init(void) +ska_base64_init(void) { int i; @@ -31,7 +31,7 @@ base64_init(void) base64_initialized = 1; } -void 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; @@ -39,7 +39,7 @@ void base64_decode(char* result, const char *data, int result_size) if (!data) return; if (!base64_initialized) - base64_init(); + ska_base64_init(); val = c = 0; for (j = 0; *data ;data++) { @@ -66,7 +66,7 @@ void base64_decode(char* result, const char *data, int result_size) } /* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */ -void 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; @@ -76,7 +76,7 @@ void base64_encode(char* result, const char *data, int result_size, int data_siz return; if (!base64_initialized) - base64_init(); + ska_base64_init(); while (data_size--) { int c = (unsigned char) *data++; @@ -134,12 +134,12 @@ end: return; } -int base64_encode_len(int len) +int ska_base64_encode_len(int len) { return ((len+2)/3*4)+1; } -int base64_decode_len(const char *data) +int ska_base64_decode_len(const char *data) { int i,j; diff --git a/helpers/negotiate_auth/squid_kerb_auth/base64.h b/helpers/negotiate_auth/squid_kerb_auth/base64.h index ebcb9bc1aa..3e3961e6bd 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/base64.h +++ b/helpers/negotiate_auth/squid_kerb_auth/base64.h @@ -2,8 +2,8 @@ * Markus Moeller has modified the following code from Squid */ -void base64_decode(char* result, const char *data, int result_size); -void 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 base64_encode_len(int len); -int base64_decode_len(const char *data); +int ska_base64_encode_len(int len); +int ska_base64_decode_len(const char *data); diff --git a/helpers/negotiate_auth/squid_kerb_auth/configure.in b/helpers/negotiate_auth/squid_kerb_auth/configure.in new file mode 100644 index 0000000000..7b6eb6ce5f --- /dev/null +++ b/helpers/negotiate_auth/squid_kerb_auth/configure.in @@ -0,0 +1,501 @@ +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.3],[markus_moeller@compuserve.com]) +AM_INIT_AUTOMAKE(squid_kerb_auth,1.0.3) + +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 + +eval ac_p_include=$includedir +CPPFLAGS="$CPPFLAGS -I$ac_p_include -I../../../include" +AC_CACHE_CHECK([for SQUID],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" = x"yes"; 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" +fi + +AC_CONFIG_HEADER(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. + * + * ----------------------------------------------------------------------------- + */ +]) +AH_BOTTOM([ +#ifdef HAVE_HEIMDAL_KERBEROS +#ifdef HAVE_GSSAPI_GSSAPI_H +#include +#elif defined(HAVE_GSSAPI_H) +#include +#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 +#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 +#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 config.h" +sed -e "s/|MAIL|/"$PACKAGE_BUGREPORT"/" config.h > .config.h.tmp +mv .config.h.tmp config.h diff --git a/helpers/negotiate_auth/squid_kerb_auth/do.sh b/helpers/negotiate_auth/squid_kerb_auth/do.sh deleted file mode 100755 index c245c8cb37..0000000000 --- a/helpers/negotiate_auth/squid_kerb_auth/do.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# -# Linux: -# -D__LITTLE_ENDIAN__ -# Solaris: -# -D__BIG_ENDIAN__ -# -CC=gcc -#CFLAGS="-Wall -Wextra -Werror -Wcomment -Wpointer-arith -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement -Wshadow -O2" -CFLAGS="-Wall -Werror -Wcomment -Wpointer-arith -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -O2" -if [ "$1" = "HEIMDAL" ]; then - DEFINE="-DHEIMDAL -D__LITTLE_ENDIAN__" - INCLUDE="-I/usr/include/heimdal -Ispnegohelp" - LIBS="-lgssapi -lkrb5 -lcom_err -lasn1 -lroken" -else -if [ "$1" = "SOLARIS" ]; then -#MIT - CC=cc - CFLAGS="" - DEFINE="-D__BIG_ENDIAN__ -DSOLARIS_11" - INCLUDE="-Ispnegohelp -Iinclude -Iinclude/kerberosv5" - LIBS="-R/usr/lib/gss -L/usr/lib/gss -lgss /usr/lib/gss/mech_krb5.so -lsocket" -else -#MIT - DEFINE="-D__LITTLE_ENDIAN__" - INCLUDE=-Ispnegohelp - LIBS="-lgssapi_krb5 -lkrb5 -lcom_err" -fi -fi -SPNEGO="spnegohelp/derparse.c spnegohelp/spnego.c spnegohelp/spnegohelp.c spnegohelp/spnegoparse.c" -SOURCE="squid_kerb_auth.c base64.c" -$CC -g $CFLAGS -o squid_kerb_auth $DEFINE $INCLUDE $SOURCE $SPNEGO $LIBS diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/Makefile b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/Makefile deleted file mode 100644 index 7fd352c45a..0000000000 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# -# Linux: -# -D__LITTLE_ENDIAN__ -# Solaris: -# -D__BIG_ENDIAN__ -# - -CFLAGS = -fpic - -LIB = libspnegohelp.a -SLIB = libspnegohelp.so - -OBJS = derparse.o spnego.o spnegohelp.o spnegoparse.o - -all: - make `uname` - -debug: - make CFLAGS="$(CFLAGS) -DDEBUG" `uname` - -SunOS: - make CFLAGS="$(CFLAGS) -D__BIG_ENDIAN__" libs - -AIX: - make CFLAGS="$(CFLAGS) -D__BIG_ENDIAN__" libs - -Linux: - make CFLAGS="$(CFLAGS) -D__LITTLE_ENDIAN__" libs - -libs: $(LIB) $(SLIB) - -$(LIB): $(OBJS) - ar -r $(LIB) $(OBJS) - -$(SLIB): $(OBJS) - gcc --shared -o $(SLIB) $(OBJS) - -derparse.o: derparse.c derparse.h spnego.h Makefile - gcc -c $(CFLAGS) derparse.c -o $@ - -spnego.o: spnego.c derparse.h spnego.h spnegoparse.h Makefile - gcc -c $(CFLAGS) spnego.c -o $@ - -spnegoparse.o: spnegoparse.c derparse.h spnego.h spnegoparse.h Makefile - gcc -c $(CFLAGS) spnegoparse.c -o $@ - -spnegohelp.o: spnegohelp.c spnego.h spnegohelp.h Makefile - gcc -c $(CFLAGS) spnegohelp.c -o $@ - -clean: - rm $(OBJS) $(LIB) $(SLIB) diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c index 1cac0a1b1b..8af877dae6 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/derparse.c @@ -91,7 +91,7 @@ int ASNDerGetLength( unsigned char* pbLengthData, long nBoundaryLength, long* pn // Bump by 1 byte pbLengthData++; - #ifdef __LITTLE_ENDIAN__ + #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 @@ -503,7 +503,7 @@ int ASNDerWriteLength( unsigned char* pbData, long nLength ) // Point to where we'll actually write the length pbData++; -#ifdef __LITTLE_ENDIAN__ +#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 diff --git a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c index 6163e1201a..a10bc25c92 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c @@ -1,263 +1,263 @@ -/* ----------------------------------------------------------------------------- - * 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 20747098af..5bcbabea64 100644 --- a/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h +++ b/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h @@ -1,58 +1,58 @@ -/* ----------------------------------------------------------------------------- - * spnegohelp.c declares RFC 2478 SPNEGO GSS-API mechanism APIs. - * - * Author: Frank Balluffi - * - * Copyright (C) 2002-2003. All rights reserved. - * ----------------------------------------------------------------------------- - */ - -#ifndef SPNEGOHELP_H -#define SPNEGOHELP_H - -#ifdef __cplusplus -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); - -#ifdef __cplusplus -} -#endif - -#endif /* SPNEGOHELP_H */ +/* ----------------------------------------------------------------------------- + * spnegohelp.c declares RFC 2478 SPNEGO GSS-API mechanism APIs. + * + * Author: Frank Balluffi + * + * Copyright (C) 2002-2003. All rights reserved. + * ----------------------------------------------------------------------------- + */ + +#ifndef SPNEGOHELP_H +#define SPNEGOHELP_H + +#ifdef __cplusplus +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); + +#ifdef __cplusplus +} +#endif + +#endif /* SPNEGOHELP_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 old mode 100644 new mode 100755 index 2870a13f56..efd5466473 --- a/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c +++ b/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c @@ -19,6 +19,11 @@ * 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. + * * ----------------------------------------------------------------------------- */ /* @@ -32,41 +37,100 @@ #include #include +#include "config.h" + +#ifdef HAVE_SQUID +#ifdef PACKAGE +#undef PACKAGE +#endif +#ifdef PACKAGE_BUGREPORT +#undef PACKAGE_BUGREPORT +#endif +#ifdef PACKAGE_NAME +#undef PACKAGE_NAME +#endif +#ifdef PACKAGE_STRING +#undef PACKAGE_STRING +#endif +#ifdef PACKAGE_TARNAME +#undef PACKAGE_TARNAME +#endif +#ifdef PACKAGE_VERSION +#undef PACKAGE_VERSION +#endif +#ifdef VERSION +#undef VERSION +#endif +#ifdef HAVE_GETADDRINFO_H #include "getaddrinfo.h" +#endif +#ifdef HAVE_GETNAMEINFO_H #include "getnameinfo.h" +#endif +#ifdef HAVE_UTIL_H +#include "util.h" +#endif +#ifdef PACKAGE +#undef PACKAGE +#endif +#ifdef PACKAGE_BUGREPORT +#undef PACKAGE_BUGREPORT +#endif +#ifdef PACKAGE_NAME +#undef PACKAGE_NAME +#endif +#ifdef PACKAGE_STRING +#undef PACKAGE_STRING +#endif +#ifdef PACKAGE_TARNAME +#undef PACKAGE_TARNAME +#endif +#ifdef PACKAGE_VERSION +#undef PACKAGE_VERSION +#endif +#ifdef VERSION +#undef VERSION +#endif +/* + * Reset varibles + */ +#include "config.h" +#endif +#if !defined(HAVE_DECL_XGETADDRINFO) || !HAVE_DECL_XGETADDRINFO +#define xgetaddrinfo getaddrinfo +#endif +#if !defined(HAVE_DECL_XFREEADDRINFO) || !HAVE_DECL_XFREEADDRINFO +#define xfreeaddrinfo freeaddrinfo +#endif +#if !defined(HAVE_DECL_XGAI_STRERROR) || !HAVE_DECL_XGAI_STRERROR +#define xgai_strerror gai_strerror +#endif +#if !defined(HAVE_DECL_XGETNAMEINFO) || !HAVE_DECL_XGETNAMEINFO +#define xgetnameinfo getnameinfo +#endif +#if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC +#define xmalloc malloc +#endif +#if !defined(HAVE_DECL_XSTRDUP) || !HAVE_DECL_XSTRDUP +#define xstrdup strdup +#endif +#if !defined(HAVE_DECL_XFREE) || !HAVE_DECL_XFREE +#define xfree free +#endif #include "base64.h" #ifndef HAVE_SPNEGO #include "spnegohelp.h" #endif -// AYJ: must match the definition in src/auth/negotiate/auth_negotiate.cc -#define MAX_AUTHTOKEN_LEN 32768 - -// AYJ: match define in include/rfc2181.h -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 256 -#endif -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN HOST_NAME_MAX -#endif - #define PROGRAM "squid_kerb_auth" -#ifdef HEIMDAL -#include -#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE -#else -#include -#ifndef SOLARIS_11 -#include -#else -#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE -#endif + +#ifndef MAX_AUTHTOKEN_LEN +#define MAX_AUTHTOKEN_LEN 65535 #endif -#include -int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char* function, int debug, int loging); +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); @@ -81,20 +145,19 @@ static const char *LogTime() gettimeofday(&now, NULL); if (now.tv_sec != last_t) { - tm = localtime(&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; } -// AYJ: this looks like a duplicate of the lib/gethostname function */ char *gethost_name(void) { - char hostname[MAXHOSTNAMELEN]; + char hostname[sysconf(_SC_HOST_NAME_MAX)]; struct addrinfo *hres=NULL, *hres_list; int rc,count; - rc = gethostname(hostname,MAXHOSTNAMELEN); + rc = gethostname(hostname,sysconf(_SC_HOST_NAME_MAX)); if (rc) { fprintf(stderr, "%s| %s: error while resolving hostname '%s'\n", LogTime(), PROGRAM, hostname); @@ -103,7 +166,6 @@ char *gethost_name(void) { 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)); - xfreeaddrinfo(hres); return NULL; } hres_list=hres; @@ -112,7 +174,7 @@ char *gethost_name(void) { 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); @@ -120,11 +182,11 @@ char *gethost_name(void) { } xfreeaddrinfo(hres); - hostname[MAXHOSTNAMELEN]='\0'; - return(strdup(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 loging) { +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; @@ -171,23 +233,28 @@ int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char* fu } gss_release_buffer(&min_stat, &status_string); } - if (debug) + if (debug) fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM, function, buf); - fprintf(stdout, "NA %s failed: %s\n",function, buf); - if (loging) + 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); } + + int main(int argc, char * const argv[]) { char buf[MAX_AUTHTOKEN_LEN]; char *c; int length=0; static int err=0; - int opt, rc, debug=0, loging=0; + int opt, debug=0, log=0; +#ifndef HAVE_SPNEGO + int rc; +#endif OM_uint32 ret_flags=0, spnego_flag=0; char *service_name=(char *)"HTTP",*host_name=NULL; char *token = NULL; @@ -197,12 +264,13 @@ int main(int argc, char * const argv[]) 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_cred_id_t delegated_cred = 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; +#endif const unsigned char *spnegoToken = NULL ; size_t spnegoTokenLength = 0; @@ -215,23 +283,28 @@ int main(int argc, char * const argv[]) debug = 1; break; case 'i': - loging = 1; + log = 1; break; case 's': - service_principal = strdup(optarg); + service_principal = xstrdup(optarg); break; case 'h': - fprintf(stdout, "Usage: \n"); - fprintf(stdout, "squid_kerb_auth -d [-s SPN]\n"); - fprintf(stdout, "SPN = service principal name\n"); - fprintf(stdout, "Can be set to GSS_C_NO_NAME to allow any entry from keytab\n"); - fprintf(stdout, "default SPN is HTTP/fqdn@DEFAULT_REALM\n"); - break; + 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); } } + 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); @@ -239,9 +312,10 @@ int main(int argc, char * const argv[]) 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 = malloc(strlen(service_name)+strlen(host_name)+2); + 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); } @@ -253,8 +327,10 @@ int main(int argc, char * const argv[]) 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); } @@ -268,25 +344,25 @@ int main(int argc, char * const argv[]) if (err) { if (debug) fprintf(stderr, "%s| %s: Oversized message\n", LogTime(), PROGRAM); - fprintf(stdout, "NA Oversized message\n"); + 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?buf:"NULL",length); + 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, "NA Invalid request\n"); + 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, "NA Invalid request\n"); + fprintf(stdout, "BH Invalid request\n"); continue; } @@ -295,37 +371,40 @@ int main(int argc, char * const argv[]) gss_release_buffer(&minor_status, &output_token); gss_release_buffer(&minor_status, &service); gss_release_cred(&minor_status, &server_creds); - gss_release_cred(&minor_status, &delegated_cred); - gss_release_name(&minor_status, &server_name); - gss_release_name(&minor_status, &client_name); - gss_delete_sec_context(&minor_status, &gss_context, NULL); + 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) - free((char *)kerberosToken); + xfree((char *)kerberosToken); kerberosToken=NULL; } if (spnego_flag) { /* Allocated by makeNegTokenTarg, but no matching free function exists.. */ if (spnegoToken) - free((char *)spnegoToken); + xfree((char *)spnegoToken); spnegoToken=NULL; } if (token) { - free(token); + xfree(token); token=NULL; } if (host_name) { - free(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 ( strncmp(buf, "YR", 2) && strncmp(buf, "KK", 2) ) { if (debug) fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(), PROGRAM, buf); - fprintf(stdout, "NA Invalid request\n"); + fprintf(stdout, "BH Invalid request\n"); continue; } if ( !strncmp(buf, "YR", 2) ){ @@ -337,14 +416,16 @@ int main(int argc, char * const argv[]) if (strlen(buf) <= 3) { if (debug) fprintf(stderr, "%s| %s: Invalid negotiate request [%s]\n", LogTime(), PROGRAM, buf); - fprintf(stdout, "NA Invalid negotiate request\n"); + fprintf(stdout, "BH Invalid negotiate request\n"); continue; } - input_token.length = base64_decode_len(buf+3); - input_token.value = malloc(input_token.length); + 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); - base64_decode(input_token.value,buf+3,input_token.length); + ska_base64_decode(input_token.value,buf+3,input_token.length); #ifndef HAVE_SPNEGO @@ -359,16 +440,18 @@ int main(int argc, char * const argv[]) if ( rc < 100 || rc > 199 ) { if (debug) fprintf(stderr, "%s| %s: Invalid GSS-SPNEGO query [%s]\n", LogTime(), PROGRAM, buf); - fprintf(stdout, "NA Invalid GSS-SPNEGO query\n"); + 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, "NA received type %d NTLM token\n",(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); @@ -381,7 +464,7 @@ int main(int argc, char * const argv[]) (!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, "NA received type %d NTLM token\n",(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 @@ -400,13 +483,13 @@ int main(int argc, char * const argv[]) gss_nt_service_name, &server_name); } - if ( check_gss_err(major_status,minor_status,"gss_import_name()",debug,loging) ) + 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,loging) ) + if (check_gss_err(major_status,minor_status,"gss_acquire_cred()",debug,log) ) goto cleanup; major_status = gss_accept_sec_context(&minor_status, @@ -419,7 +502,7 @@ int main(int argc, char * const argv[]) &output_token, &ret_flags, NULL, - &delegated_cred); + NULL); if (output_token.length) { @@ -431,7 +514,7 @@ int main(int argc, char * const argv[]) &spnegoTokenLength))!=0 ) { if (debug) fprintf(stderr, "%s| %s: makeNegTokenTarg failed with rc=%d\n", LogTime(), PROGRAM, rc); - fprintf(stdout, "NA makeNegTokenTarg failed with rc=%d\n",rc); + fprintf(stdout, "BH makeNegTokenTarg failed with rc=%d\n",rc); goto cleanup; } } else { @@ -442,17 +525,17 @@ int main(int argc, char * const argv[]) spnegoToken = output_token.value; spnegoTokenLength = output_token.length; #endif - token = malloc(base64_encode_len(spnegoTokenLength)); + token = xmalloc(ska_base64_encode_len(spnegoTokenLength)); if (token == NULL) { if (debug) fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(), PROGRAM); - fprintf(stdout, "NA Not enough memory\n"); + fprintf(stdout, "BH Not enough memory\n"); goto cleanup; } - base64_encode(token,(const char *)spnegoToken,base64_encode_len(spnegoTokenLength),spnegoTokenLength); + 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,loging) ) + 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) @@ -464,28 +547,28 @@ int main(int argc, char * const argv[]) major_status = gss_display_name(&minor_status, client_name, &output_token, NULL); - if (check_gss_err(major_status,minor_status,"gss_display_name()",debug,loging) ) + if (check_gss_err(major_status,minor_status,"gss_display_name()",debug,log) ) goto cleanup; fprintf(stdout, "AF %s %s\n",token,(char *)output_token.value); if (debug) fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM, token,(char *)output_token.value); - if (loging) + if (log) fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(), PROGRAM, (char *)output_token.value); goto cleanup; } else { - if (check_gss_err(major_status,minor_status,"gss_accept_sec_context()",debug,loging) ) + 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 No token to return to continue\n"); + 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,loging) ) + 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 @@ -493,30 +576,31 @@ int main(int argc, char * const argv[]) fprintf(stdout, "AF %s %s\n","AA==",(char *)output_token.value); if (debug) fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM, "AA==", (char *)output_token.value); - if (loging) + if (log) fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(), PROGRAM, (char *)output_token.value); cleanup: gss_release_buffer(&minor_status, &input_token); gss_release_buffer(&minor_status, &output_token); gss_release_cred(&minor_status, &server_creds); - gss_release_cred(&minor_status, &delegated_cred); - gss_release_name(&minor_status, &server_name); - gss_release_name(&minor_status, &client_name); + 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) - free((char *)kerberosToken); + xfree((char *)kerberosToken); kerberosToken=NULL; } if (spnego_flag) { /* Allocated by makeNegTokenTarg, but no matching free function exists.. */ if (spnegoToken) - free((char *)spnegoToken); + xfree((char *)spnegoToken); spnegoToken=NULL; } if (token) { - free(token); + xfree(token); token=NULL; } continue; 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 new file mode 100644 index 0000000000..2318326dd4 --- /dev/null +++ b/helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth_test.c @@ -0,0 +1,260 @@ +/* + * ----------------------------------------------------------------------------- + * + * Author: Markus Moeller (markus_moeller at compuserve.com) + * + * Copyright (C) 2007 Markus Moeller. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * ----------------------------------------------------------------------------- + */ +/* + * Hosted at http://sourceforge.net/projects/squidkerbauth + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#ifdef HAVE_SQUID +#ifdef PACKAGE +#undef PACKAGE +#endif +#ifdef PACKAGE_BUGREPORT +#undef PACKAGE_BUGREPORT +#endif +#ifdef PACKAGE_NAME +#undef PACKAGE_NAME +#endif +#ifdef PACKAGE_STRING +#undef PACKAGE_STRING +#endif +#ifdef PACKAGE_TARNAME +#undef PACKAGE_TARNAME +#endif +#ifdef PACKAGE_VERSION +#undef PACKAGE_VERSION +#endif +#ifdef VERSION +#undef VERSION +#endif +#ifdef HAVE_UTIL_H +#include "util.h" +#endif +#ifdef PACKAGE +#undef PACKAGE +#endif +#ifdef PACKAGE_BUGREPORT +#undef PACKAGE_BUGREPORT +#endif +#ifdef PACKAGE_NAME +#undef PACKAGE_NAME +#endif +#ifdef PACKAGE_STRING +#undef PACKAGE_STRING +#endif +#ifdef PACKAGE_TARNAME +#undef PACKAGE_TARNAME +#endif +#ifdef PACKAGE_VERSION +#undef PACKAGE_VERSION +#endif +#ifdef VERSION +#undef VERSION +#endif +/* + * Reset varibles + */ +#include "config.h" +#endif +#if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC +#define xmalloc malloc +#endif +#if !defined(HAVE_DECL_XSTRDUP) || !HAVE_DECL_XSTRDUP +#define xstrdup strdup +#endif + +#include "base64.h" + +static const char *LogTime(void); + +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() +{ + struct tm *tm; + struct timeval now; + static time_t last_t = 0; + static char buf[128]; + + gettimeofday(&now, NULL); + if (now.tv_sec != last_t) { + 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"}; +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){ + 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); + } + return(0); +} + +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; + } + + 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); + + 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, +#ifdef HAVE_SPNEGO + gss_mech_spnego, +#else + 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; + + 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); + } + + +cleanup: + gss_delete_sec_context(&minor_status, &gss_context, NULL); + gss_release_buffer(&minor_status, &service); + gss_release_buffer(&minor_status, &input_token); + gss_release_buffer(&minor_status, &output_token); + gss_release_name(&minor_status, &server_name); + + return token; +} + +int main(int argc, char *argv[]) { + + const char *Token; + + if (argc < 1) { + fprintf(stderr, "%s| %s: Error: No proxy server name given\n", LogTime(), PROGRAM); + exit(99); + } + Token = (const char *)squid_kerb_proxy_auth(argv[1]); + fprintf(stdout,"Token: %s\n",Token?Token:"NULL"); + + exit(0); +} +