X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=mech_eap%2Futil.h;h=9a606ab93b17b459eca833ef19ab9eceb4d204ba;hb=d81b9e4605c7bd3da62f3679effe124778592b13;hp=2242735279e04b09e242513a0d1a658e1d4243c5;hpb=5229ab0c335b489d4c1125e3eb44ef1d6c92fb4e;p=mech_eap.git diff --git a/mech_eap/util.h b/mech_eap/util.h index 2242735..9a606ab 100644 --- a/mech_eap/util.h +++ b/mech_eap/util.h @@ -61,12 +61,24 @@ #ifndef _UTIL_H_ #define _UTIL_H_ 1 +#ifdef HAVE_SYS_PARAM_H #include +#endif +#ifdef HAVE_STDINT_H +#include +#endif #include #include #include +#ifdef WIN32 +# ifndef __cplusplus +# define inline __inline +# endif +#define snprintf _snprintf +#endif + #ifdef __cplusplus extern "C" { #endif @@ -75,7 +87,7 @@ extern "C" { #define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) #endif -#if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +#if !defined(WIN32) && !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) #define GSSEAP_UNUSED __attribute__ ((__unused__)) #else #define GSSEAP_UNUSED @@ -200,7 +212,10 @@ enum gss_eap_token_type { #define ITOK_TYPE_MASK (~(ITOK_FLAG_CRITICAL | ITOK_FLAG_VERIFIED)) -#define GSSEAP_WIRE_FLAGS_MASK GSS_C_MUTUAL_FLAG +#define GSSEAP_WIRE_FLAGS_MASK ( GSS_C_MUTUAL_FLAG | \ + GSS_C_DCE_STYLE | \ + GSS_C_IDENTIFY_FLAG | \ + GSS_C_EXTENDED_ERROR_FLAG ) OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx); OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx); @@ -331,6 +346,21 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor, 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) @@ -349,6 +379,18 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor, #define KRB_CRYPTO_CONTEXT(ctx) (krbCrypto) +#define KRB_DATA_INIT(d) krb5_data_zero((d)) + +#define KRB_CHECKSUM_TYPE(c) ((c)->cksumtype) +#define KRB_CHECKSUM_LENGTH(c) ((c)->checksum.length) +#define KRB_CHECKSUM_DATA(c) ((c)->checksum.data) + +#define KRB_CHECKSUM_INIT(cksum, type, d) do { \ + (cksum)->cksumtype = (type); \ + (cksum)->checksum.length = (d)->length; \ + (cksum)->checksum.data = (d)->value; \ + } while (0) + #else #define KRB_TIME_FOREVER KRB5_INT32_MAX @@ -361,12 +403,30 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor, #define KRB_PRINC_TYPE(princ) (krb5_princ_type(NULL, (princ))) #define KRB_PRINC_NAME(princ) (krb5_princ_name(NULL, (princ))) #define KRB_PRINC_REALM(princ) (krb5_princ_realm(NULL, (princ))) +#define KRB_PRINC_COMPONENT(princ, component) \ + (krb5_princ_component(NULL, (princ), (component))) #define KRB_KT_ENT_KEYBLOCK(e) (&(e)->key) #define KRB_KT_ENT_FREE(c, e) krb5_free_keytab_entry_contents((c), (e)) #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) + +#define KRB_CHECKSUM_TYPE(c) ((c)->checksum_type) +#define KRB_CHECKSUM_LENGTH(c) ((c)->length) +#define KRB_CHECKSUM_DATA(c) ((c)->contents) + +#define KRB_CHECKSUM_INIT(cksum, type, d) do { \ + (cksum)->checksum_type = (type); \ + (cksum)->length = (d)->length; \ + (cksum)->contents = (d)->value; \ + } while (0) + #endif /* HAVE_HEIMDAL_VERSION */ #define KRB_KEY_INIT(key) do { \ @@ -555,10 +615,13 @@ gssEapDisplayName(OM_uint32 *minor, gss_buffer_t output_name_buffer, gss_OID *output_name_type); +#define COMPARE_NAME_FLAG_IGNORE_EMPTY_REALMS 0x1 + OM_uint32 gssEapCompareName(OM_uint32 *minor, gss_name_t name1, gss_name_t name2, + OM_uint32 flags, int *name_equal); /* util_oid.c */ @@ -738,23 +801,71 @@ verifyTokenHeader(OM_uint32 *minor, enum gss_eap_token_type *ret_tok_type); /* Helper macros */ - +#ifndef GSSEAP_MALLOC +#if _WIN32 +#include +#define GSSEAP_MALLOC gssalloc_malloc +#define GSSEAP_CALLOC gssalloc_calloc +#define GSSEAP_FREE gssalloc_free +#define GSSEAP_REALLOC gssalloc_realloc +#else #define GSSEAP_CALLOC calloc #define GSSEAP_MALLOC malloc #define GSSEAP_FREE free #define GSSEAP_REALLOC realloc +#endif /* _WIN32 */ +#endif /* !GSSEAP_MALLOC */ + +#ifndef GSSAPI_CALLCONV +#define GSSAPI_CALLCONV KRB5_CALLCONV +#endif + +#ifndef GSSEAP_ASSERT +#include +#define GSSEAP_ASSERT(x) assert((x)) +#endif /* !GSSEAP_ASSERT */ + +#ifdef WIN32 +#define GSSEAP_CONSTRUCTOR +#define GSSEAP_DESTRUCTOR +#else +#define GSSEAP_CONSTRUCTOR __attribute__((constructor)) +#define GSSEAP_DESTRUCTOR __attribute__((destructor)) +#endif #define GSSEAP_NOT_IMPLEMENTED do { \ - assert(0 && "not implemented"); \ + GSSEAP_ASSERT(0 && "not implemented"); \ *minor = ENOSYS; \ return GSS_S_FAILURE; \ } while (0) +#ifdef WIN32 + +#include + +#define GSSEAP_GET_LAST_ERROR() (GetLastError()) /* XXX FIXME */ + +#define GSSEAP_MUTEX CRITICAL_SECTION +#define GSSEAP_MUTEX_INIT(m) (InitializeCriticalSection((m)), 0) +#define GSSEAP_MUTEX_DESTROY(m) DeleteCriticalSection((m)) +#define GSSEAP_MUTEX_LOCK(m) EnterCriticalSection((m)) +#define GSSEAP_MUTEX_UNLOCK(m) LeaveCriticalSection((m)) +#define GSSEAP_ONCE_LEAVE do { return TRUE; } while (0) + +/* Thread-local is handled separately */ + +#define GSSEAP_THREAD_ONCE INIT_ONCE +#define GSSEAP_ONCE_CALLBACK(cb) BOOL CALLBACK cb(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) +#define GSSEAP_ONCE(o, i) InitOnceExecuteOnce((o), (i), NULL, NULL) +#define GSSEAP_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT + +#else + #include -#define GSSEAP_MUTEX pthread_mutex_t -#define GSSEAP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define GSSEAP_GET_LAST_ERROR() (errno) +#define GSSEAP_MUTEX pthread_mutex_t #define GSSEAP_MUTEX_INIT(m) pthread_mutex_init((m), NULL) #define GSSEAP_MUTEX_DESTROY(m) pthread_mutex_destroy((m)) #define GSSEAP_MUTEX_LOCK(m) pthread_mutex_lock((m)) @@ -766,8 +877,12 @@ verifyTokenHeader(OM_uint32 *minor, #define GSSEAP_SETSPECIFIC(k, d) pthread_setspecific((k), (d)) #define GSSEAP_THREAD_ONCE pthread_once_t +#define GSSEAP_ONCE_CALLBACK(cb) void cb(void) #define GSSEAP_ONCE(o, i) pthread_once((o), (i)) #define GSSEAP_ONCE_INITIALIZER PTHREAD_ONCE_INIT +#define GSSEAP_ONCE_LEAVE do { } while (0) + +#endif /* WIN32 */ /* Helper functions */ static inline void @@ -891,13 +1006,54 @@ static inline void krbPrincComponentToGssBuffer(krb5_principal krbPrinc, int index, gss_buffer_t buffer) { + if (KRB_PRINC_LENGTH(krbPrinc) < index) { + buffer->value = NULL; + buffer->length = 0; + } else { #ifdef HAVE_HEIMDAL_VERSION - buffer->value = (void *)KRB_PRINC_NAME(krbPrinc)[index]; - buffer->length = strlen((char *)buffer->value); + buffer->value = (void *)KRB_PRINC_NAME(krbPrinc)[index]; + buffer->length = strlen((char *)buffer->value); #else - buffer->value = (void *)krb5_princ_component(NULL, krbPrinc, index)->data; - buffer->length = krb5_princ_component(NULL, krbPrinc, index)->length; + buffer->value = (void *)krb5_princ_component(NULL, krbPrinc, index)->data; + buffer->length = krb5_princ_component(NULL, krbPrinc, index)->length; #endif /* HAVE_HEIMDAL_VERSION */ + } +} + +static inline krb5_error_code +krbPrincUnparseServiceSpecifics(krb5_context krbContext, krb5_principal krbPrinc, + gss_buffer_t nameBuf) +{ + krb5_error_code result = 0; + if (KRB_PRINC_LENGTH(krbPrinc) > 2) { + /* Acceptor-Service-Specific */ + krb5_principal_data ssiPrinc = *krbPrinc; + char *ssi; + + KRB_PRINC_LENGTH(&ssiPrinc) -= 2; + KRB_PRINC_NAME(&ssiPrinc) += 2; + + result = krb5_unparse_name_flags(krbContext, &ssiPrinc, + KRB5_PRINCIPAL_UNPARSE_NO_REALM, &ssi); + if (result != 0) + return result; + + nameBuf->value = ssi; + nameBuf->length = strlen(ssi); + } else { + nameBuf->value = NULL; + nameBuf->length = 0; + } + + return result; +} + +static inline void +krbFreeUnparsedName(krb5_context krbContext, gss_buffer_t nameBuf) +{ + krb5_free_unparsed_name(krbContext, (char *)(nameBuf->value)); + nameBuf->value = NULL; + nameBuf->length = 0; } static inline void @@ -918,13 +1074,32 @@ gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data) data->length = buffer->length; } +/* util_tld.c */ +struct gss_eap_status_info; + +struct gss_eap_thread_local_data { + krb5_context krbContext; + struct gss_eap_status_info *statusInfo; +}; + +struct gss_eap_thread_local_data * +gssEapGetThreadLocalData(void); + +void +gssEapDestroyStatusInfo(struct gss_eap_status_info *status); + +void +gssEapDestroyKrbContext(krb5_context context); + #ifdef __cplusplus } #endif +#ifdef GSSEAP_ENABLE_ACCEPTOR #include "util_json.h" #include "util_attr.h" #include "util_base64.h" +#endif /* GSSEAP_ENABLE_ACCEPTOR */ #ifdef GSSEAP_ENABLE_REAUTH #include "util_reauth.h" #endif