#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
-scriptversion=2010-11-15.09; # UTC
+scriptversion=2009-10-06.20; # UTC
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010 Free Software
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
# Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# 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, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
-nl='
-'
-
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent tools from complaining about whitespace usage.
-IFS=" "" $nl"
-
-file_conv=
-
-# func_file_conv build_file lazy
-# Convert a $build file to $host form and store it in $file
-# Currently only supports Win32 hosts. If the determined conversion
-# type is listed in (the comma separated) LAZY, no conversion will
-# take place.
-func_file_conv ()
-{
- file=$1
- case $file in
- / | /[!/]*) # absolute file, and not a UNC file
- if test -z "$file_conv"; then
- # lazily determine how to convert abs files
- case `uname -s` in
- MINGW*)
- file_conv=mingw
- ;;
- CYGWIN*)
- file_conv=cygwin
- ;;
- *)
- file_conv=wine
- ;;
- esac
- fi
- case $file_conv/,$2, in
- *,$file_conv,*)
- ;;
- mingw/*)
- file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
- ;;
- cygwin/*)
- file=`cygpath -m "$file" || echo "$file"`
- ;;
- wine/*)
- file=`winepath -w "$file" || echo "$file"`
- ;;
- esac
- ;;
- esac
-}
-
-# func_cl_wrapper cl arg...
-# Adjust compile command to suit cl
-func_cl_wrapper ()
-{
- # Assume a capable shell
- lib_path=
- shared=:
- linker_opts=
- for arg
- do
- if test -n "$eat"; then
- eat=
- else
- case $1 in
- -o)
- # configure might choose to run compile as `compile cc -o foo foo.c'.
- eat=1
- case $2 in
- *.o | *.[oO][bB][jJ])
- func_file_conv "$2"
- set x "$@" -Fo"$file"
- shift
- ;;
- *)
- func_file_conv "$2"
- set x "$@" -Fe"$file"
- shift
- ;;
- esac
- ;;
- -I*)
- func_file_conv "${1#-I}" mingw
- set x "$@" -I"$file"
- shift
- ;;
- -l*)
- lib=${1#-l}
- found=no
- save_IFS=$IFS
- IFS=';'
- for dir in $lib_path $LIB
- do
- IFS=$save_IFS
- if $shared && test -f "$dir/$lib.dll.lib"; then
- found=yes
- set x "$@" "$dir/$lib.dll.lib"
- break
- fi
- if test -f "$dir/$lib.lib"; then
- found=yes
- set x "$@" "$dir/$lib.lib"
- break
- fi
- done
- IFS=$save_IFS
-
- test "$found" != yes && set x "$@" "$lib.lib"
- shift
- ;;
- -L*)
- func_file_conv "${1#-L}"
- if test -z "$lib_path"; then
- lib_path=$file
- else
- lib_path="$lib_path;$file"
- fi
- linker_opts="$linker_opts -LIBPATH:$file"
- ;;
- -static)
- shared=false
- ;;
- -Wl,*)
- arg=${1#-Wl,}
- save_ifs="$IFS"; IFS=','
- for flag in $arg; do
- IFS="$save_ifs"
- linker_opts="$linker_opts $flag"
- done
- IFS="$save_ifs"
- ;;
- -Xlinker)
- eat=1
- linker_opts="$linker_opts $2"
- ;;
- -*)
- set x "$@" "$1"
- shift
- ;;
- *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
- func_file_conv "$1"
- set x "$@" -Tp"$file"
- shift
- ;;
- *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
- func_file_conv "$1" mingw
- set x "$@" "$file"
- shift
- ;;
- *)
- set x "$@" "$1"
- shift
- ;;
- esac
- fi
- shift
- done
- if test -n "$linker_opts"; then
- linker_opts="-link$linker_opts"
- fi
- exec "$@" $linker_opts
- exit 1
-}
-
-eat=
-
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
echo "compile $scriptversion"
exit $?
;;
- cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
- func_cl_wrapper "$@" # Doesn't return...
- ;;
esac
ofile=
cfile=
+eat=
for arg
do
static void
saveStatusInfoNoCopy(OM_uint32 minor, char *message)
{
- struct gss_eap_status_info **next = NULL, *p=NULL;
+ struct gss_eap_status_info **next = NULL, *p = NULL;
struct gss_eap_thread_local_data *tld = gssEapGetThreadLocalData();
if (tld != NULL) {
size_t *pRemain,
krb5_cksumtype *checksumType,
krb5_enctype *pEncryptionType,
- krb5_keyblock *key)
+ krb5_keyblock *pKey)
{
unsigned char *p = *pBuf;
size_t remain = *pRemain;
OM_uint32 encryptionType;
OM_uint32 length;
- gss_buffer_desc tmp;
+ krb5_context krbContext;
+ krb5_keyblock key;
+ krb5_error_code code;
+
+ GSSEAP_KRB_INIT(&krbContext);
+
+ KRB_KEY_INIT(pKey);
if (remain < 12) {
*minor = GSSEAP_TOK_TRUNC;
return GSS_S_DEFECTIVE_TOKEN;
}
- if (load_buffer(&p[12], length, &tmp) == NULL) {
- *minor = ENOMEM;
- return GSS_S_FAILURE;
- }
+ if (encryptionType != ENCTYPE_NULL) {
+ KRB_KEY_INIT(&key);
- KRB_KEY_TYPE(key) = encryptionType;
- KRB_KEY_LENGTH(key) = tmp.length;
- KRB_KEY_DATA(key) = (unsigned char *)tmp.value;
+ KRB_KEY_TYPE(&key) = encryptionType;
+ KRB_KEY_LENGTH(&key) = length;
+ KRB_KEY_DATA(&key) = &p[12];
+
+ code = krb5_copy_keyblock_contents(krbContext, &key, pKey);
+ if (code != 0) {
+ *minor = code;
+ return GSS_S_FAILURE;
+ }
+ }
*pBuf += 12 + length;
*pRemain -= 12 + length;
GSSEAP_KRB_INIT(&krbContext);
- t.length = 0;
- t.data = NULL;
-
- ns.length = 0;
- ns.data = NULL;
+ KRB_DATA_INIT(&t);
+ KRB_DATA_INIT(&ns);
if (prf_key != GSS_C_PRF_KEY_PARTIAL &&
prf_key != GSS_C_PRF_KEY_FULL) {
goto cleanup;
}
+#ifndef HAVE_HEIMDAL_VERSION
+ /* Same API, but different allocation rules, unfortunately. */
t.length = prflen;
t.data = GSSEAP_MALLOC(t.length);
if (t.data == NULL) {
code = ENOMEM;
goto cleanup;
}
+#endif
memcpy((unsigned char *)ns.data + 4, prf_in->value, prf_in->length);
i = 0;
cleanup:
if (code != 0)
gss_release_buffer(&tmpMinor, prf_out);
- krb5_free_data_contents(krbContext, &ns);
+ if (ns.data != NULL) {
+ memset(ns.data, 0, ns.length);
+ GSSEAP_FREE(ns.data);
+ }
+#ifdef HAVE_HEIMDAL_VERSION
krb5_free_data_contents(krbContext, &t);
+#else
+ if (t.data != NULL) {
+ memset(t.data, 0, t.length);
+ GSSEAP_FREE(t.data);
+ }
+#endif
*minor = code;
krb5_keyblock *pKey);
/* util_krb.c */
+
+#ifndef KRB_MALLOC
+/*
+ * If your Kerberos library uses a different allocator to your
+ * GSS mechanism glue, then you might wish to define these in
+ * config.h or elsewhere. This should eventually go away when
+ * we no longer need to allocate memory that is freed by the
+ * Kerberos library.
+ */
+#define KRB_CALLOC calloc
+#define KRB_MALLOC malloc
+#define KRB_FREE free
+#define KRB_REALLOC realloc
+#endif /* KRB_MALLOC */
+
#ifdef HAVE_HEIMDAL_VERSION
#define KRB_TIME_FOREVER ((time_t)~0L)
#define KRB_CRYPTO_CONTEXT(ctx) (krbCrypto)
+#define KRB_DATA_INIT(d) krb5_data_zero((d))
+
#else
#define KRB_TIME_FOREVER KRB5_INT32_MAX
#define KRB_CRYPTO_CONTEXT(ctx) (&(ctx)->rfc3961Key)
+#define KRB_DATA_INIT(d) do { \
+ (d)->magic = KV5M_DATA; \
+ (d)->length = 0; \
+ (d)->data = NULL; \
+ } while (0)
+
#endif /* HAVE_HEIMDAL_VERSION */
#define KRB_KEY_INIT(key) do { \
/* Helper macros */
+#ifndef GSSEAP_MALLOC
#define GSSEAP_CALLOC calloc
#define GSSEAP_MALLOC malloc
#define GSSEAP_FREE free
#define GSSEAP_REALLOC realloc
+#endif
#ifndef GSSAPI_CALLCONV
#define GSSAPI_CALLCONV KRB5_CALLCONV
struct gss_eap_thread_local_data *tld;
*minor = 0;
+ *context = NULL;
tld = gssEapGetThreadLocalData();
if (tld != NULL) {
- *context = tld->krbContext;
- if (*context == NULL) {
- *minor = initKrbContext(context);
- if (*minor == 0)
- tld->krbContext = *context;
+ if (tld->krbContext == NULL) {
+ *minor = initKrbContext(&tld->krbContext);
+ if (*minor != 0)
+ tld->krbContext = NULL;
}
+ *context = tld->krbContext;
+ } else {
+ *minor = GSSEAP_GET_LAST_ERROR();
}
- return *minor == 0 ? GSS_S_COMPLETE : GSS_S_FAILURE;
+
+ GSSEAP_ASSERT(*context != NULL || *minor != 0);
+
+ return (*minor == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
}
/*
* Tn = pseudo-random(KMSK, n || "rfc4121-gss-eap")
* L = output key size
* K = truncate(L, T1 || T2 || .. || Tn)
+ *
+ * The output must be freed by krb5_free_keyblock_contents(),
+ * not GSSEAP_FREE().
*/
OM_uint32
gssEapDeriveRfc3961Key(OM_uint32 *minor,
#ifndef HAVE_HEIMDAL_VERSION
krb5_data data;
#endif
- krb5_data ns, t, prfOut;
+ krb5_data ns, t, derivedKeyData;
krb5_keyblock kd;
krb5_error_code code;
size_t randomLength, keyLength, prfLength;
unsigned char constant[4 + sizeof("rfc4121-gss-eap") - 1], *p;
ssize_t i, remain;
- GSSEAP_ASSERT(encryptionType != ENCTYPE_NULL);
-
- memset(pKey, 0, sizeof(*pKey));
-
GSSEAP_KRB_INIT(&krbContext);
+ GSSEAP_ASSERT(encryptionType != ENCTYPE_NULL);
+ KRB_KEY_INIT(pKey);
KRB_KEY_INIT(&kd);
KRB_KEY_TYPE(&kd) = encryptionType;
- t.data = NULL;
- t.length = 0;
-
- prfOut.data = NULL;
- prfOut.length = 0;
+ KRB_DATA_INIT(&ns);
+ KRB_DATA_INIT(&t);
+ KRB_DATA_INIT(&derivedKeyData);
code = krb5_c_keylengths(krbContext, encryptionType,
&randomLength, &keyLength);
if (code != 0)
goto cleanup;
- KRB_KEY_DATA(&kd) = GSSEAP_MALLOC(keyLength);
- if (KRB_KEY_DATA(&kd) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
- KRB_KEY_LENGTH(&kd) = keyLength;
+ /* Convert EAP MSK into a Kerberos key */
- /* Convert MSK into a Kerberos key */
#ifdef HAVE_HEIMDAL_VERSION
code = krb5_random_to_key(krbContext, encryptionType, inputKey,
MIN(inputKeyLength, randomLength), &kd);
data.length = MIN(inputKeyLength, randomLength);
data.data = (char *)inputKey;
+ KRB_KEY_DATA(&kd) = KRB_MALLOC(keyLength);
+ if (KRB_KEY_DATA(&kd) == NULL) {
+ code = ENOMEM;
+ goto cleanup;
+ }
+ KRB_KEY_LENGTH(&kd) = keyLength;
+
code = krb5_c_random_to_key(krbContext, encryptionType, &data, &kd);
-#endif
+#endif /* HAVE_HEIMDAL_VERSION */
if (code != 0)
goto cleanup;
if (code != 0)
goto cleanup;
+#ifndef HAVE_HEIMDAL_VERSION
+ /* Same API, but different allocation rules, unfortunately. */
t.length = prfLength;
t.data = GSSEAP_MALLOC(t.length);
if (t.data == NULL) {
code = ENOMEM;
goto cleanup;
}
+#endif
- prfOut.length = randomLength;
- prfOut.data = GSSEAP_MALLOC(prfOut.length);
- if (prfOut.data == NULL) {
+ derivedKeyData.length = randomLength;
+ derivedKeyData.data = GSSEAP_MALLOC(derivedKeyData.length);
+ if (derivedKeyData.data == NULL) {
code = ENOMEM;
goto cleanup;
}
- for (i = 0, p = (unsigned char *)prfOut.data, remain = randomLength;
+ for (i = 0, p = (unsigned char *)derivedKeyData.data, remain = randomLength;
remain > 0;
p += t.length, remain -= t.length, i++)
{
/* Finally, convert PRF output into a new key which we will return */
#ifdef HAVE_HEIMDAL_VERSION
+ krb5_free_keyblock_contents(krbContext, &kd);
+ KRB_KEY_INIT(&kd);
+
code = krb5_random_to_key(krbContext, encryptionType,
- prfOut.data, prfOut.length, &kd);
+ derivedKeyData.data, derivedKeyData.length, &kd);
#else
- code = krb5_c_random_to_key(krbContext, encryptionType, &prfOut, &kd);
+ code = krb5_c_random_to_key(krbContext, encryptionType,
+ &derivedKeyData, &kd);
#endif
if (code != 0)
goto cleanup;
*pKey = kd;
- KRB_KEY_DATA(&kd) = NULL;
cleanup:
- if (KRB_KEY_DATA(&kd) != NULL) {
- memset(KRB_KEY_DATA(&kd), 0, KRB_KEY_LENGTH(&kd));
- GSSEAP_FREE(KRB_KEY_DATA(&kd));
- }
+ if (code != 0)
+ krb5_free_keyblock_contents(krbContext, &kd);
+#ifdef HAVE_HEIMDAL_VERSION
+ krb5_free_data_contents(krbContext, &t);
+#else
if (t.data != NULL) {
memset(t.data, 0, t.length);
GSSEAP_FREE(t.data);
}
- if (prfOut.data != NULL) {
- memset(prfOut.data, 0, prfOut.length);
- GSSEAP_FREE(prfOut.data);
+#endif
+ if (derivedKeyData.data != NULL) {
+ memset(derivedKeyData.data, 0, derivedKeyData.length);
+ GSSEAP_FREE(derivedKeyData.data);
}
+
*minor = code;
+
return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
}
if (*minor != 0)
return GSS_S_FAILURE;
#else
- data.length = 0;
- data.data = NULL;
+ KRB_DATA_INIT(&data);
memset(&cksum, 0, sizeof(cksum));
#ifdef HAVE_HEIMDAL_VERSION
if (code == 0 && KRB_PRINC_REALM(krbPrinc) == NULL) {
- KRB_PRINC_REALM(krbPrinc) = GSSEAP_CALLOC(1, sizeof(char));
+ KRB_PRINC_REALM(krbPrinc) = KRB_CALLOC(1, sizeof(char));
if (KRB_PRINC_REALM(krbPrinc) == NULL)
code = ENOMEM;
}
* data and uses this index with TlsSetValue() to store it.
* It can then subsequently be retrieved with TlsGetValue().
*/
-static DWORD tlsIndex;
+static DWORD tlsIndex = TLS_OUT_OF_INDEXES;
/* Access thread-local data */
struct gss_eap_thread_local_data *
gssEapGetThreadLocalData(void)
{
- return TlsGetValue(tlsIndex);
+ struct gss_eap_thread_local_data *tlsData;
+
+ GSSEAP_ASSERT(tlsIndex != TLS_OUT_OF_INDEXES);
+
+ tlsData = TlsGetValue(tlsIndex);
+ if (tlsData == NULL) {
+ tlsData = GSSEAP_CALLOC(1, sizeof(*tlsData));
+ TlsSetValue(tlsIndex, tlsData);
+ }
+
+ return tlsData;
}
BOOL WINAPI
case DLL_THREAD_ATTACH:
/* Initialize the TLS index for this thread. */
tlsData = GSSEAP_CALLOC(1, sizeof(*tlsData));
- if (tlsData != NULL)
- TlsSetValue(tlsIndex, tlsData);
+ if (tlsData == NULL)
+ return FALSE;
+ TlsSetValue(tlsIndex, tlsData);
break;
case DLL_THREAD_DETACH:
/* Release the allocated memory for this thread. */