2
* Copyright (c) 2011, JANET(UK)
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
16
* 3. Neither the name of JANET(UK) nor the names of its contributors
17
* may be used to endorse or promote products derived from this software
18
* without specific prior written permission.
20
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
* Portions Copyright 2003-2010 Massachusetts Institute of Technology.
34
* All Rights Reserved.
36
* Export of this software from the United States of America may
37
* require a specific license from the United States Government.
38
* It is the responsibility of any person or organization contemplating
39
* export to obtain such a license before exporting.
41
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
42
* distribute this software and its documentation for any purpose and
43
* without fee is hereby granted, provided that the above copyright
44
* notice appear in all copies and that both that copyright notice and
45
* this permission notice appear in supporting documentation, and that
46
* the name of M.I.T. not be used in advertising or publicity pertaining
47
* to distribution of the software without specific, written prior
48
* permission. Furthermore if you modify this software you must label
49
* your software as modified software and not distribute it in such a
50
* fashion that it might be confused with the original M.I.T. software.
51
* M.I.T. makes no representations about the suitability of
52
* this software for any purpose. It is provided "as is" without express
53
* or implied warranty.
64
#ifdef HAVE_SYS_PARAM_H
65
#include <sys/param.h>
77
# define inline __inline
79
#define snprintf _snprintf
87
#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
90
#if !defined(WIN32) && !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
91
#define GSSEAP_UNUSED __attribute__ ((__unused__))
98
makeStringBuffer(OM_uint32 *minor,
100
gss_buffer_t buffer);
102
#define makeStringBufferOrCleanup(src, dst) \
104
major = makeStringBuffer((minor), (src), (dst));\
105
if (GSS_ERROR(major)) \
110
bufferToString(OM_uint32 *minor,
111
const gss_buffer_t buffer,
115
duplicateBuffer(OM_uint32 *minor,
116
const gss_buffer_t src,
119
#define duplicateBufferOrCleanup(src, dst) \
121
major = duplicateBuffer((minor), (src), (dst)); \
122
if (GSS_ERROR(major)) \
127
bufferEqual(const gss_buffer_t b1, const gss_buffer_t b2)
129
return (b1->length == b2->length &&
130
memcmp(b1->value, b2->value, b2->length) == 0);
134
bufferEqualString(const gss_buffer_t b1, const char *s)
138
b2.length = strlen(s);
139
b2.value = (char *)s;
141
return bufferEqual(b1, &b2);
146
gssEapSign(krb5_context context,
149
#ifdef HAVE_HEIMDAL_VERSION
154
krb5_keyusage sign_usage,
155
gss_iov_buffer_desc *iov,
159
gssEapVerify(krb5_context context,
162
#ifdef HAVE_HEIMDAL_VERSION
167
krb5_keyusage sign_usage,
168
gss_iov_buffer_desc *iov,
174
gssEapEncodeGssChannelBindings(OM_uint32 *minor,
175
gss_channel_bindings_t chanBindings,
176
gss_buffer_t encodedBindings);
180
#define EAP_EXPORT_CONTEXT_V1 1
182
enum gss_eap_token_type {
183
TOK_TYPE_NONE = 0x0000, /* no token */
184
TOK_TYPE_MIC = 0x0404, /* RFC 4121 MIC token */
185
TOK_TYPE_WRAP = 0x0504, /* RFC 4121 wrap token */
186
TOK_TYPE_EXPORT_NAME = 0x0401, /* RFC 2743 exported name */
187
TOK_TYPE_EXPORT_NAME_COMPOSITE = 0x0402, /* exported composite name */
188
TOK_TYPE_DELETE_CONTEXT = 0x0405, /* RFC 2743 delete context */
189
TOK_TYPE_INITIATOR_CONTEXT = 0x0601, /* initiator-sent context token */
190
TOK_TYPE_ACCEPTOR_CONTEXT = 0x0602, /* acceptor-sent context token */
193
/* inner token types and flags */
194
#define ITOK_TYPE_NONE 0x00000000
195
#define ITOK_TYPE_CONTEXT_ERR 0x00000001 /* critical */
196
#define ITOK_TYPE_ACCEPTOR_NAME_REQ 0x00000002 /* TBD */
197
#define ITOK_TYPE_ACCEPTOR_NAME_RESP 0x00000003 /* TBD */
198
#define ITOK_TYPE_EAP_RESP 0x00000004 /* critical, required, if not reauth */
199
#define ITOK_TYPE_EAP_REQ 0x00000005 /* critical, required, if not reauth */
200
#define ITOK_TYPE_GSS_CHANNEL_BINDINGS 0x00000006 /* critical, required, if not reauth */
201
#define ITOK_TYPE_REAUTH_CREDS 0x00000007 /* optional */
202
#define ITOK_TYPE_REAUTH_REQ 0x00000008 /* optional */
203
#define ITOK_TYPE_REAUTH_RESP 0x00000009 /* optional */
204
#define ITOK_TYPE_VERSION_INFO 0x0000000A /* optional */
205
#define ITOK_TYPE_VENDOR_INFO 0x0000000B /* optional */
206
#define ITOK_TYPE_GSS_FLAGS 0x0000000C /* optional */
207
#define ITOK_TYPE_INITIATOR_MIC 0x0000000D /* critical, required, if not reauth */
208
#define ITOK_TYPE_ACCEPTOR_MIC 0x0000000E /* TBD */
210
#define ITOK_FLAG_CRITICAL 0x80000000 /* critical, wire flag */
211
#define ITOK_FLAG_VERIFIED 0x40000000 /* verified, API flag */
213
#define ITOK_TYPE_MASK (~(ITOK_FLAG_CRITICAL | ITOK_FLAG_VERIFIED))
215
#define GSSEAP_WIRE_FLAGS_MASK ( GSS_C_MUTUAL_FLAG | \
217
GSS_C_IDENTIFY_FLAG | \
218
GSS_C_EXTENDED_ERROR_FLAG )
220
OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
221
OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
224
gssEapMakeToken(OM_uint32 *minor,
226
const gss_buffer_t innerToken,
227
enum gss_eap_token_type tokenType,
228
gss_buffer_t outputToken);
231
gssEapVerifyToken(OM_uint32 *minor,
233
const gss_buffer_t inputToken,
234
enum gss_eap_token_type *tokenType,
235
gss_buffer_t innerInputToken);
238
gssEapContextTime(OM_uint32 *minor,
239
gss_ctx_id_t context_handle,
240
OM_uint32 *time_rec);
243
gssEapMakeTokenMIC(OM_uint32 *minor,
245
gss_buffer_t tokenMIC);
248
gssEapVerifyTokenMIC(OM_uint32 *minor,
250
const gss_buffer_t tokenMIC);
253
OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred);
254
OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred);
257
gssEapPrimaryMechForCred(gss_cred_id_t cred);
260
gssEapAcquireCred(OM_uint32 *minor,
261
const gss_name_t desiredName,
263
const gss_OID_set desiredMechs,
265
gss_cred_id_t *pCred,
266
gss_OID_set *pActualMechs,
270
gssEapSetCredPassword(OM_uint32 *minor,
272
const gss_buffer_t password);
275
gssEapSetCredClientCertificate(OM_uint32 *minor,
277
const gss_buffer_t clientCert,
278
const gss_buffer_t privateKey);
281
gssEapSetCredService(OM_uint32 *minor,
283
const gss_name_t target);
286
gssEapResolveInitiatorCred(OM_uint32 *minor,
287
const gss_cred_id_t cred,
288
const gss_name_t target,
289
gss_cred_id_t *resolvedCred);
291
int gssEapCredAvailable(gss_cred_id_t cred, gss_OID mech);
294
gssEapInquireCred(OM_uint32 *minor,
297
OM_uint32 *pLifetime,
298
gss_cred_usage_t *cred_usage,
299
gss_OID_set *mechanisms);
303
gssEapEncrypt(krb5_context context, int dce_style, size_t ec,
305
#ifdef HAVE_HEIMDAL_VERSION
311
gss_iov_buffer_desc *iov, int iov_count);
314
gssEapDecrypt(krb5_context context, int dce_style, size_t ec,
316
#ifdef HAVE_HEIMDAL_VERSION
322
gss_iov_buffer_desc *iov, int iov_count);
325
gssEapMapCryptoFlag(OM_uint32 type);
328
gssEapLocateIov(gss_iov_buffer_desc *iov,
333
gssEapIovMessageLength(gss_iov_buffer_desc *iov,
336
size_t *assoc_data_length);
339
gssEapReleaseIov(gss_iov_buffer_desc *iov, int iov_count);
342
gssEapIsIntegrityOnly(gss_iov_buffer_desc *iov, int iov_count);
345
gssEapAllocIov(gss_iov_buffer_t iov, size_t size);
348
gssEapDeriveRfc3961Key(OM_uint32 *minor,
349
const unsigned char *key,
351
krb5_enctype enctype,
352
krb5_keyblock *pKey);
358
* If your Kerberos library uses a different allocator to your
359
* GSS mechanism glue, then you might wish to define these in
360
* config.h or elsewhere. This should eventually go away when
361
* we no longer need to allocate memory that is freed by the
364
#define KRB_CALLOC calloc
365
#define KRB_MALLOC malloc
366
#define KRB_FREE free
367
#define KRB_REALLOC realloc
368
#endif /* KRB_MALLOC */
370
#ifdef HAVE_HEIMDAL_VERSION
372
#define KRB_TIME_FOREVER ((time_t)~0L)
374
#define KRB_KEY_TYPE(key) ((key)->keytype)
375
#define KRB_KEY_DATA(key) ((key)->keyvalue.data)
376
#define KRB_KEY_LENGTH(key) ((key)->keyvalue.length)
378
#define KRB_PRINC_LENGTH(princ) ((princ)->name.name_string.len)
379
#define KRB_PRINC_TYPE(princ) ((princ)->name.name_type)
380
#define KRB_PRINC_NAME(princ) ((princ)->name.name_string.val)
381
#define KRB_PRINC_REALM(princ) ((princ)->realm)
383
#define KRB_KT_ENT_KEYBLOCK(e) (&(e)->keyblock)
384
#define KRB_KT_ENT_FREE(c, e) krb5_kt_free_entry((c), (e))
386
#define KRB_CRYPTO_CONTEXT(ctx) (krbCrypto)
388
#define KRB_DATA_INIT(d) krb5_data_zero((d))
390
#define KRB_CHECKSUM_TYPE(c) ((c)->cksumtype)
391
#define KRB_CHECKSUM_LENGTH(c) ((c)->checksum.length)
392
#define KRB_CHECKSUM_DATA(c) ((c)->checksum.data)
394
#define KRB_CHECKSUM_INIT(cksum, type, d) do { \
395
(cksum)->cksumtype = (type); \
396
(cksum)->checksum.length = (d)->length; \
397
(cksum)->checksum.data = (d)->value; \
402
#define KRB_TIME_FOREVER KRB5_INT32_MAX
404
#define KRB_KEY_TYPE(key) ((key)->enctype)
405
#define KRB_KEY_DATA(key) ((key)->contents)
406
#define KRB_KEY_LENGTH(key) ((key)->length)
408
#define KRB_PRINC_LENGTH(princ) (krb5_princ_size(NULL, (princ)))
409
#define KRB_PRINC_TYPE(princ) (krb5_princ_type(NULL, (princ)))
410
#define KRB_PRINC_NAME(princ) (krb5_princ_name(NULL, (princ)))
411
#define KRB_PRINC_REALM(princ) (krb5_princ_realm(NULL, (princ)))
412
#define KRB_PRINC_COMPONENT(princ, component) \
413
(krb5_princ_component(NULL, (princ), (component)))
415
#define KRB_KT_ENT_KEYBLOCK(e) (&(e)->key)
416
#define KRB_KT_ENT_FREE(c, e) krb5_free_keytab_entry_contents((c), (e))
418
#define KRB_CRYPTO_CONTEXT(ctx) (&(ctx)->rfc3961Key)
420
#define KRB_DATA_INIT(d) do { \
421
(d)->magic = KV5M_DATA; \
426
#define KRB_CHECKSUM_TYPE(c) ((c)->checksum_type)
427
#define KRB_CHECKSUM_LENGTH(c) ((c)->length)
428
#define KRB_CHECKSUM_DATA(c) ((c)->contents)
430
#define KRB_CHECKSUM_INIT(cksum, type, d) do { \
431
(cksum)->checksum_type = (type); \
432
(cksum)->length = (d)->length; \
433
(cksum)->contents = (d)->value; \
436
#endif /* HAVE_HEIMDAL_VERSION */
438
#define KRB_KEY_INIT(key) do { \
439
KRB_KEY_TYPE(key) = ENCTYPE_NULL; \
440
KRB_KEY_DATA(key) = NULL; \
441
KRB_KEY_LENGTH(key) = 0; \
444
#define GSSEAP_KRB_INIT(ctx) do { \
445
OM_uint32 tmpMajor; \
447
tmpMajor = gssEapKerberosInit(minor, ctx); \
448
if (GSS_ERROR(tmpMajor)) { \
454
gssEapKerberosInit(OM_uint32 *minor, krb5_context *context);
457
rfc3961ChecksumTypeForKey(OM_uint32 *minor,
459
krb5_cksumtype *cksumtype);
462
krbCryptoLength(krb5_context krbContext,
463
#ifdef HAVE_HEIMDAL_VERSION
464
krb5_crypto krbCrypto,
472
krbPaddingLength(krb5_context krbContext,
473
#ifdef HAVE_HEIMDAL_VERSION
474
krb5_crypto krbCrypto,
482
krbBlockSize(krb5_context krbContext,
483
#ifdef HAVE_HEIMDAL_VERSION
484
krb5_crypto krbCrypto,
491
krbEnctypeToString(krb5_context krbContext,
492
krb5_enctype enctype,
494
gss_buffer_t string);
497
krbMakeAuthDataKdcIssued(krb5_context context,
498
const krb5_keyblock *key,
499
krb5_const_principal issuer,
500
#ifdef HAVE_HEIMDAL_VERSION
501
const AuthorizationData *authdata,
502
AuthorizationData *adKdcIssued
504
krb5_authdata *const *authdata,
505
krb5_authdata ***adKdcIssued
510
krbMakeCred(krb5_context context,
511
krb5_auth_context authcontext,
517
gssEapExportLucidSecContext(OM_uint32 *minor,
519
const gss_OID desiredObject,
520
gss_buffer_set_t *data_set);
523
extern gss_OID GSS_EAP_MECHANISM;
525
#define OID_FLAG_NULL_VALID 0x00000001
526
#define OID_FLAG_FAMILY_MECH_VALID 0x00000002
527
#define OID_FLAG_MAP_NULL_TO_DEFAULT_MECH 0x00000004
528
#define OID_FLAG_MAP_FAMILY_MECH_TO_NULL 0x00000008
531
gssEapCanonicalizeOid(OM_uint32 *minor,
537
gssEapReleaseOid(OM_uint32 *minor, gss_OID *oid);
540
gssEapDefaultMech(OM_uint32 *minor,
544
gssEapIndicateMechs(OM_uint32 *minor,
548
gssEapEnctypeToOid(OM_uint32 *minor,
549
krb5_enctype enctype,
553
gssEapOidToEnctype(OM_uint32 *minor,
555
krb5_enctype *enctype);
558
gssEapIsMechanismOid(const gss_OID oid);
561
gssEapIsConcreteMechanismOid(const gss_OID oid);
564
gssEapValidateMechs(OM_uint32 *minor,
565
const gss_OID_set mechs);
568
gssEapOidToSaslName(const gss_OID oid);
571
gssEapSaslNameToOid(const gss_buffer_t name);
573
/* util_moonshot.c */
575
libMoonshotResolveDefaultIdentity(OM_uint32 *minor,
576
const gss_cred_id_t cred,
580
libMoonshotResolveInitiatorCred(OM_uint32 *minor,
582
const gss_name_t targetName);
585
#define EXPORT_NAME_FLAG_OID 0x1
586
#define EXPORT_NAME_FLAG_COMPOSITE 0x2
587
#define EXPORT_NAME_FLAG_ALLOW_COMPOSITE 0x4
589
OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName);
590
OM_uint32 gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName);
591
OM_uint32 gssEapExportName(OM_uint32 *minor,
592
const gss_name_t name,
593
gss_buffer_t exportedName);
594
OM_uint32 gssEapExportNameInternal(OM_uint32 *minor,
595
const gss_name_t name,
596
gss_buffer_t exportedName,
598
OM_uint32 gssEapImportName(OM_uint32 *minor,
599
const gss_buffer_t input_name_buffer,
600
const gss_OID input_name_type,
601
const gss_OID input_mech_type,
602
gss_name_t *output_name);
603
OM_uint32 gssEapImportNameInternal(OM_uint32 *minor,
604
const gss_buffer_t input_name_buffer,
605
gss_name_t *output_name,
608
gssEapDuplicateName(OM_uint32 *minor,
609
const gss_name_t input_name,
610
gss_name_t *dest_name);
613
gssEapCanonicalizeName(OM_uint32 *minor,
614
const gss_name_t input_name,
615
const gss_OID mech_type,
616
gss_name_t *dest_name);
619
gssEapDisplayName(OM_uint32 *minor,
621
gss_buffer_t output_name_buffer,
622
gss_OID *output_name_type);
624
#define COMPARE_NAME_FLAG_IGNORE_EMPTY_REALMS 0x1
627
gssEapCompareName(OM_uint32 *minor,
635
composeOid(OM_uint32 *minor_status,
642
decomposeOid(OM_uint32 *minor_status,
649
duplicateOid(OM_uint32 *minor_status,
650
const gss_OID_desc * const oid,
654
duplicateOidSet(OM_uint32 *minor,
655
const gss_OID_set src,
659
oidEqual(const gss_OID_desc *o1, const gss_OID_desc *o2)
661
if (o1 == GSS_C_NO_OID)
662
return (o2 == GSS_C_NO_OID);
663
else if (o2 == GSS_C_NO_OID)
664
return (o1 == GSS_C_NO_OID);
666
return (o1->length == o2->length &&
667
memcmp(o1->elements, o2->elements, o1->length) == 0);
670
/* util_ordering.c */
672
sequenceInternalize(OM_uint32 *minor,
678
sequenceExternalize(OM_uint32 *minor,
684
sequenceSize(void *vqueue);
687
sequenceFree(OM_uint32 *minor, void **vqueue);
690
sequenceCheck(OM_uint32 *minor, void **vqueue, uint64_t seqnum);
693
sequenceInit(OM_uint32 *minor, void **vqueue, uint64_t seqnum,
694
int do_replay, int do_sequence, int wide_nums);
698
GSSEAP_STATE_INITIAL = 0x01, /* initial state */
699
GSSEAP_STATE_AUTHENTICATE = 0x02, /* exchange EAP messages */
700
GSSEAP_STATE_INITIATOR_EXTS = 0x04, /* initiator extensions */
701
GSSEAP_STATE_ACCEPTOR_EXTS = 0x08, /* acceptor extensions */
702
#ifdef GSSEAP_ENABLE_REAUTH
703
GSSEAP_STATE_REAUTHENTICATE = 0x10, /* GSS reauthentication messages */
705
GSSEAP_STATE_ESTABLISHED = 0x20, /* context established */
706
GSSEAP_STATE_ALL = 0x3F
709
#define GSSEAP_STATE_NEXT(s) ((s) << 1)
711
#define GSSEAP_SM_STATE(ctx) ((ctx)->state)
714
void gssEapSmTransition(gss_ctx_id_t ctx, enum gss_eap_state state);
715
#define GSSEAP_SM_TRANSITION(ctx, state) gssEapSmTransition((ctx), (state))
717
#define GSSEAP_SM_TRANSITION(ctx, newstate) do { (ctx)->state = (newstate); } while (0)
720
#define GSSEAP_SM_TRANSITION_NEXT(ctx) GSSEAP_SM_TRANSITION((ctx), GSSEAP_STATE_NEXT(GSSEAP_SM_STATE((ctx))))
722
/* state machine entry */
724
OM_uint32 inputTokenType;
725
OM_uint32 outputTokenType;
726
enum gss_eap_state validStates;
728
OM_uint32 (*processToken)(OM_uint32 *,
735
gss_channel_bindings_t,
741
/* state machine flags, set by handler */
742
#define SM_FLAG_FORCE_SEND_TOKEN 0x00000001 /* send token even if no inner tokens */
743
#define SM_FLAG_OUTPUT_TOKEN_CRITICAL 0x00000002 /* output token is critical */
745
/* state machine flags, set by state machine */
746
#define SM_FLAG_INPUT_TOKEN_CRITICAL 0x10000000 /* input token was critical */
748
#define SM_ITOK_FLAG_REQUIRED 0x00000001 /* received tokens must be present */
751
gssEapSmStep(OM_uint32 *minor,
758
gss_channel_bindings_t chanBindings,
759
gss_buffer_t inputToken,
760
gss_buffer_t outputToken,
761
struct gss_eap_sm *sm,
765
gssEapSmTransition(gss_ctx_id_t ctx, enum gss_eap_state state);
768
struct gss_eap_token_buffer_set {
769
gss_buffer_set_desc buffers; /* pointers only */
774
gssEapEncodeInnerTokens(OM_uint32 *minor,
775
struct gss_eap_token_buffer_set *tokens,
776
gss_buffer_t buffer);
778
gssEapDecodeInnerTokens(OM_uint32 *minor,
779
const gss_buffer_t buffer,
780
struct gss_eap_token_buffer_set *tokens);
783
gssEapReleaseInnerTokens(OM_uint32 *minor,
784
struct gss_eap_token_buffer_set *tokens,
788
gssEapAllocInnerTokens(OM_uint32 *minor,
790
struct gss_eap_token_buffer_set *tokens);
793
tokenSize(const gss_OID_desc *mech, size_t body_size);
796
makeTokenHeader(const gss_OID_desc *mech,
799
enum gss_eap_token_type tok_type);
802
verifyTokenHeader(OM_uint32 *minor,
805
unsigned char **buf_in,
807
enum gss_eap_token_type *ret_tok_type);
810
#ifndef GSSEAP_MALLOC
812
#include <gssapi/gssapi_alloc.h>
813
#define GSSEAP_MALLOC gssalloc_malloc
814
#define GSSEAP_CALLOC gssalloc_calloc
815
#define GSSEAP_FREE gssalloc_free
816
#define GSSEAP_REALLOC gssalloc_realloc
818
#define GSSEAP_CALLOC calloc
819
#define GSSEAP_MALLOC malloc
820
#define GSSEAP_FREE free
821
#define GSSEAP_REALLOC realloc
823
#endif /* !GSSEAP_MALLOC */
825
#ifndef GSSAPI_CALLCONV
826
#define GSSAPI_CALLCONV KRB5_CALLCONV
829
#ifndef GSSEAP_ASSERT
831
#define GSSEAP_ASSERT(x) assert((x))
832
#endif /* !GSSEAP_ASSERT */
835
#define GSSEAP_CONSTRUCTOR
836
#define GSSEAP_DESTRUCTOR
838
#define GSSEAP_CONSTRUCTOR __attribute__((constructor))
839
#define GSSEAP_DESTRUCTOR __attribute__((destructor))
842
#define GSSEAP_NOT_IMPLEMENTED do { \
843
GSSEAP_ASSERT(0 && "not implemented"); \
845
return GSS_S_FAILURE; \
852
#define GSSEAP_GET_LAST_ERROR() (GetLastError()) /* XXX FIXME */
854
#define GSSEAP_MUTEX CRITICAL_SECTION
855
#define GSSEAP_MUTEX_INIT(m) (InitializeCriticalSection((m)), 0)
856
#define GSSEAP_MUTEX_DESTROY(m) DeleteCriticalSection((m))
857
#define GSSEAP_MUTEX_LOCK(m) EnterCriticalSection((m))
858
#define GSSEAP_MUTEX_UNLOCK(m) LeaveCriticalSection((m))
859
#define GSSEAP_ONCE_LEAVE do { return TRUE; } while (0)
861
/* Thread-local is handled separately */
863
#define GSSEAP_THREAD_ONCE INIT_ONCE
864
#define GSSEAP_ONCE_CALLBACK(cb) BOOL CALLBACK cb(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
865
#define GSSEAP_ONCE(o, i) InitOnceExecuteOnce((o), (i), NULL, NULL)
866
#define GSSEAP_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
872
#define GSSEAP_GET_LAST_ERROR() (errno)
874
#define GSSEAP_MUTEX pthread_mutex_t
875
#define GSSEAP_MUTEX_INIT(m) pthread_mutex_init((m), NULL)
876
#define GSSEAP_MUTEX_DESTROY(m) pthread_mutex_destroy((m))
877
#define GSSEAP_MUTEX_LOCK(m) pthread_mutex_lock((m))
878
#define GSSEAP_MUTEX_UNLOCK(m) pthread_mutex_unlock((m))
880
#define GSSEAP_THREAD_KEY pthread_key_t
881
#define GSSEAP_KEY_CREATE(k, d) pthread_key_create((k), (d))
882
#define GSSEAP_GETSPECIFIC(k) pthread_getspecific((k))
883
#define GSSEAP_SETSPECIFIC(k, d) pthread_setspecific((k), (d))
885
#define GSSEAP_THREAD_ONCE pthread_once_t
886
#define GSSEAP_ONCE_CALLBACK(cb) void cb(void)
887
#define GSSEAP_ONCE(o, i) pthread_once((o), (i))
888
#define GSSEAP_ONCE_INITIALIZER PTHREAD_ONCE_INIT
889
#define GSSEAP_ONCE_LEAVE do { } while (0)
893
/* Helper functions */
895
store_uint16_be(uint16_t val, void *vp)
897
unsigned char *p = (unsigned char *)vp;
899
p[0] = (val >> 8) & 0xff;
900
p[1] = (val ) & 0xff;
903
static inline uint16_t
904
load_uint16_be(const void *cvp)
906
const unsigned char *p = (const unsigned char *)cvp;
908
return (p[1] | (p[0] << 8));
912
store_uint32_be(uint32_t val, void *vp)
914
unsigned char *p = (unsigned char *)vp;
916
p[0] = (val >> 24) & 0xff;
917
p[1] = (val >> 16) & 0xff;
918
p[2] = (val >> 8) & 0xff;
919
p[3] = (val ) & 0xff;
922
static inline uint32_t
923
load_uint32_be(const void *cvp)
925
const unsigned char *p = (const unsigned char *)cvp;
927
return (p[3] | (p[2] << 8)
928
| ((uint32_t) p[1] << 16)
929
| ((uint32_t) p[0] << 24));
933
store_uint64_be(uint64_t val, void *vp)
935
unsigned char *p = (unsigned char *)vp;
937
p[0] = (unsigned char)((val >> 56) & 0xff);
938
p[1] = (unsigned char)((val >> 48) & 0xff);
939
p[2] = (unsigned char)((val >> 40) & 0xff);
940
p[3] = (unsigned char)((val >> 32) & 0xff);
941
p[4] = (unsigned char)((val >> 24) & 0xff);
942
p[5] = (unsigned char)((val >> 16) & 0xff);
943
p[6] = (unsigned char)((val >> 8) & 0xff);
944
p[7] = (unsigned char)((val ) & 0xff);
947
static inline uint64_t
948
load_uint64_be(const void *cvp)
950
const unsigned char *p = (const unsigned char *)cvp;
952
return ((uint64_t)load_uint32_be(p) << 32) | load_uint32_be(p + 4);
955
static inline unsigned char *
956
store_buffer(gss_buffer_t buffer, void *vp, int wide_nums)
958
unsigned char *p = (unsigned char *)vp;
961
store_uint64_be(buffer->length, p);
964
store_uint32_be(buffer->length, p);
968
if (buffer->value != NULL) {
969
memcpy(p, buffer->value, buffer->length);
976
static inline unsigned char *
977
load_buffer(const void *cvp, size_t length, gss_buffer_t buffer)
980
buffer->value = GSSEAP_MALLOC(length);
981
if (buffer->value == NULL)
983
buffer->length = length;
984
memcpy(buffer->value, cvp, length);
985
return (unsigned char *)cvp + length;
988
static inline unsigned char *
989
store_oid(gss_OID oid, void *vp)
993
if (oid != GSS_C_NO_OID) {
994
buf.length = oid->length;
995
buf.value = oid->elements;
1001
return store_buffer(&buf, vp, FALSE);
1005
krbDataToGssBuffer(krb5_data *data, gss_buffer_t buffer)
1007
buffer->value = (void *)data->data;
1008
buffer->length = data->length;
1012
krbPrincComponentToGssBuffer(krb5_principal krbPrinc,
1013
int index, gss_buffer_t buffer)
1015
if (KRB_PRINC_LENGTH(krbPrinc) <= index) {
1016
buffer->value = NULL;
1019
#ifdef HAVE_HEIMDAL_VERSION
1020
buffer->value = (void *)KRB_PRINC_NAME(krbPrinc)[index];
1021
buffer->length = strlen((char *)buffer->value);
1023
buffer->value = (void *)krb5_princ_component(NULL, krbPrinc, index)->data;
1024
buffer->length = krb5_princ_component(NULL, krbPrinc, index)->length;
1025
#endif /* HAVE_HEIMDAL_VERSION */
1029
static inline krb5_error_code
1030
krbPrincUnparseServiceSpecifics(krb5_context krbContext, krb5_principal krbPrinc,
1031
gss_buffer_t nameBuf)
1033
krb5_error_code result = 0;
1034
if (KRB_PRINC_LENGTH(krbPrinc) > 2) {
1035
/* Acceptor-Service-Specific */
1036
krb5_principal_data ssiPrinc = *krbPrinc;
1039
KRB_PRINC_LENGTH(&ssiPrinc) -= 2;
1040
KRB_PRINC_NAME(&ssiPrinc) += 2;
1042
result = krb5_unparse_name_flags(krbContext, &ssiPrinc,
1043
KRB5_PRINCIPAL_UNPARSE_NO_REALM, &ssi);
1047
nameBuf->value = ssi;
1048
nameBuf->length = strlen(ssi);
1050
nameBuf->value = NULL;
1051
nameBuf->length = 0;
1058
krbFreeUnparsedName(krb5_context krbContext, gss_buffer_t nameBuf)
1060
#ifdef HAVE_HEIMDAL_VERSION
1061
krb5_xfree((char *) nameBuf->value);
1063
krb5_free_unparsed_name(krbContext, (char *)(nameBuf->value));
1065
nameBuf->value = NULL;
1066
nameBuf->length = 0;
1070
krbPrincRealmToGssBuffer(krb5_principal krbPrinc, gss_buffer_t buffer)
1072
#ifdef HAVE_HEIMDAL_VERSION
1073
buffer->value = (void *)KRB_PRINC_REALM(krbPrinc);
1074
buffer->length = strlen((char *)buffer->value);
1076
krbDataToGssBuffer(KRB_PRINC_REALM(krbPrinc), buffer);
1081
gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data)
1083
data->data = (char *)buffer->value;
1084
data->length = buffer->length;
1088
struct gss_eap_status_info;
1090
struct gss_eap_thread_local_data {
1091
krb5_context krbContext;
1092
struct gss_eap_status_info *statusInfo;
1095
struct gss_eap_thread_local_data *
1096
gssEapGetThreadLocalData(void);
1099
gssEapDestroyStatusInfo(struct gss_eap_status_info *status);
1102
gssEapDestroyKrbContext(krb5_context context);
1108
#ifdef GSSEAP_ENABLE_ACCEPTOR
1109
#include "util_json.h"
1110
#include "util_attr.h"
1111
#include "util_base64.h"
1112
#endif /* GSSEAP_ENABLE_ACCEPTOR */
1113
#ifdef GSSEAP_ENABLE_REAUTH
1114
#include "util_reauth.h"
1117
#endif /* _UTIL_H_ */