From 2b2f711f2addee052253e4ff54fb7cdf3e20c0ae Mon Sep 17 00:00:00 2001 From: Kevin Coffman Date: Wed, 1 Nov 2006 22:40:30 +0000 Subject: Modify the preath plugin interface so that a plugin's context is global to all the modules within a plugin. Also, change the client-side interface so that the preauth plugin context (once created) lives the lifetime of a krb5_context. This will allow future changes that can set plugin parameters. The client side request context lives the lifetime of a call to krb5_get_init_creds(). Make the sample preauth plugins buildable outside the source tree. Fix minor memory leak in sort_krb5_padata_sequence(). Add a prototype for krb5_do_preauth_tryagain() and change the plugin interface. Incorporates fixes from Nalin Dahyabhai for leaks of the function table pointers (rt #4566) and fix KDC crash (rt #4567) ticket: 4566 ticket: 4567 ticket: 4587 Target_Version: 1.6 Tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18754 dc483132-0cff-0310-8789-dd5450dbe970 --- src/plugins/preauth/wpse/Makefile.in | 6 +- src/plugins/preauth/wpse/src/wpse.c | 341 -------------------------------- src/plugins/preauth/wpse/wpse_main.c | 374 +++++++++++++++++++++++++++++++++++ 3 files changed, 377 insertions(+), 344 deletions(-) delete mode 100644 src/plugins/preauth/wpse/src/wpse.c create mode 100644 src/plugins/preauth/wpse/wpse_main.c (limited to 'src/plugins/preauth/wpse') diff --git a/src/plugins/preauth/wpse/Makefile.in b/src/plugins/preauth/wpse/Makefile.in index 6b18a7c064..6c2830f50b 100644 --- a/src/plugins/preauth/wpse/Makefile.in +++ b/src/plugins/preauth/wpse/Makefile.in @@ -9,7 +9,7 @@ PROG_RPATH=$(KRB5_LIBDIR) MODULE_INSTALL_DIR = $(KRB5_PA_MODULE_DIR) DEFS=@DEFS@ -LOCALINCLUDES = -I../../../include/krb5 +LOCALINCLUDES = -I../../../include/krb5 -I. LIBBASE=wpse LIBMAJOR=0 @@ -25,9 +25,9 @@ SHLIB_EXPLIBS= -lkrb5 -lcom_err -lk5crypto $(SUPPORT_LIB) $(LIBS) SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) STOBJLISTS=OBJS.ST -STLIBOBJS=src/wpse.o +STLIBOBJS=wpse_main.o -SRCS= $(srcdir)/src/wpse.c +SRCS=wpse_main.c all-unix:: $(LIBBASE)$(SO_EXT) install-unix:: install-libs diff --git a/src/plugins/preauth/wpse/src/wpse.c b/src/plugins/preauth/wpse/src/wpse.c deleted file mode 100644 index 07c52d95a3..0000000000 --- a/src/plugins/preauth/wpse/src/wpse.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (C) 2006 Red Hat, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Red Hat, Inc., nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Worst. Preauthentication. Scheme. Ever. */ - -#ident "$Id$" - -#ifdef HAVE_CONFIG_H -#include "../config.h" -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include -#include - -#include -#include - -/* This is not a standardized value. It's defined here only to make it easier - * to change in this module. */ -#define KRB5_PADATA_WPSE_REQ 131 - -static int -client_get_flags(krb5_context kcontext, krb5_preauthtype pa_type) -{ - return PA_REAL; -} - -static krb5_error_code -client_init(krb5_context kcontext, krb5_preauthtype pa_type, void **ctx) -{ - int *mctx; - - mctx = malloc(sizeof(int)); - if (mctx == NULL) - return ENOMEM; - *mctx = 0; - *ctx = mctx; - return 0; -} - -static void -client_fini(krb5_context kcontext, krb5_preauthtype pa_type, void *ctx) -{ - int *mctx; - - mctx = ctx; - if (mctx) { -#ifdef DEBUG - fprintf(stderr, "wpse module called total of %d times\n", *mctx); -#endif - free(mctx); - } -} - -static krb5_error_code -client_process(krb5_context kcontext, - void *module_context, - void **request_context, - krb5_kdc_req *request, - krb5_data *encoded_request_body, - krb5_data *encoded_previous_request, - krb5_pa_data *pa_data, - krb5_prompter_fct prompter, - void *prompter_data, - preauth_get_as_key_proc gak_fct, - krb5_data *salt, krb5_data *s2kparams, - void *gak_data, - krb5_keyblock *as_key, - krb5_pa_data **out_pa_data) -{ - krb5_pa_data *send_pa; - krb5_int32 nnonce, enctype; - krb5_keyblock *kb; - krb5_error_code status; - int *mctx; - -#ifdef DEBUG - fprintf(stderr, "%d bytes of preauthentication data (type %d)\n", - pa_data->length, pa_data->pa_type); -#endif - - mctx = module_context; - if (mctx) { - (*mctx)++; - } - - if (pa_data->length == 0) { - /* Create preauth data. */ - send_pa = malloc(sizeof(krb5_pa_data)); - if (send_pa == NULL) - return ENOMEM; - send_pa->pa_type = KRB5_PADATA_WPSE_REQ; - send_pa->length = 4; - send_pa->contents = malloc(4); - if (send_pa->contents == NULL) { - free(send_pa); - return ENOMEM; - } - /* Store the preauth data. */ - nnonce = htonl(request->nonce); - memcpy(send_pa->contents, &nnonce, 4); - *out_pa_data = send_pa; - /* Allocate a context. Useful for verifying that we do in fact - * do per-request cleanup. */ - if (*request_context == NULL) - *request_context = malloc(4); - } else { - /* A reply from the KDC. Conventionally this would be - * indicated by a different preauthentication type, but this - * mechanism/implementation doesn't do that. */ - if (pa_data->length > 4) { - memcpy(&enctype, pa_data->contents, 4); - kb = NULL; - status = krb5_init_keyblock(kcontext, ntohl(enctype), - pa_data->length - 4, &kb); - if (status != 0) - return status; - memcpy(kb->contents, pa_data->contents + 4, pa_data->length - 4); -#ifdef DEBUG - fprintf(stderr, "Recovered key type=%d, length=%d.\n", - kb->enctype, kb->length); -#endif - status = krb5_copy_keyblock_contents(kcontext, kb, as_key); - krb5_free_keyblock(kcontext, kb); - return status; - } - return KRB5KRB_ERR_GENERIC; - } - return 0; -} - -static void -client_cleanup(krb5_context kcontext, void *module_context, - void **request_context) -{ - if (*request_context != NULL) { - free(*request_context); - *request_context = NULL; - } - return; -} - -/* Free state. */ -static krb5_error_code -server_free_pa_request_context(krb5_context kcontext, void *module_context, - void **request_context) -{ - if (*request_context != NULL) { - free(*request_context); - *request_context = NULL; - } - return 0; -} - -/* Obtain and return any preauthentication data (which is destined for the - * client) which matches type data->pa_type. */ -static krb5_error_code -server_get_edata(krb5_context kcontext, - krb5_kdc_req *request, - struct _krb5_db_entry_new *client, - struct _krb5_db_entry_new *server, - preauth_get_entry_data_proc server_get_entry_data, - void *pa_module_context, - krb5_pa_data *data) -{ - /* Return zero bytes of data. */ - data->length = 0; - data->contents = NULL; - return 0; -} - -/* Verify a request from a client. */ -static krb5_error_code -server_verify(krb5_context kcontext, - struct _krb5_db_entry_new *client, - krb5_data *req_pkt, - krb5_kdc_req *request, - krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *data, - preauth_get_entry_data_proc server_get_entry_data, - void *pa_module_context, - void **pa_request_context) -{ - krb5_int32 nnonce; - /* Verify the preauth data. */ - if (data->length != 4) - return KRB5KDC_ERR_PREAUTH_FAILED; - memcpy(&nnonce, data->contents, 4); - nnonce = ntohl(nnonce); - if (memcmp(&nnonce, &request->nonce, 4) != 0) - return KRB5KDC_ERR_PREAUTH_FAILED; - /* Note that preauthentication succeeded. */ - enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; - enc_tkt_reply->flags |= TKT_FLG_HW_AUTH; - /* Allocate a context. Useful for verifying that we do in fact do - * per-request cleanup. */ - if (*pa_request_context == NULL) - *pa_request_context = malloc(4); - return 0; -} - -/* Create the response for a client. */ -static krb5_error_code -server_return(krb5_context kcontext, - krb5_pa_data *padata, - struct _krb5_db_entry_new *client, - krb5_data *req_pkt, - krb5_kdc_req *request, - krb5_kdc_rep *reply, - struct _krb5_key_data *client_key, - krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, - preauth_get_entry_data_proc server_get_entry_data, - void *pa_module_context, - void **pa_request_context) -{ - /* This module does a couple of dumb things. It tags its reply with - * the same type as the initial challenge (expecting the client to sort - * out whether there's anything useful in there). Oh, and it replaces - * the AS reply key with one which is sent in the clear. */ - krb5_keyblock *kb; - krb5_int32 enctype; - int i; - - *send_pa = NULL; - - /* We'll want a key with the first supported enctype. */ - for (i = 0; i < request->nktypes; i++) { - kb = NULL; - if (krb5_init_keyblock(kcontext, request->ktype[i], 0, &kb) == 0) { - break; - } - } - if (i >= request->nktypes) { - /* No matching cipher type found. */ - return 0; - } - - /* Randomize a key and save it for the client. */ - if (krb5_c_make_random_key(kcontext, request->ktype[i], kb) != 0) { - krb5_free_keyblock(kcontext, kb); - return 0; - } -#ifdef DEBUG - fprintf(stderr, "Generated random key, type=%d, length=%d.\n", - kb->enctype, kb->length); -#endif - - *send_pa = malloc(sizeof(krb5_pa_data)); - if (*send_pa == NULL) { - krb5_free_keyblock(kcontext, kb); - return ENOMEM; - } - (*send_pa)->pa_type = KRB5_PADATA_WPSE_REQ; - (*send_pa)->length = 4 + kb->length; - (*send_pa)->contents = malloc(4 + kb->length); - if ((*send_pa)->contents == NULL) { - free(*send_pa); - *send_pa = NULL; - krb5_free_keyblock(kcontext, kb); - return ENOMEM; - } - - /* Store the preauth data. */ - enctype = htonl(kb->enctype); - memcpy((*send_pa)->contents, &enctype, 4); - memcpy((*send_pa)->contents + 4, kb->contents, kb->length); - krb5_copy_keyblock_contents(kcontext, kb, encrypting_key); - - /* Clean up. */ - krb5_free_keyblock(kcontext, kb); - - return 0; -} - -static int -server_get_flags(krb5_context kcontext, krb5_preauthtype pa_type) -{ - return PA_HARDWARE | PA_REPLACES_KEY; -} - -static krb5_preauthtype supported_client_pa_types[] = {KRB5_PADATA_WPSE_REQ, 0}; -static krb5_preauthtype supported_server_pa_types[] = {KRB5_PADATA_WPSE_REQ, 0}; - -struct krb5plugin_preauth_client_ftable_v0 preauthentication_client_0 = { - "wpse", - &supported_client_pa_types[0], - NULL, - client_init, - client_fini, - client_get_flags, - client_cleanup, - client_process, - NULL, -}; - -struct krb5plugin_preauth_server_ftable_v0 preauthentication_server_0 = { - "wpse", - &supported_server_pa_types[0], - NULL, - NULL, - server_get_flags, - server_get_edata, - server_verify, - server_return, - server_free_pa_request_context, -}; diff --git a/src/plugins/preauth/wpse/wpse_main.c b/src/plugins/preauth/wpse/wpse_main.c new file mode 100644 index 0000000000..e7d7b6d557 --- /dev/null +++ b/src/plugins/preauth/wpse/wpse_main.c @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2006 Red Hat, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Red Hat, Inc., nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Worst. Preauthentication. Scheme. Ever. */ + +#ident "$Id$" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_ERRNO_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif + +#include +#include + +#include +#include + +/* This is not a standardized value. It's defined here only to make it easier + * to change in this module. */ +#define KRB5_PADATA_WPSE_REQ 131 + +static int +client_get_flags(krb5_context kcontext, krb5_preauthtype pa_type) +{ + return PA_REAL; +} + +static krb5_error_code +client_init(krb5_context kcontext, void **ctx) +{ + int *pctx; + + pctx = malloc(sizeof(int)); + if (pctx == NULL) + return ENOMEM; + *pctx = 0; + *ctx = pctx; + return 0; +} + +static void +client_fini(krb5_context kcontext, void *ctx) +{ + int *pctx; + + pctx = ctx; + if (pctx) { +#ifdef DEBUG + fprintf(stderr, "wpse module called total of %d times\n", *pctx); +#endif + free(pctx); + } +} + +static krb5_error_code +client_process(krb5_context kcontext, + void *plugin_context, + void *request_context, + krb5_kdc_req *request, + krb5_data *encoded_request_body, + krb5_data *encoded_previous_request, + krb5_pa_data *pa_data, + krb5_prompter_fct prompter, + void *prompter_data, + preauth_get_as_key_proc gak_fct, + void *gak_data, + krb5_data *salt, krb5_data *s2kparams, + krb5_keyblock *as_key, + krb5_pa_data **out_pa_data) +{ + krb5_pa_data *send_pa; + krb5_int32 nnonce, enctype; + krb5_keyblock *kb; + krb5_error_code status; + int *pctx; + +#ifdef DEBUG + fprintf(stderr, "%d bytes of preauthentication data (type %d)\n", + pa_data->length, pa_data->pa_type); +#endif + + pctx = plugin_context; + if (pctx) { + (*pctx)++; + } + + if (pa_data->length == 0) { + /* Create preauth data. */ + send_pa = malloc(sizeof(krb5_pa_data)); + if (send_pa == NULL) + return ENOMEM; + send_pa->pa_type = KRB5_PADATA_WPSE_REQ; + send_pa->length = 4; + send_pa->contents = malloc(4); + if (send_pa->contents == NULL) { + free(send_pa); + return ENOMEM; + } + /* Store the preauth data. */ + nnonce = htonl(request->nonce); + memcpy(send_pa->contents, &nnonce, 4); + *out_pa_data = send_pa; + } else { + /* A reply from the KDC. Conventionally this would be + * indicated by a different preauthentication type, but this + * mechanism/implementation doesn't do that. */ + if (pa_data->length > 4) { + memcpy(&enctype, pa_data->contents, 4); + kb = NULL; + status = krb5_init_keyblock(kcontext, ntohl(enctype), + pa_data->length - 4, &kb); + if (status != 0) + return status; + memcpy(kb->contents, pa_data->contents + 4, pa_data->length - 4); +#ifdef DEBUG + fprintf(stderr, "Recovered key type=%d, length=%d.\n", + kb->enctype, kb->length); +#endif + status = krb5_copy_keyblock_contents(kcontext, kb, as_key); + krb5_free_keyblock(kcontext, kb); + return status; + } + return KRB5KRB_ERR_GENERIC; + } + return 0; +} + +#define WPSE_MAGIC 0x77707365 +typedef struct _wpse_req_ctx +{ + int magic; + int value; +} wpse_req_ctx; + +static void +client_req_init(krb5_context kcontext, void *plugin_context, void **req_context_p) +{ + wpse_req_ctx *ctx; + + *req_context_p = NULL; + + /* Allocate a request context. Useful for verifying that we do in fact + * do per-request cleanup. */ + ctx = (wpse_req_ctx *) malloc(sizeof(*ctx)); + if (ctx == NULL) + return; + ctx->magic = WPSE_MAGIC; + ctx->value = 0xc0dec0de; + + *req_context_p = ctx; +} + +static void +client_req_cleanup(krb5_context kcontext, void *plugin_context, void *req_context) +{ + wpse_req_ctx *ctx = (wpse_req_ctx *)req_context; + + if (ctx) { +#ifdef DEBUG + fprintf(stderr, "client_req_cleanup: req_ctx at %p has magic %x and value %x\n", + ctx, ctx->magic, ctx->value); +#endif + if (ctx->magic != WPSE_MAGIC) { +#ifdef DEBUG + fprintf(stderr, "client_req_cleanup: req_context at %p has bad magic value %x\n", + ctx, ctx->magic); +#endif + return; + } + free(ctx); + } + return; +} + +/* Free state. */ +static krb5_error_code +server_free_pa_request_context(krb5_context kcontext, void *plugin_context, + void **request_context) +{ + if (*request_context != NULL) { + free(*request_context); + *request_context = NULL; + } + return 0; +} + +/* Obtain and return any preauthentication data (which is destined for the + * client) which matches type data->pa_type. */ +static krb5_error_code +server_get_edata(krb5_context kcontext, + krb5_kdc_req *request, + struct _krb5_db_entry_new *client, + struct _krb5_db_entry_new *server, + preauth_get_entry_data_proc server_get_entry_data, + void *pa_module_context, + krb5_pa_data *data) +{ + /* Return zero bytes of data. */ + data->length = 0; + data->contents = NULL; + return 0; +} + +/* Verify a request from a client. */ +static krb5_error_code +server_verify(krb5_context kcontext, + struct _krb5_db_entry_new *client, + krb5_data *req_pkt, + krb5_kdc_req *request, + krb5_enc_tkt_part *enc_tkt_reply, + krb5_pa_data *data, + preauth_get_entry_data_proc server_get_entry_data, + void *pa_module_context, + void **pa_request_context) +{ + krb5_int32 nnonce; + /* Verify the preauth data. */ + if (data->length != 4) + return KRB5KDC_ERR_PREAUTH_FAILED; + memcpy(&nnonce, data->contents, 4); + nnonce = ntohl(nnonce); + if (memcmp(&nnonce, &request->nonce, 4) != 0) + return KRB5KDC_ERR_PREAUTH_FAILED; + /* Note that preauthentication succeeded. */ + enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; + enc_tkt_reply->flags |= TKT_FLG_HW_AUTH; + /* Allocate a context. Useful for verifying that we do in fact do + * per-request cleanup. */ + if (*pa_request_context == NULL) + *pa_request_context = malloc(4); + return 0; +} + +/* Create the response for a client. */ +static krb5_error_code +server_return(krb5_context kcontext, + krb5_pa_data *padata, + struct _krb5_db_entry_new *client, + krb5_data *req_pkt, + krb5_kdc_req *request, + krb5_kdc_rep *reply, + struct _krb5_key_data *client_key, + krb5_keyblock *encrypting_key, + krb5_pa_data **send_pa, + preauth_get_entry_data_proc server_get_entry_data, + void *pa_module_context, + void **pa_request_context) +{ + /* This module does a couple of dumb things. It tags its reply with + * the same type as the initial challenge (expecting the client to sort + * out whether there's anything useful in there). Oh, and it replaces + * the AS reply key with one which is sent in the clear. */ + krb5_keyblock *kb; + krb5_int32 enctype; + int i; + + *send_pa = NULL; + + /* We'll want a key with the first supported enctype. */ + for (i = 0; i < request->nktypes; i++) { + kb = NULL; + if (krb5_init_keyblock(kcontext, request->ktype[i], 0, &kb) == 0) { + break; + } + } + if (i >= request->nktypes) { + /* No matching cipher type found. */ + return 0; + } + + /* Randomize a key and save it for the client. */ + if (krb5_c_make_random_key(kcontext, request->ktype[i], kb) != 0) { + krb5_free_keyblock(kcontext, kb); + return 0; + } +#ifdef DEBUG + fprintf(stderr, "Generated random key, type=%d, length=%d.\n", + kb->enctype, kb->length); +#endif + + *send_pa = malloc(sizeof(krb5_pa_data)); + if (*send_pa == NULL) { + krb5_free_keyblock(kcontext, kb); + return ENOMEM; + } + (*send_pa)->pa_type = KRB5_PADATA_WPSE_REQ; + (*send_pa)->length = 4 + kb->length; + (*send_pa)->contents = malloc(4 + kb->length); + if ((*send_pa)->contents == NULL) { + free(*send_pa); + *send_pa = NULL; + krb5_free_keyblock(kcontext, kb); + return ENOMEM; + } + + /* Store the preauth data. */ + enctype = htonl(kb->enctype); + memcpy((*send_pa)->contents, &enctype, 4); + memcpy((*send_pa)->contents + 4, kb->contents, kb->length); + krb5_copy_keyblock_contents(kcontext, kb, encrypting_key); + + /* Clean up. */ + krb5_free_keyblock(kcontext, kb); + + return 0; +} + +static int +server_get_flags(krb5_context kcontext, krb5_preauthtype pa_type) +{ + return PA_HARDWARE | PA_REPLACES_KEY; +} + +static krb5_preauthtype supported_client_pa_types[] = {KRB5_PADATA_WPSE_REQ, 0}; +static krb5_preauthtype supported_server_pa_types[] = {KRB5_PADATA_WPSE_REQ, 0}; + +struct krb5plugin_preauth_client_ftable_v0 preauthentication_client_0 = { + "wpse", /* name */ + &supported_client_pa_types[0], /* pa_type_list */ + NULL, /* enctype_list */ + client_init, /* plugin init function */ + client_fini, /* plugin fini function */ + client_get_flags, /* get flags function */ + client_req_init, /* request init function */ + client_req_cleanup, /* request fini function */ + client_process, /* process function */ + NULL, /* try_again function */ +}; + +struct krb5plugin_preauth_server_ftable_v0 preauthentication_server_0 = { + "wpse", + &supported_server_pa_types[0], + NULL, + NULL, + server_get_flags, + server_get_edata, + server_verify, + server_return, + server_free_pa_request_context, +}; -- cgit