#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
#endif
+#if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#define GSSEAP_UNUSED __attribute__ ((__unused__))
+#else
+#define GSSEAP_UNUSED
+#endif
+
/* util_buffer.c */
OM_uint32
makeStringBuffer(OM_uint32 *minor,
TOK_TYPE_EXPORT_NAME = 0x0401, /* RFC 2743 exported name */
TOK_TYPE_EXPORT_NAME_COMPOSITE = 0x0402, /* exported composite name */
TOK_TYPE_DELETE_CONTEXT = 0x0405, /* RFC 2743 delete context */
- TOK_TYPE_EAP_RESP = 0x0601, /* EAP response */
- TOK_TYPE_EAP_REQ = 0x0602, /* EAP request */
- TOK_TYPE_EXT_REQ = 0x0603, /* GSS EAP extensions request */
- TOK_TYPE_EXT_RESP = 0x0604, /* GSS EAP extensions response */
- TOK_TYPE_GSS_REAUTH = 0x0605, /* GSS EAP fast reauthentication token */
- TOK_TYPE_CONTEXT_ERR = 0x0606, /* context error */
+ TOK_TYPE_INITIATOR_CONTEXT = 0x0601, /* initiator-sent context token */
+ TOK_TYPE_ACCEPTOR_CONTEXT = 0x0602, /* acceptor-sent context token */
};
+/* inner token types and flags */
+#define ITOK_TYPE_NONE 0x00000000
+#define ITOK_TYPE_CONTEXT_ERR 0x00000001 /* critical */
+#define ITOK_TYPE_ACCEPTOR_NAME_REQ 0x00000002 /* TBD */
+#define ITOK_TYPE_ACCEPTOR_NAME_RESP 0x00000003 /* TBD */
+#define ITOK_TYPE_EAP_RESP 0x00000004 /* critical, required, if not reauth */
+#define ITOK_TYPE_EAP_REQ 0x00000005 /* critical, required, if not reauth */
+#define ITOK_TYPE_GSS_CHANNEL_BINDINGS 0x00000006 /* critical, required, if not reauth */
+#define ITOK_TYPE_REAUTH_CREDS 0x00000007 /* optional */
+#define ITOK_TYPE_REAUTH_REQ 0x00000008 /* optional */
+#define ITOK_TYPE_REAUTH_RESP 0x00000009 /* optional */
+#define ITOK_TYPE_VERSION_INFO 0x0000000A /* optional */
+#define ITOK_TYPE_VENDOR_INFO 0x0000000B /* optional */
+
+#define ITOK_FLAG_CRITICAL 0x80000000 /* critical, wire flag */
+#define ITOK_FLAG_VERIFIED 0x40000000 /* verified, API flag */
+
+#define ITOK_TYPE_MASK (~(ITOK_FLAG_CRITICAL | ITOK_FLAG_VERIFIED))
+
OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
krb5_enctype enctype,
krb5_keyblock *pKey);
-/* util_exts.c */
-#define EXT_FLAG_CRITICAL 0x80000000 /* critical, wire flag */
-#define EXT_FLAG_VERIFIED 0x40000000 /* verified, API flag */
-
-#define EXT_TYPE_GSS_CHANNEL_BINDINGS 0x00000000
-#define EXT_TYPE_REAUTH_CREDS 0x00000001
-#define EXT_TYPE_MASK (~(EXT_FLAG_CRITICAL | EXT_FLAG_VERIFIED))
-
-struct gss_eap_extension_provider {
- OM_uint32 type;
- int critical; /* client */
- int required; /* server */
- OM_uint32 (*make)(OM_uint32 *,
- gss_cred_id_t,
- gss_ctx_id_t,
- gss_channel_bindings_t,
- gss_buffer_t);
- OM_uint32 (*verify)(OM_uint32 *,
- gss_cred_id_t,
- gss_ctx_id_t,
- gss_channel_bindings_t,
- const gss_buffer_t);
-};
-
-OM_uint32
-gssEapMakeExtensions(OM_uint32 *minor,
- gss_cred_id_t cred,
- gss_ctx_id_t ctx,
- gss_channel_bindings_t chanBindings,
- gss_buffer_t buffer);
-
-OM_uint32
-gssEapVerifyExtensions(OM_uint32 *minor,
- gss_cred_id_t cred,
- gss_ctx_id_t ctx,
- gss_channel_bindings_t chanBindings,
- const gss_buffer_t buffer);
-
/* util_krb.c */
#ifdef HAVE_HEIMDAL_VERSION
sequenceInit(OM_uint32 *minor, void **vqueue, uint64_t seqnum,
int do_replay, int do_sequence, int wide_nums);
+/* util_sm.c */
+enum gss_eap_state {
+ GSSEAP_STATE_INITIAL = 0x01, /* initial state */
+ GSSEAP_STATE_AUTHENTICATE = 0x02, /* exchange EAP messages */
+ GSSEAP_STATE_INITIATOR_EXTS = 0x04, /* initiator extensions */
+ GSSEAP_STATE_ACCEPTOR_EXTS = 0x08, /* acceptor extensions */
+#ifdef GSSEAP_ENABLE_REAUTH
+ GSSEAP_STATE_REAUTHENTICATE = 0x10, /* GSS reauthentication messages */
+#endif
+ GSSEAP_STATE_ESTABLISHED = 0x20, /* context established */
+ GSSEAP_STATE_ALL = 0x3F
+};
+
+#define GSSEAP_STATE_NEXT(s) ((s) << 1)
+
+#define GSSEAP_SM_STATE(ctx) ((ctx)->state)
+
+#ifdef GSSEAP_DEBUG
+void gssEapSmTransition(gss_ctx_id_t ctx, enum gss_eap_state state);
+#define GSSEAP_SM_TRANSITION(ctx, state) gssEapSmTransition((ctx), (state))
+#else
+#define GSSEAP_SM_TRANSITION(ctx, newstate) do { (ctx)->state = (newstate); } while (0)
+#endif
+
+#define GSSEAP_SM_TRANSITION_NEXT(ctx) GSSEAP_SM_TRANSITION((ctx), GSSEAP_STATE_NEXT(GSSEAP_SM_STATE((ctx))))
+
+/* state machine entry */
+struct gss_eap_sm {
+ OM_uint32 inputTokenType;
+ OM_uint32 outputTokenType;
+ enum gss_eap_state validStates;
+ OM_uint32 itokFlags;
+ OM_uint32 (*processToken)(OM_uint32 *,
+ gss_cred_id_t,
+ gss_ctx_id_t,
+ gss_name_t,
+ gss_OID,
+ OM_uint32,
+ OM_uint32,
+ gss_channel_bindings_t,
+ gss_buffer_t,
+ gss_buffer_t,
+ OM_uint32 *);
+};
+
+/* state machine flags, set by handler */
+#define SM_FLAG_FORCE_SEND_TOKEN 0x00000001 /* send token even if no inner tokens */
+#define SM_FLAG_OUTPUT_TOKEN_CRITICAL 0x00000002 /* output token is critical */
+
+/* state machine flags, set by state machine */
+#define SM_FLAG_INPUT_TOKEN_CRITICAL 0x10000000 /* input token was critical */
+
+#define SM_ITOK_FLAG_REQUIRED 0x00000001 /* received tokens must be present */
+
+OM_uint32
+gssEapSmStep(OM_uint32 *minor,
+ gss_cred_id_t cred,
+ gss_ctx_id_t ctx,
+ gss_name_t target,
+ gss_OID mech,
+ OM_uint32 reqFlags,
+ OM_uint32 timeReq,
+ gss_channel_bindings_t chanBindings,
+ gss_buffer_t inputToken,
+ gss_buffer_t outputToken,
+ struct gss_eap_sm *sm,
+ size_t smCount);
+
+void
+gssEapSmTransition(gss_ctx_id_t ctx, enum gss_eap_state state);
+
/* util_token.c */
+OM_uint32
+gssEapEncodeInnerTokens(OM_uint32 *minor,
+ gss_buffer_set_t extensions,
+ OM_uint32 *types,
+ gss_buffer_t buffer);
+OM_uint32
+gssEapDecodeInnerTokens(OM_uint32 *minor,
+ const gss_buffer_t buffer,
+ gss_buffer_set_t *pExtensions,
+ OM_uint32 **pTypes);
+
size_t
tokenSize(const gss_OID_desc *mech, size_t body_size);