diff options
Diffstat (limited to 'src')
28 files changed, 1224 insertions, 1333 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 86ec114b0a..76993f397a 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -809,48 +809,11 @@ error(MIT_DES_KEYSIZE does not equal KRB5_MIT_DES_KEYSIZE) * expanded in the future as new types of requests are defined which * may require other things to be passed through. */ struct krb5int_fast_request_state; -typedef struct _krb5_preauth_client_rock { - krb5_magic magic; +struct krb5_clpreauth_rock_st { + krb5_magic magic; krb5_enctype *etype; struct krb5int_fast_request_state *fast_state; -} krb5_preauth_client_rock; - -/* This structure lets us keep track of all of the modules which are loaded, - * turning the list of modules and their lists of implemented preauth types - * into a single list which we can walk easily. */ -typedef struct _krb5_preauth_context { - int n_modules; - struct _krb5_preauth_context_module { - /* Which of the possibly more than one preauth types which the - * module supports we're using at this point in the list. */ - krb5_preauthtype pa_type; - /* Encryption types which the client claims to support -- we - * copy them directly into the krb5_kdc_req structure during - * krb5_preauth_prepare_request(). */ - krb5_enctype *enctypes; - /* The plugin's per-plugin context and a function to clear it. */ - void *plugin_context; - preauth_client_plugin_fini_proc client_fini; - /* The module's table, and some of its members, copied here for - * convenience when we populated the list. */ - struct krb5plugin_preauth_client_ftable_v1 *ftable; - const char *name; - int flags, use_count; - preauth_client_process_proc client_process; - preauth_client_tryagain_proc client_tryagain; - preauth_client_supply_gic_opts_proc client_supply_gic_opts; - preauth_client_request_init_proc client_req_init; - preauth_client_request_fini_proc client_req_fini; - /* The per-request context which the client_req_init() function - * might allocate, which we'll need to clean up later by - * calling the client_req_fini() function. */ - void *request_context; - /* A pointer to the request_context pointer. All modules within - * a plugin will point at the request_context of the first - * module within the plugin. */ - void **request_context_pp; - } *modules; -} krb5_preauth_context; +}; typedef struct _krb5_pa_enc_ts { krb5_timestamp patimestamp; @@ -1121,7 +1084,7 @@ krb5_do_preauth(krb5_context context, krb5_kdc_req *request, krb5_data *s2kparams, krb5_enctype *etype, krb5_keyblock *as_key, krb5_prompter_fct prompter, void *prompter_data, krb5_gic_get_as_key_fct gak_fct, - void *gak_data, krb5_preauth_client_rock *get_data_rock, + void *gak_data, krb5_clpreauth_rock preauth_rock, krb5_gic_opt_ext *opte); krb5_error_code KRB5_CALLCONV @@ -1134,7 +1097,7 @@ krb5_do_preauth_tryagain(krb5_context context, krb5_kdc_req *request, krb5_enctype *etype, krb5_keyblock *as_key, krb5_prompter_fct prompter, void *prompter_data, krb5_gic_get_as_key_fct gak_fct, void *gak_data, - krb5_preauth_client_rock *get_data_rock, + krb5_clpreauth_rock preauth_rock, krb5_gic_opt_ext *opte); void KRB5_CALLCONV krb5_init_preauth_context(krb5_context); @@ -1411,9 +1374,11 @@ struct plugin_interface { /* A list of plugin interface IDs. Make sure to increment * PLUGIN_NUM_INTERFACES when a new interface is added. */ -#define PLUGIN_INTERFACE_PWQUAL 0 -#define PLUGIN_INTERFACE_KADM5_HOOK 1 -#define PLUGIN_NUM_INTERFACES 2 +#define PLUGIN_INTERFACE_PWQUAL 0 +#define PLUGIN_INTERFACE_KADM5_HOOK 1 +#define PLUGIN_INTERFACE_CLPREAUTH 2 +#define PLUGIN_INTERFACE_KDCPREAUTH 3 +#define PLUGIN_NUM_INTERFACES 4 /* Retrieve the plugin module of type interface_id and name modname, * storing the result into module. */ @@ -1452,6 +1417,7 @@ k5_plugin_free_context(krb5_context context); struct _kdb5_dal_handle; /* private, in kdb5.h */ typedef struct _kdb5_dal_handle kdb5_dal_handle; struct _kdb_log_context; +typedef struct krb5_preauth_context_st krb5_preauth_context; struct _krb5_context { krb5_magic magic; krb5_enctype *in_tkt_etypes; @@ -1490,7 +1456,6 @@ struct _krb5_context { void (**locate_fptrs)(void); /* preauth module stuff */ - struct plugin_dir_handle preauth_plugins; krb5_preauth_context *preauth_context; /* error detail info */ diff --git a/src/include/krb5/preauth_plugin.h b/src/include/krb5/preauth_plugin.h index 21140cb45b..2ddacdabba 100644 --- a/src/include/krb5/preauth_plugin.h +++ b/src/include/krb5/preauth_plugin.h @@ -1,7 +1,7 @@ /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 2006 Red Hat, Inc. - * Portions copyright (c) 2006 Massachusetts Institute of Technology + * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,20 +30,50 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* Preauthentication plugin definitions for Kerberos 5 */ +/* + * Declarations for preauth plugin module implementors. + * + * This header defines two preauth interfaces, clpreauth and kdcpreauth. A + * shared object can implement both interfaces or it can implement just one. + * + * + * The clpreauth interface has a single supported major version, which is + * 1. Major version 1 has a current minor version of 1. clpreauth modules + * should define a function named clpreauth_<modulename>_initvt, matching + * the signature: + * + * krb5_error_code + * clpreauth_modname_initvt(krb5_context context, int maj_ver, + * int min_ver, krb5_plugin_vtable vtable); + * + * The kdcpreauth interface has a single supported major version, which is 1. + * Major version 1 has a current minor version of 1. kdcpreauth modules should + * define a function named kdcpreauth_<modulename>_initvt, matching the + * signature: + * + * krb5_error_code + * kdcpreauth_modname_initvt(krb5_context context, int maj_ver, int min_ver, + * krb5_plugin_vtable vtable); + * + * For both interfaces, the initvt function should: + * + * - Check that the supplied maj_ver number is supported by the module, or + * return KRB5_PLUGIN_VER_NOTSUPP if it is not. + * + * - Cast the vtable pointer as appropriate for the interface and maj_ver: + * clpreauth, maj_ver == 1: Cast to krb5_clpreauth_vtable + * kdcpreauth, maj_ver == 1: Cast to krb5_kdcpreauth_vtable + * + * - Initialize the methods of the vtable, stopping as appropriate for the + * supplied min_ver. Optional methods may be left uninitialized. + * + * Memory for the vtable is allocated by the caller, not by the module. + */ #ifndef KRB5_PREAUTH_PLUGIN_H_INCLUDED #define KRB5_PREAUTH_PLUGIN_H_INCLUDED #include <krb5/krb5.h> - -/* - * While arguments of these types are passed-in, for the most part a preauth - * module can treat them as opaque. If we need keying data, we can ask for - * it directly. - */ -struct _krb5_db_entry_new; -struct _krb5_key_data; -struct _krb5_preauth_client_rock; +#include <krb5/plugin.h> /* * Preauth mechanism property flags, unified from previous definitions in the @@ -58,444 +88,390 @@ struct _krb5_preauth_client_rock; * REAL mechanism callbacks (client-only). */ #define PA_INFO 0x00000002 -/* Causes the KDC to include this mechanism in a list of supported preauth +/* + * Causes the KDC to include this mechanism in a list of supported preauth * types if the user's DB entry flags the user as requiring hardware-based - * preauthentication (server-only). */ + * preauthentication (KDC-only). + */ #define PA_HARDWARE 0x00000004 -/* Causes the KDC to include this mechanism in a list of supported preauth +/* + * Causes the KDC to include this mechanism in a list of supported preauth * types if the user's DB entry flags the user as requiring preauthentication, * and to fail preauthentication if we can't verify the client data. The - * flipside of PA_SUFFICIENT (server-only). */ + * flipside of PA_SUFFICIENT (KDC-only). + */ #define PA_REQUIRED 0x00000008 -/* Causes the KDC to include this mechanism in a list of supported preauth +/* + * Causes the KDC to include this mechanism in a list of supported preauth * types if the user's DB entry flags the user as requiring preauthentication, * and to mark preauthentication as successful if we can verify the client - * data. The flipside of PA_REQUIRED (server-only). */ + * data. The flipside of PA_REQUIRED (KDC-only). + */ #define PA_SUFFICIENT 0x00000010 -/* Marks this preauthentication mechanism as one which changes the key which is +/* + * Marks this preauthentication mechanism as one which changes the key which is * used for encrypting the response to the client. Modules which have this - * flag have their server_return_proc called before modules which do not, and - * are passed over if a previously-called module has modified the encrypting - * key (server-only). */ + * flag have their server_return_fn called before modules which do not, and are + * passed over if a previously-called module has modified the encrypting key + * (KDC-only). + */ #define PA_REPLACES_KEY 0x00000020 -/* Causes the KDC to check with this preauthentication module even if the - * client has no entry in the realm database. If the module returns a success - * code, continue processing and assume that its return_padata callback will - * supply us with a key for encrypting the AS reply (server-only). */ -/* #define PA_VIRTUAL (0x00000040 | PA_REPLACES_KEY) */ - -/* Not really a padata type, so don't include it in any list of preauth types - * which gets sent over the wire. */ +/* + * Not really a padata type, so don't include it in any list of preauth types + * which gets sent over the wire. + */ #define PA_PSEUDO 0x00000080 -/*************************************************************************** - * - * Client-side preauthentication plugin interface definition. - * - ***************************************************************************/ +/* + * clpreauth plugin interface definition. + */ + +/* Abstract type for a client request information handle. */ +typedef struct krb5_clpreauth_rock_st *krb5_clpreauth_rock; + +/* Abstract types for module data and per-request module data. */ +typedef struct krb5_clpreauth_moddata_st *krb5_clpreauth_moddata; +typedef struct krb5_clpreauth_modreq_st *krb5_clpreauth_modreq; /* - * A callback which will obtain the user's long-term AS key by prompting the - * user for the password, then salting it properly, and so on. For the moment, - * it's identical to the get_as_key callback used inside of libkrb5, but we - * define a new typedef here instead of making the existing one public to - * isolate ourselves from potential future changes. + * Provided by krb5: a callback which will obtain the user's long-term AS key + * by prompting the user for the password, then salting it properly, and so on. + * For the moment, it's identical to the get_as_key callback used inside of + * libkrb5, but we define a new typedef here instead of making the existing one + * public to isolate ourselves from potential future changes. */ typedef krb5_error_code -(*preauth_get_as_key_proc)(krb5_context, - krb5_principal, - krb5_enctype, - krb5_prompter_fct, - void *prompter_data, - krb5_data *salt, - krb5_data *s2kparams, - krb5_keyblock *as_key, - void *gak_data); +(*krb5_clpreauth_get_as_key_fn)(krb5_context context, + krb5_principal princ, + krb5_enctype enctype, + krb5_prompter_fct prompter, + void *prompter_data, + krb5_data *salt, + krb5_data *s2kparams, + krb5_keyblock *as_key, + void *gak_data); /* - * A client module's callback functions are allowed to request various - * information to enable it to process a request. + * Provided by krb5: a client module's callback functions are allowed to + * request various information to enable it to process a request. */ -enum krb5plugin_preauth_client_request_type { - /* The returned krb5_data item holds the enctype expected to be used to encrypt the - * encrypted portion of the AS_REP packet. When handling a - * PREAUTH_REQUIRED error, this typically comes from etype-info2. - * When handling an AS reply, it is initialized from the AS reply itself.*/ - krb5plugin_preauth_client_get_etype = 1, - /* Free the data returned from krb5plugin_preauth_client_req_get_etype */ - krb5plugin_preauth_client_free_etype = 2, - /* The returned krb5_data contains the FAST armor key in a - * krb5_keyblock. Returns success with a NULL data item in the - * krb5_data if the client library supports FAST but is not using it.*/ - krb5plugin_preauth_client_fast_armor = 3, - /* Frees return from KRB5PLUGIN_PREAUTH_CLIENT_FAST_ARMOR. It is - * acceptable to set data to NULL and free the keyblock using - * krb5_free_keyblock; in that case, this frees the krb5_data - * only.*/ - krb5plugin_preauth_client_free_fast_armor = 4 +enum krb5_clpreauth_request_type { + /* + * The returned krb5_data item holds the enctype expected to be used to + * encrypt the encrypted portion of the AS_REP packet. When handling a + * PREAUTH_REQUIRED error, this typically comes from etype-info2. When + * handling an AS reply, it is initialized from the AS reply itself. + */ + krb5_clpreauth_get_etype = 1, + + /* Free the data returned from krb5plugin_clpreauth_req_get_etype */ + krb5_clpreauth_free_etype = 2, + + /* + * The returned krb5_data contains the FAST armor key in a krb5_keyblock. + * Returns success with a NULL data item in the krb5_data if the client + * library supports FAST but is not using it. + */ + krb5_clpreauth_fast_armor = 3, + + /* + * Frees return from KRB5PLUGIN_CLPREAUTH_FAST_ARMOR. It is + * acceptable to set data->data to NULL and free the keyblock using + * krb5_free_keyblock; in that case, this frees the krb5_data only. + */ + krb5_clpreauth_free_fast_armor = 4 }; typedef krb5_error_code -(*preauth_get_client_data_proc)(krb5_context, - struct _krb5_preauth_client_rock *, - krb5_int32 request_type, - krb5_data **); - -/* Per-plugin initialization/cleanup. The init function is called - * by libkrb5 when the plugin is loaded, and the fini function is - * called before the plugin is unloaded. Both are optional and - * may be called multiple times in case the plugin is used in - * multiple contexts. The returned context lives the lifetime of - * the krb5_context */ +(*krb5_clpreauth_get_data_fn)(krb5_context context, + krb5_clpreauth_rock rock, + krb5_int32 request_type, krb5_data **data); + +/* + * Optional: per-plugin initialization/cleanup. The init function is called by + * libkrb5 when the plugin is loaded, and the fini function is called before + * the plugin is unloaded. These may be called multiple times in case the + * plugin is used in multiple contexts. The returned context lives the + * lifetime of the krb5_context. + */ typedef krb5_error_code -(*preauth_client_plugin_init_proc)(krb5_context context, - void **plugin_context); +(*krb5_clpreauth_init_fn)(krb5_context context, + krb5_clpreauth_moddata *moddata_out); typedef void -(*preauth_client_plugin_fini_proc)(krb5_context context, - void *plugin_context); +(*krb5_clpreauth_fini_fn)(krb5_context context, + krb5_clpreauth_moddata moddata); -/* A callback which returns flags indicating if the module is a "real" or - * an "info" mechanism, and so on. This function is called for each entry - * in the client_pa_type_list. */ +/* + * Mandatory: Return flags indicating if the module is a "real" or an "info" + * mechanism, and so on. This function is called for each entry in the + * client_pa_type_list. + */ typedef int -(*preauth_client_get_flags_proc)(krb5_context context, - krb5_preauthtype pa_type); +(*krb5_clpreauth_get_flags_fn)(krb5_context context, krb5_preauthtype pa_type); -/* Per-request initialization/cleanup. The request_init function is +/* + * Optional: per-request initialization/cleanup. The request_init function is * called when beginning to process a get_init_creds request and the - * request_fini function is called when processing of the request is - * complete. This is optional. It may be called multiple times in - * the lifetime of a krb5_context. */ + * request_fini function is called when processing of the request is complete. + * This is optional. It may be called multiple times in the lifetime of a + * krb5_context. + */ typedef void -(*preauth_client_request_init_proc)(krb5_context context, - void *plugin_context, - void **request_context); +(*krb5_clpreauth_request_init_fn)(krb5_context context, + krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq *modreq_out); typedef void -(*preauth_client_request_fini_proc)(krb5_context context, - void *plugin_context, - void *request_context); - -/* Client function which processes server-supplied data in pa_data, - * returns created data in out_pa_data, storing any of its own state in - * client_context if data for the associated preauthentication type is - * needed. It is also called after the AS-REP is received if the AS-REP - * includes preauthentication data of the associated type. - * NOTE! the encoded_previous_request will be NULL the first time this - * function is called, because it is expected to only ever contain the data - * obtained from a previous call to this function. */ -typedef krb5_error_code -(*preauth_client_process_proc)(krb5_context context, - void *plugin_context, - void *request_context, - krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc get_data_proc, - struct _krb5_preauth_client_rock *rock, - 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); - -/* Client function which can attempt to use e-data in the error response to - * try to recover from the given error. If this function is not NULL, and - * it stores data in out_pa_data which is different data from the contents - * of in_pa_data, then the client library will retransmit the request. */ +(*krb5_clpreauth_request_fini_fn)(krb5_context context, + krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq); + +/* + * Mandatory: process server-supplied data in pa_data and returns created data + * in out_pa_data. It is also called after the AS-REP is received if the + * AS-REP includes preauthentication data of the associated type. NOTE: the + * encoded_previous_request will be NULL the first time this function is + * called, because it is expected to only ever contain the data obtained from a + * previous call to this function. + */ typedef krb5_error_code -(*preauth_client_tryagain_proc)(krb5_context context, - void *plugin_context, - void *request_context, - krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc get_data_proc, - struct _krb5_preauth_client_rock *rock, - krb5_kdc_req *request, - krb5_data *encoded_request_body, - krb5_data *encoded_previous_request, - krb5_pa_data *in_pa_data, - krb5_error *error, - 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_clpreauth_process_fn)(krb5_context context, + krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq, + krb5_get_init_creds_opt *opt, + krb5_clpreauth_get_data_fn get_data, + krb5_clpreauth_rock rock, + 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, + krb5_clpreauth_get_as_key_fn gak_fct, + void *gak_data, + krb5_data *salt, krb5_data *s2kparams, + krb5_keyblock *as_key, + krb5_pa_data ***out_pa_data); /* - * Client function which receives krb5_get_init_creds_opt information. - * The attr and value information supplied should be copied locally by - * the module if it wishes to reference it after returning from this call. + * Optional: Attempt to use e-data in the error response to try to recover from + * the given error. If this function is provided, and it stores data in + * out_pa_data which is different data from the contents of in_pa_data, then + * the client library will retransmit the request. */ typedef krb5_error_code -(*preauth_client_supply_gic_opts_proc)(krb5_context context, - void *plugin_context, - krb5_get_init_creds_opt *opt, - const char *attr, - const char *value); +(*krb5_clpreauth_tryagain_fn)(krb5_context context, + krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq, + krb5_get_init_creds_opt *opt, + krb5_clpreauth_get_data_fn get_data, + krb5_clpreauth_rock rock, + krb5_kdc_req *request, + krb5_data *encoded_request_body, + krb5_data *encoded_previous_request, + krb5_pa_data *in_pa_data, + krb5_error *error, + krb5_prompter_fct prompter, void *prompter_data, + krb5_clpreauth_get_as_key_fn gak_fct, + void *gak_data, + krb5_data *salt, krb5_data *s2kparams, + krb5_keyblock *as_key, + krb5_pa_data ***out_pa_data); /* - * The function table / structure which a preauth client module must export as - * "preauthentication_client_0". If the interfaces work correctly, future - * versions of the table will add either more callbacks or more arguments to - * callbacks, and in both cases we'll be able to wrap the v0 functions. + * Optional: receive krb5_get_init_creds_opt information. The attr and value + * information supplied should be copied into moddata by the module if it + * wishes to reference it after returning from this call. */ -typedef struct krb5plugin_preauth_client_ftable_v1 { - /* Not-usually-visible name. */ +typedef krb5_error_code +(*krb5_clpreauth_supply_gic_opts_fn)(krb5_context context, + krb5_clpreauth_moddata moddata, + krb5_get_init_creds_opt *opt, + const char *attr, const char *value); + +typedef struct krb5_clpreauth_vtable_st { + /* Mandatory: name of module. */ char *name; - /* Pointer to zero-terminated list of pa_types which this module can - * provide services for. */ + /* Mandatory: pointer to zero-terminated list of pa_types which this module + * can provide services for. */ krb5_preauthtype *pa_type_list; - /* Pointer to zero-terminated list of enc_types which this module claims - * to add support for. */ + /* Optional: pointer to zero-terminated list of enc_types which this module + * claims to add support for. */ krb5_enctype *enctype_list; - /* Per-plugin initialization/cleanup. The init function is called - * by libkrb5 when the plugin is loaded, and the fini function is - * called before the plugin is unloaded. Both are optional and - * may be called multiple times in case the plugin is used in - * multiple contexts. The returned context lives the lifetime of - * the krb5_context */ - preauth_client_plugin_init_proc init; - preauth_client_plugin_fini_proc fini; - - /* A callback which returns flags indicating if the module is a "real" or - * an "info" mechanism, and so on. This function is called for each entry - * in the client_pa_type_list. */ - preauth_client_get_flags_proc flags; - - /* Per-request initialization/cleanup. The request_init function is - * called when beginning to process a get_init_creds request and the - * request_fini function is called when processing of the request is - * complete. This is optional. It may be called multiple times in - * the lifetime of a krb5_context. */ - preauth_client_request_init_proc request_init; - preauth_client_request_fini_proc request_fini; - - /* Client function which processes server-supplied data in pa_data, - * returns created data in out_pa_data, storing any of its own state in - * client_context if data for the associated preauthentication type is - * needed. It is also called after the AS-REP is received if the AS-REP - * includes preauthentication data of the associated type. - * NOTE! the encoded_previous_request will be NULL the first time this - * function is called, because it is expected to only ever contain the data - * obtained from a previous call to this function. */ - preauth_client_process_proc process; - - /* Client function which can attempt to use e-data in the error response to - * try to recover from the given error. If this function is not NULL, and - * it stores data in out_pa_data which is different data from the contents - * of in_pa_data, then the client library will retransmit the request. */ - preauth_client_tryagain_proc tryagain; + krb5_clpreauth_init_fn init; + krb5_clpreauth_fini_fn fini; + krb5_clpreauth_get_flags_fn flags; + krb5_clpreauth_request_init_fn request_init; + krb5_clpreauth_request_fini_fn request_fini; + krb5_clpreauth_process_fn process; + krb5_clpreauth_tryagain_fn tryagain; + krb5_clpreauth_supply_gic_opts_fn gic_opts; + /* Minor version 1 ends here. */ +} *krb5_clpreauth_vtable; - /* - * Client function which receives krb5_get_init_creds_opt information. - * The attr and value information supplied should be copied locally by - * the module if it wishes to reference it after returning from this call. - */ - preauth_client_supply_gic_opts_proc gic_opts; -} krb5plugin_preauth_client_ftable_v1; +/* + * kdcpreauth plugin interface definition. + */ +/* While arguments of these types are passed in, they are opaque to kdcpreauth + * modules. */ +struct _krb5_db_entry_new; +struct _krb5_key_data; -/*************************************************************************** - * - * Server-side preauthentication plugin interface definition. - * - ***************************************************************************/ +/* Abstract type for module data and per-request module data. */ +typedef struct krb5_kdcpreauth_moddata_st *krb5_kdcpreauth_moddata; +typedef struct krb5_kdcpreauth_modreq_st *krb5_kdcpreauth_modreq; /* - * A server module's callback functions are allowed to request specific types - * of information about the given client or server record or request, even - * though the database records themselves are opaque to the module. + * Provided by krb5: a kdcpreauth module's callback functions are allowed to + * request specific types of information about the given client or server + * record or request, even though the database records themselves are opaque to + * the module. */ -enum krb5plugin_preauth_entry_request_type { +enum krb5_kdcpreauth_request_type { /* The returned krb5_data item holds a DER-encoded X.509 certificate. */ - krb5plugin_preauth_entry_request_certificate = 1, + krb5_kdcpreauth_request_certificate = 1, /* The returned krb5_data_item holds a krb5_deltat. */ - krb5plugin_preauth_entry_max_time_skew = 2, - /* The returned krb5_data_item holds an array of krb5_keyblock structures, - * terminated by an entry with key type = 0. - * Each keyblock should have its contents freed in turn, and then the data - * item itself should be freed. */ - krb5plugin_preauth_keys = 3, - /* The returned krb5_data_item holds the request structure, re-encoded + krb5_kdcpreauth_max_time_skew = 2, + /* + * The returned krb5_data_item holds an array of krb5_keyblock structures, + * terminated by an entry with key type = 0. Each keyblock should have its + * contents freed in turn, and then the data item itself should be freed. + */ + krb5_kdcpreauth_keys = 3, + /* + * The returned krb5_data_item holds the request structure, re-encoded * using DER. Unless the client implementation is the same as the server * implementation, there's a good chance that the result will not match - * what the client sent, so don't go creating any fatal errors if it - * doesn't match up. */ - krb5plugin_preauth_request_body = 4, - /* The returned krb5_data contains a krb5_keyblock with the FAST - armor key. The data member is NULL if this method is not part - of a FAST tunnel */ - krb5plugin_preauth_fast_armor = 5, - /* Frees a fast armor key; it is acceptable to set data to NULL - and free the keyblock using krb5_free_keyblock; in that case, - this function simply frees the data*/ - krb5plugin_preauth_free_fast_armor = 6 + * what the client sent, so don't create any fatal errors if it doesn't + * match up. + */ + krb5_kdcpreauth_request_body = 4, + /* + * The returned krb5_data contains a krb5_keyblock with the FAST armor key. + * The data member is NULL if this method is not part of a FAST tunnel. + */ + krb5_kdcpreauth_fast_armor = 5, + /* + * Frees a fast armor key. It is acceptable to set data to NULL and free + * the keyblock using krb5_free_keyblock; in that case, this function + * simply frees the data. + */ + krb5_kdcpreauth_free_fast_armor = 6 }; - typedef krb5_error_code -(*preauth_get_entry_data_proc)(krb5_context, - krb5_kdc_req *, - struct _krb5_db_entry_new *, +(*krb5_kdcpreauth_get_data_fn)(krb5_context context, krb5_kdc_req *request, + struct _krb5_db_entry_new *entry, krb5_int32 request_type, krb5_data **); -/* Preauth plugin initialization function */ +/* Optional: preauth plugin initialization function. */ typedef krb5_error_code -(*preauth_server_init_proc)(krb5_context context, - void **plugin_context, - const char** realmnames); +(*krb5_kdcpreauth_init_fn)(krb5_context context, + krb5_kdcpreauth_moddata *moddata_out, + const char **realmnames); -/* Preauth plugin cleanup function */ +/* Optional: preauth plugin cleanup function. */ typedef void -(*preauth_server_fini_proc)(krb5_context context, void *plugin_context); - -/* Return the flags which the KDC should use for this module. This is a - * callback instead of a static value because the module may or may not - * wish to count itself as a hardware preauthentication module (in other - * words, the flags may be affected by the configuration, for example if a - * site administrator can force a particular preauthentication type to be - * supported using only hardware). This function is called for each entry - * entry in the server_pa_type_list. */ +(*krb5_kdcpreauth_fini_fn)(krb5_context context, + krb5_kdcpreauth_moddata moddata); + +/* + * Optional: return the flags which the KDC should use for this module. This + * is a callback instead of a static value because the module may or may not + * wish to count itself as a hardware preauthentication module (in other words, + * the flags may be affected by the configuration, for example if a site + * administrator can force a particular preauthentication type to be supported + * using only hardware). This function is called for each entry entry in the + * server_pa_type_list. + */ typedef int -(*preauth_server_flags_proc)(krb5_context context, krb5_preauthtype patype); - -/* Get preauthentication data to send to the client as part of the "you - * need to use preauthentication" error. The module doesn't need to - * actually provide data if the protocol doesn't require it, but it should - * return either zero or non-zero to control whether its padata type is - * included in the list which is sent back to the client. Is not allowed - * to create a context because we have no guarantee that the client will - * ever call again (or that it will hit this server if it does), in which - * case a context might otherwise hang around forever. */ +(*krb5_kdcpreauth_flags_fn)(krb5_context context, krb5_preauthtype patype); + +/* + * Optional: fill in pa_out->length and pa_out->contents with data to send to + * the client as part of the "you need to use preauthentication" error. If + * this function returns non-zero, the padata type will not be included in the + * list; if this function is not provided or returns zero without changing + * pa_out, the padata type will be included in the list with an empty value. + * This function not allowed to create a context because we have no guarantee + * that the client will ever call again (or that it will hit this server if it + * does), in which case a context might otherwise hang around forever. + */ typedef krb5_error_code -(*preauth_server_edata_proc)(krb5_context, - krb5_kdc_req *request, - struct _krb5_db_entry_new *client, - struct _krb5_db_entry_new *server, - preauth_get_entry_data_proc, - void *pa_module_context, - krb5_pa_data *data); +(*krb5_kdcpreauth_edata_fn)(krb5_context context, krb5_kdc_req *request, + struct _krb5_db_entry_new *client, + struct _krb5_db_entry_new *server, + krb5_kdcpreauth_get_data_fn get_data, + krb5_kdcpreauth_moddata moddata, + krb5_pa_data *pa_out); -/* Verify preauthentication data sent by the client, setting the +/* + * Optional: verify preauthentication data sent by the client, setting the * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags" * field as appropriate, and returning nonzero on failure. Can create - * context data for consumption by the return_proc or freepa_proc below. */ -typedef krb5_error_code -(*preauth_server_verify_proc)(krb5_context context, - 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, - void *pa_module_context, - void **pa_request_context, - krb5_data **e_data, - krb5_authdata ***authz_data); - -/* Generate preauthentication response data to send to the client as part - * of the AS-REP. If it needs to override the key which is used to encrypt - * the response, it can do so. The module is expected (but not required, - * if a preauth_server_free_reqcontext_proc is also provided) to free any - * context data it saved in "pa_request_context". */ -typedef krb5_error_code -(*preauth_server_return_proc)(krb5_context context, - 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_keys, - krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, - preauth_get_entry_data_proc, - void *pa_module_context, - void **pa_request_context); - -/* Free up the server-side per-request context, in cases where - * server_return_proc() didn't or for whatever reason was not called. - * Can be NULL. */ + * per-request module data for consumption by the return_fn or free_modreq_fn + * below. + */ typedef krb5_error_code -(*preauth_server_free_reqcontext_proc)(krb5_context, - void *pa_module_context, - void **request_pa_context); +(*krb5_kdcpreauth_verify_fn)(krb5_context context, + 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, + krb5_kdcpreauth_get_data_fn get_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq *modreq_out, + krb5_data **e_data_out, + krb5_authdata ***authz_data_out); /* - * The function table / structure which a preauth server module must export as - * "preauthentication_server_0". NOTE: replace "0" with "1" for the type and - * variable names if this gets picked up by upstream. If the interfaces work - * correctly, future versions of the table will add either more callbacks or - * more arguments to callbacks, and in both cases we'll be able to wrap the v0 - * functions. + * Optional: generate preauthentication response data to send to the client as + * part of the AS-REP. If it needs to override the key which is used to + * encrypt the response, it can do so. */ -typedef struct krb5plugin_preauth_server_ftable_v1 { - /* Not-usually-visible name. */ +typedef krb5_error_code +(*krb5_kdcpreauth_return_fn)(krb5_context context, + 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_keys, + krb5_keyblock *encrypting_key, + krb5_pa_data **send_pa_out, + krb5_kdcpreauth_get_data_fn, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq); + +/* Optional: free a per-request context. */ +typedef void +(*krb5_kdcpreauth_free_modreq_fn)(krb5_context, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq); + +typedef struct krb5_kdcpreauth_vtable_st { + /* Mandatory: name of module. */ char *name; - /* Pointer to zero-terminated list of pa_types which this module can - * provide services for. */ + /* Mandatory: pointer to zero-terminated list of pa_types which this module + * can provide services for. */ krb5_preauthtype *pa_type_list; - /* Per-plugin initialization/cleanup. The init function is called by the - * KDC when the plugin is loaded, and the fini function is called before - * the plugin is unloaded. Both are optional. */ - preauth_server_init_proc init_proc; - preauth_server_fini_proc fini_proc; - - /* Return the flags which the KDC should use for this module. This is a - * callback instead of a static value because the module may or may not - * wish to count itself as a hardware preauthentication module (in other - * words, the flags may be affected by the configuration, for example if a - * site administrator can force a particular preauthentication type to be - * supported using only hardware). This function is called for each entry - * entry in the server_pa_type_list. */ - preauth_server_flags_proc flags_proc; - - /* Get preauthentication data to send to the client as part of the "you - * need to use preauthentication" error. The module doesn't need to - * actually provide data if the protocol doesn't require it, but it should - * return either zero or non-zero to control whether its padata type is - * included in the list which is sent back to the client. Is not allowed - * to create a context because we have no guarantee that the client will - * ever call again (or that it will hit this server if it does), in which - * case a context might otherwise hang around forever. */ - preauth_server_edata_proc edata_proc; - - /* Verify preauthentication data sent by the client, setting the - * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags" - * field as appropriate, and returning nonzero on failure. Can create - * context data for consumption by the return_proc or freepa_proc below. */ - preauth_server_verify_proc verify_proc; - - /* Generate preauthentication response data to send to the client as part - * of the AS-REP. If it needs to override the key which is used to encrypt - * the response, it can do so. The module is expected (but not required, - * if a freepa_proc is also provided) to free any context data it saved in - * "request_pa_context". */ - preauth_server_return_proc return_proc; - - /* Free up the server-side per-request context, in cases where - * server_return_proc() didn't or for whatever reason was not called. - * Can be NULL. */ - preauth_server_free_reqcontext_proc freepa_reqcontext_proc; - -} krb5plugin_preauth_server_ftable_v1; - + krb5_kdcpreauth_init_fn init; + krb5_kdcpreauth_fini_fn fini; + krb5_kdcpreauth_flags_fn flags; + krb5_kdcpreauth_edata_fn edata; + krb5_kdcpreauth_verify_fn verify; + krb5_kdcpreauth_return_fn return_padata; + krb5_kdcpreauth_free_modreq_fn free_modreq; +} *krb5_kdcpreauth_vtable; /* * This function allows a preauth plugin to obtain preauth @@ -503,7 +479,7 @@ typedef struct krb5plugin_preauth_server_ftable_v1 { * should be freed by calling krb5_get_init_creds_opt_free_pa(). * * The 'opt' pointer supplied to this function must have been - * obtained using krb5_get_init_creds_opt_alloc() + * obtained using krb5_get_init_creds_opt_alloc(). */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_get_pa(krb5_context context, diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index d4bef89330..87bccdb59f 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -616,8 +616,7 @@ errout: /* fall through */ egress: - if (pa_context) - free_padata_context(kdc_context, &pa_context); + free_padata_context(kdc_context, pa_context); if (as_encrypting_key) krb5_free_keyblock(kdc_context, as_encrypting_key); if (errcode) diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 8378e997d9..d0a57b5fcb 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -91,58 +91,45 @@ #include <assert.h> #include "../include/krb5/preauth_plugin.h" -#if TARGET_OS_MAC -static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR, - LIBDIR "/krb5/plugins/preauth", - NULL }; /* should be a list */ -#else -static const char *objdirs[] = { LIBDIR "/krb5/plugins/preauth", NULL }; -#endif - -typedef struct _krb5_preauth_systems { +typedef struct preauth_system_st { const char *name; - int type; - int flags; - void *plugin_context; - preauth_server_init_proc init; - preauth_server_fini_proc fini; - preauth_server_edata_proc get_edata; - preauth_server_verify_proc verify_padata; - preauth_server_return_proc return_padata; - preauth_server_free_reqcontext_proc free_pa_reqctx; -} krb5_preauth_systems; + int type; + int flags; + krb5_kdcpreauth_moddata moddata; + krb5_kdcpreauth_init_fn init; + krb5_kdcpreauth_fini_fn fini; + krb5_kdcpreauth_edata_fn get_edata; + krb5_kdcpreauth_verify_fn verify_padata; + krb5_kdcpreauth_return_fn return_padata; + krb5_kdcpreauth_free_modreq_fn free_modreq; +} preauth_system; static krb5_error_code -verify_enc_timestamp (krb5_context, krb5_db_entry *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 get_entry_data, - void *pa_system_context, - void **pa_request_context, - krb5_data **e_data, - krb5_authdata ***authz_data); +verify_enc_timestamp(krb5_context, krb5_db_entry *client, krb5_data *req_pkt, + krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, + krb5_pa_data *data, + krb5_kdcpreauth_get_data_fn get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq *modreq_out, krb5_data **e_data, + krb5_authdata ***authz_data); static krb5_error_code -get_enc_ts(krb5_context, krb5_kdc_req *request, +get_enc_ts(krb5_context context, krb5_kdc_req *request, krb5_db_entry *client, krb5_db_entry *server, - preauth_get_entry_data_proc get_entry_data, - void *pa_system_context, - krb5_pa_data *data); + krb5_kdcpreauth_get_data_fn get_entry_data, + krb5_kdcpreauth_moddata modata, krb5_pa_data *data); static krb5_error_code -get_etype_info(krb5_context, krb5_kdc_req *request, +get_etype_info(krb5_context context, krb5_kdc_req *request, krb5_db_entry *client, krb5_db_entry *server, - preauth_get_entry_data_proc get_entry_data, - void *pa_system_context, - krb5_pa_data *data); + krb5_kdcpreauth_get_data_fn get_entry_data, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *data); static krb5_error_code get_etype_info2(krb5_context context, krb5_kdc_req *request, krb5_db_entry *client, krb5_db_entry *server, - preauth_get_entry_data_proc get_entry_data, - void *pa_system_context, - krb5_pa_data *pa_data); + krb5_kdcpreauth_get_data_fn get_entry_data, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data); static krb5_error_code etype_info_as_rep_helper(krb5_context context, krb5_pa_data * padata, @@ -154,40 +141,31 @@ etype_info_as_rep_helper(krb5_context context, krb5_pa_data * padata, int etype_info2); static krb5_error_code -return_etype_info(krb5_context, krb5_pa_data * padata, - krb5_db_entry *client, - krb5_data *req_pkt, - krb5_kdc_req *request, krb5_kdc_rep *reply, - krb5_key_data *client_key, - krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, - preauth_get_entry_data_proc get_entry_data, - void *pa_system_context, - void **pa_request_context); +return_etype_info(krb5_context, krb5_pa_data *padata, krb5_db_entry *client, + krb5_data *req_pkt, krb5_kdc_req *request, + krb5_kdc_rep *reply, krb5_key_data *client_key, + krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, + krb5_kdcpreauth_get_data_fn get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq); static krb5_error_code -return_etype_info2(krb5_context, krb5_pa_data * padata, - krb5_db_entry *client, - krb5_data *req_pkt, - krb5_kdc_req *request, krb5_kdc_rep *reply, - krb5_key_data *client_key, - krb5_keyblock *encrypting_key, - krb5_pa_data **send_pa, - preauth_get_entry_data_proc get_entry_data, - void *pa_system_context, - void **pa_request_context); +return_etype_info2(krb5_context, krb5_pa_data *padata, krb5_db_entry *client, + krb5_data *req_pkt, krb5_kdc_req *request, + krb5_kdc_rep *reply, krb5_key_data *client_key, + krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, + krb5_kdcpreauth_get_data_fn get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq); static krb5_error_code -return_pw_salt(krb5_context, krb5_pa_data * padata, - krb5_db_entry *client, - krb5_data *req_pkt, - krb5_kdc_req *request, krb5_kdc_rep *reply, - krb5_key_data *client_key, - krb5_keyblock *encrypting_key, +return_pw_salt(krb5_context, krb5_pa_data *padata, krb5_db_entry *client, + krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, + krb5_key_data *client_key, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - preauth_get_entry_data_proc get_entry_data, - void *pa_system_context, - void **pa_request_context); + krb5_kdcpreauth_get_data_fn get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq); #if APPLE_PKINIT @@ -227,7 +205,7 @@ static krb5_error_code return_pkinit_response( void **pa_request_context); #endif /* APPLE_PKINIT */ -static krb5_preauth_systems static_preauth_systems[] = { +static preauth_system static_preauth_systems[] = { #if APPLE_PKINIT { "pkinit", @@ -239,7 +217,7 @@ static krb5_preauth_systems static_preauth_systems[] = { get_pkinit_edata, verify_pkinit_request, return_pkinit_response, - NULL /* free_pa_request_context */ + NULL /* free_modreq */ }, #endif /* APPLE_PKINIT */ { @@ -318,219 +296,168 @@ static krb5_preauth_systems static_preauth_systems[] = { return_server_referral }, #endif - { "[end]", -1,} }; -static krb5_preauth_systems *preauth_systems; -static int n_preauth_systems; -static struct plugin_dir_handle preauth_plugins; +#define NUM_STATIC_PREAUTH_SYSTEMS (sizeof(static_preauth_systems) / \ + sizeof(*static_preauth_systems)) -/* Open plugin directories for preauth modules. */ -static krb5_error_code -open_preauth_plugin_dirs(krb5_context ctx) +static preauth_system *preauth_systems; +static size_t n_preauth_systems; + +/* Get all available kdcpreauth vtables and a count of preauth types they + * support. Return an empty list on failure. */ +static void +get_plugin_vtables(krb5_context context, + struct krb5_kdcpreauth_vtable_st **vtables_out, + size_t *n_tables_out, size_t *n_systems_out) { - static const char *path[] = { - KRB5_CONF_LIBDEFAULTS, KRB5_CONF_PREAUTH_MODULE_DIR, NULL, - }; - char **profpath = NULL; - const char **dirs; - krb5_error_code ret; + krb5_plugin_initvt_fn *plugins = NULL, *pl; + struct krb5_kdcpreauth_vtable_st *vtables; + size_t count, n_tables, n_systems, i; + + *vtables_out = NULL; + *n_tables_out = *n_systems_out = 0; + + /* Auto-register pkinit and encrypted challenge if possible. */ + k5_plugin_register_dyn(context, PLUGIN_INTERFACE_KDCPREAUTH, "pkinit", + "preauth"); + k5_plugin_register_dyn(context, PLUGIN_INTERFACE_KDCPREAUTH, + "encrypted_challenge", "preauth"); - ret = profile_get_values(ctx->profile, path, &profpath); - if (ret != 0 && ret != PROF_NO_RELATION) - return ret; - dirs = (profpath != NULL) ? (const char **) profpath : objdirs; - ret = krb5int_open_plugin_dirs(dirs, NULL, &preauth_plugins, &ctx->err); - profile_free_list(profpath); - return ret; + if (k5_plugin_load_all(context, PLUGIN_INTERFACE_KDCPREAUTH, &plugins)) + return; + for (count = 0; plugins[count]; count++); + vtables = calloc(count + 1, sizeof(*vtables)); + if (vtables == NULL) + goto cleanup; + for (pl = plugins, n_tables = 0; *pl != NULL; pl++) { + if ((*pl)(context, 1, 1, (krb5_plugin_vtable)&vtables[n_tables]) == 0) + n_tables++; + } + for (i = 0, n_systems = 0; i < n_tables; i++) { + for (count = 0; vtables[i].pa_type_list[count] > 0; count++); + n_systems += count; + } + *vtables_out = vtables; + *n_tables_out = n_tables; + *n_systems_out = n_systems; + +cleanup: + k5_plugin_free_modules(context, plugins); } -krb5_error_code -load_preauth_plugins(krb5_context context) +/* Make a list of realm names. The caller should free the list container but + * not the list elements (which are aliases into kdc_realmlist). */ +static krb5_error_code +get_realm_names(const char ***list_out) { - void **preauth_plugins_ftables; - struct krb5plugin_preauth_server_ftable_v1 *ftable; - size_t module_count, i, j, k; - void *plugin_context; - preauth_server_init_proc server_init_proc = NULL; - char **kdc_realm_names = NULL; - - /* Attempt to load all of the preauth plugins we can find. */ - PLUGIN_DIR_INIT(&preauth_plugins); - if (PLUGIN_DIR_OPEN(&preauth_plugins) == 0) { - if (open_preauth_plugin_dirs(context) != 0) - return KRB5_PLUGIN_NO_HANDLE; - } - - /* Get the method tables provided by the loaded plugins. */ - preauth_plugins_ftables = NULL; - if (krb5int_get_plugin_dir_data(&preauth_plugins, - "preauthentication_server_1", - &preauth_plugins_ftables, &context->err) != 0) { - return KRB5_PLUGIN_NO_HANDLE; - } - - /* Count the valid modules. */ - module_count = sizeof(static_preauth_systems) - / sizeof(static_preauth_systems[0]); - if (preauth_plugins_ftables != NULL) { - for (i = 0; preauth_plugins_ftables[i] != NULL; i++) { - ftable = preauth_plugins_ftables[i]; - if ((ftable->flags_proc == NULL) && - (ftable->edata_proc == NULL) && - (ftable->verify_proc == NULL) && - (ftable->return_proc == NULL)) { - continue; - } - for (j = 0; - ftable->pa_type_list != NULL && - ftable->pa_type_list[j] > 0; - j++) { - module_count++; - } - } - } + const char **list; + int i; - /* Build the complete list of supported preauthentication options, and - * leave room for a terminator entry. */ - preauth_systems = malloc(sizeof(krb5_preauth_systems) * (module_count + 1)); - if (preauth_systems == NULL) { - krb5int_free_plugin_dir_data(preauth_plugins_ftables); + list = calloc(kdc_numrealms + 1, sizeof(*list)); + if (list == NULL) return ENOMEM; - } + for (i = 0; i < kdc_numrealms; i++) + list[i] = kdc_realmlist[i]->realm_name; + list[i] = NULL; + *list_out = list; + return 0; +} - /* Build a list of the names of the supported realms for this KDC. - * The list of names is terminated with a NULL. */ - kdc_realm_names = malloc(sizeof(char *) * (kdc_numrealms + 1)); - if (kdc_realm_names == NULL) { - krb5int_free_plugin_dir_data(preauth_plugins_ftables); - return ENOMEM; - } - for (i = 0; i < (size_t)kdc_numrealms; i++) { - kdc_realm_names[i] = kdc_realmlist[i]->realm_name; - } - kdc_realm_names[i] = NULL; +void +load_preauth_plugins(krb5_context context) +{ + krb5_error_code ret; + struct krb5_kdcpreauth_vtable_st *vtables = NULL, *vt; + size_t n_systems, n_tables, i, j; + krb5_kdcpreauth_moddata moddata; + const char **realm_names = NULL, *emsg; + preauth_system *sys; + + /* Get all available kdcpreauth vtables. */ + get_plugin_vtables(context, &vtables, &n_tables, &n_systems); + + /* Allocate the list of static and plugin preauth systems. */ + n_systems += NUM_STATIC_PREAUTH_SYSTEMS; + preauth_systems = calloc(n_systems + 1, sizeof(preauth_system)); + if (preauth_systems == NULL) + goto cleanup; - /* Add the locally-supplied mechanisms to the dynamic list first. */ - for (i = 0, k = 0; - i < sizeof(static_preauth_systems) / sizeof(static_preauth_systems[0]); - i++) { - if (static_preauth_systems[i].type == -1) - break; - preauth_systems[k] = static_preauth_systems[i]; - /* Try to initialize the preauth system. If it fails, we'll remove it - * from the list of systems we'll be using. */ - plugin_context = NULL; - server_init_proc = static_preauth_systems[i].init; - if ((server_init_proc != NULL) && - ((*server_init_proc)(context, &plugin_context, - (const char **)kdc_realm_names) != 0)) { - memset(&preauth_systems[k], 0, sizeof(preauth_systems[k])); - continue; - } - preauth_systems[k].plugin_context = plugin_context; - k++; - } - - /* Now add the dynamically-loaded mechanisms to the list. */ - if (preauth_plugins_ftables != NULL) { - for (i = 0; preauth_plugins_ftables[i] != NULL; i++) { - ftable = preauth_plugins_ftables[i]; - if ((ftable->flags_proc == NULL) && - (ftable->edata_proc == NULL) && - (ftable->verify_proc == NULL) && - (ftable->return_proc == NULL)) { + if (get_realm_names(&realm_names)) + goto cleanup; + + /* Add the static system to the list first. No static systems require + * initialization, so just make a direct copy. */ + memcpy(preauth_systems, static_preauth_systems, + sizeof(static_preauth_systems)); + + /* Add the dynamically-loaded mechanisms to the list. */ + n_systems = NUM_STATIC_PREAUTH_SYSTEMS; + for (i = 0; i < n_tables; i++) { + /* Try to initialize this module. */ + vt = &vtables[i]; + moddata = NULL; + if (vt->init) { + ret = vt->init(context, &moddata, realm_names); + if (ret) { + emsg = krb5_get_error_message(context, ret); + krb5_klog_syslog(LOG_ERR, _("preauth %s failed to " + "initialize: %s"), vt->name, emsg); + krb5_free_error_message(context, emsg); continue; } - plugin_context = NULL; - for (j = 0; - ftable->pa_type_list != NULL && - ftable->pa_type_list[j] > 0; - j++) { - /* Try to initialize the plugin. If it fails, we'll remove it - * from the list of modules we'll be using. */ - if (j == 0) { - server_init_proc = ftable->init_proc; - if (server_init_proc != NULL) { - krb5_error_code initerr; - initerr = (*server_init_proc)(context, &plugin_context, - (const char **)kdc_realm_names); - if (initerr) { - const char *emsg; - emsg = krb5_get_error_message(context, initerr); - krb5_klog_syslog(LOG_ERR, _("preauth %s failed to " - "initialize: %s"), - ftable->name, emsg); - krb5_free_error_message(context, emsg); - memset(&preauth_systems[k], 0, - sizeof(preauth_systems[k])); - - break; /* skip all modules in this plugin */ - } - } - } - preauth_systems[k].name = ftable->name; - preauth_systems[k].type = ftable->pa_type_list[j]; - if (ftable->flags_proc != NULL) - preauth_systems[k].flags = ftable->flags_proc(context, - preauth_systems[k].type); - else - preauth_systems[k].flags = 0; - preauth_systems[k].plugin_context = plugin_context; - preauth_systems[k].init = server_init_proc; - /* Only call fini once for each plugin */ - if (j == 0) - preauth_systems[k].fini = ftable->fini_proc; - else - preauth_systems[k].fini = NULL; - preauth_systems[k].get_edata = ftable->edata_proc; - preauth_systems[k].verify_padata = ftable->verify_proc; - preauth_systems[k].return_padata = ftable->return_proc; - preauth_systems[k].free_pa_reqctx = - ftable->freepa_reqcontext_proc; - k++; - } } - krb5int_free_plugin_dir_data(preauth_plugins_ftables); + /* Add this module to the systems list once for each pa type. */ + for (j = 0; vt->pa_type_list[j] > 0; j++) { + sys = &preauth_systems[n_systems]; + sys->name = vt->name; + sys->type = vt->pa_type_list[j]; + sys->flags = (vt->flags) ? vt->flags(context, sys->type) : 0; + sys->moddata = moddata; + sys->init = vt->init; + /* Only call fini once for each plugin. */ + sys->fini = (j == 0) ? vt->fini : NULL; + sys->get_edata = vt->edata; + sys->verify_padata = vt->verify; + sys->return_padata = vt->return_padata; + sys->free_modreq = vt->free_modreq; + n_systems++; + } } - free(kdc_realm_names); - n_preauth_systems = k; + n_preauth_systems = n_systems; /* Add the end-of-list marker. */ - preauth_systems[k].name = "[end]"; - preauth_systems[k].type = -1; - return 0; + preauth_systems[n_systems].name = "[end]"; + preauth_systems[n_systems].type = -1; + +cleanup: + free(vtables); + free(realm_names); } -krb5_error_code +void unload_preauth_plugins(krb5_context context) { - int i; - if (preauth_systems != NULL) { - for (i = 0; i < n_preauth_systems; i++) { - if (preauth_systems[i].fini != NULL) { - (*preauth_systems[i].fini)(context, - preauth_systems[i].plugin_context); - } - memset(&preauth_systems[i], 0, sizeof(preauth_systems[i])); - } - free(preauth_systems); - preauth_systems = NULL; - n_preauth_systems = 0; - krb5int_close_plugin_dirs(&preauth_plugins); + size_t i; + + for (i = 0; i < n_preauth_systems; i++) { + if (preauth_systems[i].fini) + preauth_systems[i].fini(context, preauth_systems[i].moddata); } - return 0; + free(preauth_systems); + preauth_systems = NULL; + n_preauth_systems = 0; } /* - * The make_padata_context() function creates a space for storing any context - * information which will be needed by return_padata() later. Each preauth - * type gets a context storage location of its own. + * The make_padata_context() function creates a space for storing any + * request-specific module data which will be needed by return_padata() later. + * Each preauth type gets a storage location of its own. */ struct request_pa_context { int n_contexts; struct { - krb5_preauth_systems *pa_system; - void *pa_context; + preauth_system *pa_system; + krb5_kdcpreauth_modreq modreq; } *contexts; }; @@ -556,7 +483,7 @@ make_padata_context(krb5_context context, void **padata_context) for (i = 0; i < ret->n_contexts; i++) { ret->contexts[i].pa_system = &preauth_systems[i]; - ret->contexts[i].pa_context = NULL; + ret->contexts[i].modreq = NULL; } *padata_context = ret; @@ -569,35 +496,25 @@ make_padata_context(krb5_context context, void **padata_context) * which the check_padata() function created but which weren't already cleaned * up by return_padata(). */ -krb5_error_code -free_padata_context(krb5_context kcontext, void **padata_context) +void +free_padata_context(krb5_context kcontext, void *padata_context) { - struct request_pa_context *context; - krb5_preauth_systems *preauth_system; - void **pctx, *mctx; + struct request_pa_context *context = padata_context; + preauth_system *sys; int i; - if (padata_context == NULL) - return 0; - - context = *padata_context; - + if (context == NULL) + return; for (i = 0; i < context->n_contexts; i++) { - if (context->contexts[i].pa_context != NULL) { - preauth_system = context->contexts[i].pa_system; - mctx = preauth_system->plugin_context; - if (preauth_system->free_pa_reqctx != NULL) { - pctx = &context->contexts[i].pa_context; - (*preauth_system->free_pa_reqctx)(kcontext, mctx, pctx); - } - context->contexts[i].pa_context = NULL; - } + sys = context->contexts[i].pa_system; + if (!sys->free_modreq || !context->contexts[i].modreq) + continue; + sys->free_modreq(kcontext, sys->moddata, context->contexts[i].modreq); + context->contexts[i].modreq = NULL; } free(context->contexts); free(context); - - return 0; } /* Retrieve a specified tl_data item from the given entry, and return its @@ -637,10 +554,8 @@ get_entry_tl_data(krb5_context context, krb5_db_entry *entry, * modules. */ static krb5_error_code -get_entry_data(krb5_context context, - krb5_kdc_req *request, krb5_db_entry *entry, - krb5_int32 type, - krb5_data **result) +get_entry_data(krb5_context context, krb5_kdc_req *request, + krb5_db_entry *entry, krb5_int32 type, krb5_data **result) { int i, k; krb5_data *ret; @@ -651,11 +566,11 @@ get_entry_data(krb5_context context, struct kdc_request_state *state = request->kdc_state; switch (type) { - case krb5plugin_preauth_entry_request_certificate: + case krb5_kdcpreauth_request_certificate: return get_entry_tl_data(context, entry, KRB5_TL_USER_CERTIFICATE, result); break; - case krb5plugin_preauth_entry_max_time_skew: + case krb5_kdcpreauth_max_time_skew: ret = malloc(sizeof(krb5_data)); if (ret == NULL) return ENOMEM; @@ -670,7 +585,7 @@ get_entry_data(krb5_context context, *result = ret; return 0; break; - case krb5plugin_preauth_keys: + case krb5_kdcpreauth_keys: ret = malloc(sizeof(krb5_data)); if (ret == NULL) return ENOMEM; @@ -705,7 +620,7 @@ get_entry_data(krb5_context context, free(ret); } break; - case krb5plugin_preauth_request_body: + case krb5_kdcpreauth_request_body: ret = NULL; encode_krb5_kdc_req_body(request, &ret); if (ret != NULL) { @@ -714,7 +629,7 @@ get_entry_data(krb5_context context, } return ASN1_PARSE_ERROR; break; - case krb5plugin_preauth_fast_armor: + case krb5_kdcpreauth_fast_armor: ret = calloc(1, sizeof(krb5_data)); if (ret == NULL) return ENOMEM; @@ -731,7 +646,7 @@ get_entry_data(krb5_context context, } free(ret); return error; - case krb5plugin_preauth_free_fast_armor: + case krb5_kdcpreauth_free_fast_armor: if ((*result)->data) { keys = (krb5_keyblock *) (*result)->data; krb5_free_keyblock(context, keys); @@ -745,9 +660,9 @@ get_entry_data(krb5_context context, } static krb5_error_code -find_pa_system(int type, krb5_preauth_systems **preauth) +find_pa_system(int type, preauth_system **preauth) { - krb5_preauth_systems *ap; + preauth_system *ap; ap = preauth_systems ? preauth_systems : static_preauth_systems; while ((ap->type != -1) && (ap->type != type)) @@ -758,21 +673,20 @@ find_pa_system(int type, krb5_preauth_systems **preauth) return 0; } +/* Find a pointer to the request-specific module data for pa_sys. */ static krb5_error_code -find_pa_context(krb5_preauth_systems *pa_sys, - struct request_pa_context *context, - void ***pa_context) +find_modreq(preauth_system *pa_sys, struct request_pa_context *context, + krb5_kdcpreauth_modreq **modreq_out) { int i; - *pa_context = 0; - + *modreq_out = NULL; if (context == NULL) return KRB5KRB_ERR_GENERIC; for (i = 0; i < context->n_contexts; i++) { if (context->contexts[i].pa_system == pa_sys) { - *pa_context = &context->contexts[i].pa_context; + *modreq_out = &context->contexts[i].modreq; return 0; } } @@ -797,7 +711,7 @@ pa_list_includes(krb5_pa_data **pa_data, krb5_preauthtype pa_type) static void sort_pa_order(krb5_context context, krb5_kdc_req *request, int *pa_order) { - int i, j, k, n_repliers, n_key_replacers; + size_t i, j, k, n_repliers, n_key_replacers; /* First, set up the default order. */ i = 0; @@ -909,7 +823,7 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client, krb5_db_entry *server, krb5_data *e_data) { int hw_only; - krb5_preauth_systems *ap; + preauth_system *ap; krb5_pa_data **pa_data, **pa; krb5_data *edat; krb5_error_code retval; @@ -937,8 +851,8 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client, (*pa)->magic = KV5M_PA_DATA; (*pa)->pa_type = ap->type; if (ap->get_edata) { - retval = (ap->get_edata)(kdc_context, request, client, server, - get_entry_data, ap->plugin_context, *pa); + retval = ap->get_edata(kdc_context, request, client, server, + get_entry_data, ap->moddata, *pa); if (retval) { /* just failed on this type, continue */ free(*pa); @@ -1033,8 +947,8 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, { krb5_error_code retval = 0; krb5_pa_data **padata; - krb5_preauth_systems *pa_sys; - void **pa_context; + preauth_system *pa_sys; + krb5_kdcpreauth_modreq *modreq_ptr; krb5_data *pa_e_data = NULL, *tmp_e_data = NULL; int pa_ok = 0, pa_found = 0; krb5_error_code saved_retval = 0; @@ -1058,7 +972,7 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, #endif if (find_pa_system((*padata)->pa_type, &pa_sys)) continue; - if (find_pa_context(pa_sys, *padata_context, &pa_context)) + if (find_modreq(pa_sys, *padata_context, &modreq_ptr)) continue; #ifdef DEBUG krb5_klog_syslog (LOG_DEBUG, ".. pa_type %s", pa_sys->name); @@ -1068,8 +982,9 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, pa_found++; retval = pa_sys->verify_padata(context, client, req_pkt, request, enc_tkt_reply, *padata, - get_entry_data, pa_sys->plugin_context, - pa_context, &tmp_e_data, &tmp_authz_data); + get_entry_data, pa_sys->moddata, + modreq_ptr, &tmp_e_data, + &tmp_authz_data); if (retval) { emsg = krb5_get_error_message (context, retval); krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s", @@ -1211,11 +1126,11 @@ return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, krb5_pa_data ** send_pa; krb5_pa_data * pa = 0; krb5_pa_data null_item; - krb5_preauth_systems * ap; + preauth_system * ap; int * pa_order; int * pa_type; int size = 0; - void ** pa_context; + krb5_kdcpreauth_modreq *modreq_ptr; krb5_boolean key_modified; krb5_keyblock original_key; if ((!*padata_context) && @@ -1265,7 +1180,7 @@ return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, continue; if (ap->return_padata == 0) continue; - if (find_pa_context(ap, *padata_context, &pa_context)) + if (find_modreq(ap, *padata_context, &modreq_ptr)) continue; pa = &null_item; null_item.pa_type = ap->type; @@ -1280,8 +1195,8 @@ return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt, if ((retval = ap->return_padata(context, pa, client, req_pkt, request, reply, client_key, encrypting_key, send_pa, - get_entry_data, ap->plugin_context, - pa_context))) { + get_entry_data, ap->moddata, + *modreq_ptr))) { goto cleanup; } @@ -1320,9 +1235,8 @@ request_contains_enctype(krb5_context context, const krb5_kdc_req *request, static krb5_error_code get_enc_ts(krb5_context context, krb5_kdc_req *request, krb5_db_entry *client, krb5_db_entry *server, - preauth_get_entry_data_proc get_entry_data_proc, - void *pa_system_context, - krb5_pa_data *data) + krb5_kdcpreauth_get_data_fn get_entry_data_proc, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) { struct kdc_request_state *state = request->kdc_state; if (state->armor_key) @@ -1333,12 +1247,11 @@ get_enc_ts(krb5_context context, krb5_kdc_req *request, static krb5_error_code verify_enc_timestamp(krb5_context context, krb5_db_entry *client, - krb5_data *req_pkt, - krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *pa, - preauth_get_entry_data_proc ets_get_entry_data, - void *pa_system_context, - void **pa_request_context, + krb5_data *req_pkt, krb5_kdc_req *request, + krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *pa, + krb5_kdcpreauth_get_data_fn ets_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq *modreq_out, krb5_data **e_data, krb5_authdata ***authz_data) { @@ -1580,9 +1493,8 @@ cleanup: static krb5_error_code get_etype_info(krb5_context context, krb5_kdc_req *request, krb5_db_entry *client, krb5_db_entry *server, - preauth_get_entry_data_proc etype_get_entry_data, - void *pa_system_context, - krb5_pa_data *pa_data) + krb5_kdcpreauth_get_data_fn etype_get_entry_data, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data) { int i; for (i=0; i < request->nktypes; i++) { @@ -1597,9 +1509,8 @@ get_etype_info(krb5_context context, krb5_kdc_req *request, static krb5_error_code get_etype_info2(krb5_context context, krb5_kdc_req *request, krb5_db_entry *client, krb5_db_entry *server, - preauth_get_entry_data_proc etype_get_entry_data, - void *pa_system_context, - krb5_pa_data *pa_data) + krb5_kdcpreauth_get_data_fn etype_get_entry_data, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data) { return etype_info_helper( context, request, client, server, pa_data, 1); } @@ -1689,9 +1600,9 @@ return_etype_info2(krb5_context context, krb5_pa_data * padata, krb5_key_data *client_key, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - preauth_get_entry_data_proc etype_get_entry_data, - void *pa_system_context, - void **pa_request_context) + krb5_kdcpreauth_get_data_fn etype_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq) { return etype_info_as_rep_helper(context, padata, client, request, reply, client_key, encrypting_key, send_pa, 1); @@ -1706,9 +1617,9 @@ return_etype_info(krb5_context context, krb5_pa_data * padata, krb5_key_data *client_key, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - preauth_get_entry_data_proc etypeget_entry_data, - void *pa_system_context, - void **pa_request_context) + krb5_kdcpreauth_get_data_fn etypeget_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq) { return etype_info_as_rep_helper(context, padata, client, request, reply, client_key, encrypting_key, send_pa, 0); @@ -1716,12 +1627,13 @@ return_etype_info(krb5_context context, krb5_pa_data * padata, static krb5_error_code return_pw_salt(krb5_context context, krb5_pa_data *in_padata, - krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request, - krb5_kdc_rep *reply, krb5_key_data *client_key, - krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - preauth_get_entry_data_proc etype_get_entry_data, - void *pa_system_context, - void **pa_request_context) + krb5_db_entry *client, krb5_data *req_pkt, + krb5_kdc_req *request, krb5_kdc_rep *reply, + krb5_key_data *client_key, krb5_keyblock *encrypting_key, + krb5_pa_data **send_pa, + krb5_kdcpreauth_get_data_fn etype_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq) { krb5_error_code retval; krb5_pa_data * padata; diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 2f85b0274e..20e8ac46dd 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -170,9 +170,9 @@ get_preauth_hint_list (krb5_kdc_req * request, krb5_db_entry *client, krb5_db_entry *server, krb5_data *e_data); -krb5_error_code +void load_preauth_plugins(krb5_context context); -krb5_error_code +void unload_preauth_plugins(krb5_context context); krb5_error_code @@ -189,8 +189,8 @@ return_padata (krb5_context context, krb5_db_entry *client, krb5_key_data *client_key, krb5_keyblock *encrypting_key, void **padata_context); -krb5_error_code -free_padata_context (krb5_context context, void **padata_context); +void +free_padata_context(krb5_context context, void *padata_context); krb5_pa_data * find_pa_data (krb5_pa_data **padata, krb5_preauthtype pa_type); diff --git a/src/lib/krb5/krb/copy_ctx.c b/src/lib/krb5/krb/copy_ctx.c index c524721190..9d2c3e4918 100644 --- a/src/lib/krb5/krb/copy_ctx.c +++ b/src/lib/krb5/krb/copy_ctx.c @@ -79,9 +79,6 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out) nctx->prompt_types = NULL; nctx->os_context.default_ccname = NULL; - memset(&nctx->preauth_plugins, 0, sizeof(nctx->preauth_plugins)); - nctx->preauth_context = NULL; - memset(&nctx->libkrb5_plugins, 0, sizeof(nctx->libkrb5_plugins)); nctx->vtbl = NULL; nctx->locate_fptrs = NULL; diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index fc00e21d7b..2968bd7ba0 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -705,7 +705,7 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx, code = krb5int_fast_make_state(context, &ctx->fast_state); if (code != 0) goto cleanup; - ctx->get_data_rock.fast_state = ctx->fast_state; + ctx->preauth_rock.fast_state = ctx->fast_state; krb5_preauth_request_context_init(context); if (ctx->encoded_request_body) { krb5_free_data(context, ctx->encoded_request_body); @@ -837,8 +837,8 @@ krb5_init_creds_init(krb5_context context, opte = ctx->opte; - ctx->get_data_rock.magic = CLIENT_ROCK_MAGIC; - ctx->get_data_rock.etype = &ctx->etype; + ctx->preauth_rock.magic = CLIENT_ROCK_MAGIC; + ctx->preauth_rock.etype = &ctx->etype; /* Initialise request parameters as per krb5_get_init_creds() */ ctx->request->kdc_options = context->kdc_default_options; @@ -1116,7 +1116,7 @@ init_creds_step_request(krb5_context context, ctx->prompter_data, ctx->gak_fct, ctx->gak_data, - &ctx->get_data_rock, + &ctx->preauth_rock, ctx->opte); if (code != 0) goto cleanup; @@ -1141,7 +1141,7 @@ init_creds_step_request(krb5_context context, ctx->prompter_data, ctx->gak_fct, ctx->gak_data, - &ctx->get_data_rock, + &ctx->preauth_rock, ctx->opte); } else { /* No preauth supplied, so can't query the plugins. */ @@ -1373,7 +1373,7 @@ init_creds_step_reply(krb5_context context, ctx->prompter_data, ctx->gak_fct, ctx->gak_data, - &ctx->get_data_rock, + &ctx->preauth_rock, ctx->opte); if (code != 0) goto cleanup; diff --git a/src/lib/krb5/krb/gic_opt_set_pa.c b/src/lib/krb5/krb/gic_opt_set_pa.c index a60cc3b2f3..1e79c42329 100644 --- a/src/lib/krb5/krb/gic_opt_set_pa.c +++ b/src/lib/krb5/krb/gic_opt_set_pa.c @@ -97,50 +97,3 @@ krb5_get_init_creds_opt_set_pa(krb5_context context, retval = krb5_preauth_supply_preauth_data(context, opte, attr, value); return retval; } - -/* - * Give all the preauth plugins a look at the preauth option which - * has just been set - */ -krb5_error_code -krb5_preauth_supply_preauth_data(krb5_context context, - krb5_gic_opt_ext *opte, - const char *attr, - const char *value) -{ - krb5_error_code retval = 0; - int i; - void *pctx; - const char *emsg = NULL; - - if (context->preauth_context == NULL) - krb5_init_preauth_context(context); - if (context->preauth_context == NULL) { - retval = EINVAL; - krb5int_set_error(&context->err, retval, - _("Unable to initialize preauth context")); - return retval; - } - - /* - * Go down the list of preauth modules, and supply them with the - * attribute/value pair. - */ - for (i = 0; i < context->preauth_context->n_modules; i++) { - if (context->preauth_context->modules[i].client_supply_gic_opts == NULL) - continue; - pctx = context->preauth_context->modules[i].plugin_context; - retval = (*context->preauth_context->modules[i].client_supply_gic_opts) - (context, pctx, - (krb5_get_init_creds_opt *)opte, attr, value); - if (retval) { - emsg = krb5_get_error_message(context, retval); - krb5int_set_error(&context->err, retval, - _("Preauth plugin %s: %s"), - context->preauth_context->modules[i].name, emsg); - krb5_free_error_message(context, emsg); - break; - } - } - return retval; -} diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h index 6a762982c0..de43163d85 100644 --- a/src/lib/krb5/krb/init_creds_ctx.h +++ b/src/lib/krb5/krb/init_creds_ctx.h @@ -29,7 +29,7 @@ struct _krb5_init_creds_context { krb5_data s2kparams; krb5_keyblock as_key; krb5_enctype etype; - krb5_preauth_client_rock get_data_rock; + struct krb5_clpreauth_rock_st preauth_rock; krb5_boolean enc_pa_rep_permitted; krb5_boolean have_restarted; krb5_boolean sent_nontrivial_preauth; diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c index a9d6b06a7b..6f164e0a68 100644 --- a/src/lib/krb5/krb/plugin.c +++ b/src/lib/krb5/krb/plugin.c @@ -28,7 +28,9 @@ const char *interface_names[PLUGIN_NUM_INTERFACES] = { "pwqual", - "kadm5_hook" + "kadm5_hook", + "clpreauth", + "kdcpreauth" }; /* Return the context's interface structure for id, or NULL if invalid. */ diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c index 82b422eac8..ef866b1a24 100644 --- a/src/lib/krb5/krb/preauth2.c +++ b/src/lib/krb5/krb/preauth2.c @@ -44,13 +44,41 @@ #include <unistd.h> #endif -#if TARGET_OS_MAC -static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR, - LIBDIR "/krb5/plugins/preauth", - NULL }; -#else -static const char *objdirs[] = { LIBDIR "/krb5/plugins/preauth", NULL }; -#endif +/* This structure lets us keep track of all of the modules which are loaded, + * turning the list of modules and their lists of implemented preauth types + * into a single list which we can walk easily. */ +struct krb5_preauth_context_st { + int n_modules; + struct krb5_preauth_context_module_st { + /* Which of the possibly more than one preauth types which the + * module supports we're using at this point in the list. */ + krb5_preauthtype pa_type; + /* Encryption types which the client claims to support -- we + * copy them directly into the krb5_kdc_req structure during + * krb5_preauth_prepare_request(). */ + krb5_enctype *enctypes; + /* The plugin's module data and a function to clear it. */ + krb5_clpreauth_moddata moddata; + krb5_clpreauth_fini_fn client_fini; + /* The module's table, and some of its members, copied here for + * convenience when we populated the list. */ + const char *name; + int flags, use_count; + krb5_clpreauth_process_fn client_process; + krb5_clpreauth_tryagain_fn client_tryagain; + krb5_clpreauth_supply_gic_opts_fn client_supply_gic_opts; + krb5_clpreauth_request_init_fn client_req_init; + krb5_clpreauth_request_fini_fn client_req_fini; + /* The per-request context which the client_req_init() function + * might allocate, which we'll need to clean up later by + * calling the client_req_fini() function. */ + krb5_clpreauth_modreq modreq; + /* A pointer to the request_context pointer. All modules within + * a plugin will point at the request_context of the first + * module within the plugin. */ + krb5_clpreauth_modreq *modreq_p; + } *modules; +}; typedef krb5_error_code (*pa_function)(krb5_context, krb5_kdc_req *request, @@ -70,27 +98,6 @@ typedef struct _pa_types_t { int flags; } pa_types_t; -/* Open plugin directories for preauth modules. */ -static krb5_error_code -open_preauth_plugin_dirs(krb5_context ctx) -{ - static const char *path[] = { - KRB5_CONF_LIBDEFAULTS, KRB5_CONF_PREAUTH_MODULE_DIR, NULL, - }; - char **profpath = NULL; - const char **dirs; - krb5_error_code ret; - - ret = profile_get_values(ctx->profile, path, &profpath); - if (ret != 0 && ret != PROF_NO_RELATION) - return ret; - dirs = (profpath != NULL) ? (const char **) profpath : objdirs; - ret = krb5int_open_plugin_dirs(dirs, NULL, &ctx->preauth_plugins, - &ctx->err); - profile_free_list(profpath); - return ret; -} - /* Create the per-krb5_context context. This means loading the modules * if we haven't done that yet (applications which never obtain initial * credentials should never hit this routine), breaking up the module's @@ -99,101 +106,88 @@ open_preauth_plugin_dirs(krb5_context ctx) void KRB5_CALLCONV krb5_init_preauth_context(krb5_context kcontext) { - int n_modules, n_tables, i, j, k; - void **tables; - struct krb5plugin_preauth_client_ftable_v1 *table; + int n_tables, n_modules, i, count; + krb5_plugin_initvt_fn *plugins = NULL, *pl; + struct krb5_clpreauth_vtable_st *vtables = NULL, *vt; + struct krb5_preauth_context_module_st *mod; krb5_preauth_context *context = NULL; - void *plugin_context; - krb5_preauthtype pa_type; - void **rcpp; + krb5_clpreauth_moddata moddata; + krb5_preauthtype pa_type, *pat; + krb5_boolean first; + krb5_clpreauth_modreq *rcpp; /* Only do this once for each krb5_context */ if (kcontext->preauth_context != NULL) return; - /* load the plugins for the current context */ - if (PLUGIN_DIR_OPEN(&kcontext->preauth_plugins) == 0) { - if (open_preauth_plugin_dirs(kcontext) != 0) - return; - } + /* Auto-register pkinit and encrypted challenge if possible. */ + k5_plugin_register_dyn(kcontext, PLUGIN_INTERFACE_CLPREAUTH, "pkinit", + "preauth"); + k5_plugin_register_dyn(kcontext, PLUGIN_INTERFACE_CLPREAUTH, + "encrypted_challenge", "preauth"); - /* pull out the module function tables for all of the modules */ - tables = NULL; - if (krb5int_get_plugin_dir_data(&kcontext->preauth_plugins, - "preauthentication_client_1", - &tables, - &kcontext->err) != 0) { - return; - } - if (tables == NULL) { + /* Get all available clpreauth vtables. */ + if (k5_plugin_load_all(kcontext, PLUGIN_INTERFACE_CLPREAUTH, &plugins)) return; + for (count = 0; plugins[count] != NULL; count++); + vtables = calloc(count, sizeof(*vtables)); + if (vtables == NULL) + goto cleanup; + for (pl = plugins, n_tables = 0; *pl != NULL; pl++) { + if ((*pl)(kcontext, 1, 1, (krb5_plugin_vtable)&vtables[n_tables]) == 0) + n_tables++; } - /* count how many modules we ended up loading, and how many preauth - * types we may claim to support as a result */ + /* Count how many modules we ended up loading, and how many preauth + * types we may claim to support as a result. */ n_modules = 0; - for (n_tables = 0; - (tables != NULL) && (tables[n_tables] != NULL); - n_tables++) { - table = tables[n_tables]; - if ((table->pa_type_list != NULL) && (table->process != NULL)) { - for (j = 0; table->pa_type_list[j] > 0; j++) { - n_modules++; - } - } + for (i = 0; i < n_tables; i++) { + for (count = 0; vtables[i].pa_type_list[count] > 0; count++); + n_modules += count; } - /* allocate the space we need */ + /* Allocate the space we need. */ context = malloc(sizeof(*context)); - if (context == NULL) { - krb5int_free_plugin_dir_data(tables); - return; - } - context->modules = calloc(n_modules, sizeof(context->modules[0])); - if (context->modules == NULL) { - krb5int_free_plugin_dir_data(tables); - free(context); - return; - } - context->n_modules = n_modules; + if (context == NULL) + goto cleanup; + context->modules = calloc(n_modules, sizeof(*context->modules)); + if (context->modules == NULL) + goto cleanup; /* fill in the structure */ - k = 0; + n_modules = 0; for (i = 0; i < n_tables; i++) { - table = tables[i]; - if ((table->pa_type_list != NULL) && (table->process != NULL)) { - plugin_context = NULL; - if ((table->init != NULL) && - ((*table->init)(kcontext, &plugin_context) != 0)) { + vt = &vtables[i]; + if ((vt->pa_type_list != NULL) && (vt->process != NULL)) { + moddata = NULL; + if (vt->init != NULL && vt->init(kcontext, &moddata) != 0) { #ifdef DEBUG - fprintf (stderr, "init err, skipping module \"%s\"\n", - table->name); + fprintf(stderr, "init err, skipping module \"%s\"\n", + vt->name); #endif continue; } rcpp = NULL; - for (j = 0; table->pa_type_list[j] > 0; j++) { - pa_type = table->pa_type_list[j]; - context->modules[k].pa_type = pa_type; - context->modules[k].enctypes = table->enctype_list; - context->modules[k].plugin_context = plugin_context; + for (pat = vt->pa_type_list, first = TRUE; *pat > 0; + pat++, first = FALSE) { + pa_type = *pat; + mod = &context->modules[n_modules]; + mod->pa_type = pa_type; + mod->enctypes = vt->enctype_list; + mod->moddata = moddata; /* Only call client_fini once per plugin */ - if (j == 0) - context->modules[k].client_fini = table->fini; - else - context->modules[k].client_fini = NULL; - context->modules[k].ftable = table; - context->modules[k].name = table->name; - context->modules[k].flags = (*table->flags)(kcontext, pa_type); - context->modules[k].use_count = 0; - context->modules[k].client_process = table->process; - context->modules[k].client_tryagain = table->tryagain; - if (j == 0) - context->modules[k].client_supply_gic_opts = table->gic_opts; + if (first) + mod->client_fini = vt->fini; else - context->modules[k].client_supply_gic_opts = NULL; - context->modules[k].request_context = NULL; + mod->client_fini = NULL; + mod->name = vt->name; + mod->flags = (*vt->flags)(kcontext, pa_type); + mod->use_count = 0; + mod->client_process = vt->process; + mod->client_tryagain = vt->tryagain; + mod->client_supply_gic_opts = first ? vt->gic_opts : NULL; + mod->modreq = NULL; /* * Only call request_init and request_fini once per plugin. * Only the first module within each plugin will ever @@ -202,29 +196,35 @@ krb5_init_preauth_context(krb5_context kcontext) * to that entry's request_context. That way all the * modules within the plugin share the same request_context */ - if (j == 0) { - context->modules[k].client_req_init = table->request_init; - context->modules[k].client_req_fini = table->request_fini; - rcpp = &context->modules[k].request_context; + if (first) { + mod->client_req_init = vt->request_init; + mod->client_req_fini = vt->request_fini; + rcpp = &mod->modreq; } else { - context->modules[k].client_req_init = NULL; - context->modules[k].client_req_fini = NULL; + mod->client_req_init = NULL; + mod->client_req_fini = NULL; } - context->modules[k].request_context_pp = rcpp; + mod->modreq_p = rcpp; #ifdef DEBUG - fprintf (stderr, "init module \"%s\", pa_type %d, flag %d\n", - context->modules[k].name, - context->modules[k].pa_type, - context->modules[k].flags); + fprintf(stderr, "init module \"%s\", pa_type %d, flag %d\n", + mod->name, mod->pa_type, mod->flags); #endif - k++; + n_modules++; } } } - krb5int_free_plugin_dir_data(tables); + context->n_modules = n_modules; - /* return the result */ + /* Place the constructed preauth context into the krb5 context. */ kcontext->preauth_context = context; + context = NULL; + +cleanup: + if (context) + free(context->modules); + free(context); + k5_plugin_free_modules(kcontext, plugins); + free(vtables); } /* Zero the use counts for the modules herein. Usually used before we @@ -249,23 +249,19 @@ void KRB5_CALLCONV krb5_free_preauth_context(krb5_context context) { int i; - void *pctx; - if (context && context->preauth_context != NULL) { - for (i = 0; i < context->preauth_context->n_modules; i++) { - pctx = context->preauth_context->modules[i].plugin_context; - if (context->preauth_context->modules[i].client_fini != NULL) { - (*context->preauth_context->modules[i].client_fini)(context, pctx); - } - memset(&context->preauth_context->modules[i], 0, - sizeof(context->preauth_context->modules[i])); - } - if (context->preauth_context->modules != NULL) { - free(context->preauth_context->modules); - context->preauth_context->modules = NULL; - } - free(context->preauth_context); - context->preauth_context = NULL; - } + struct krb5_preauth_context_module_st *mod; + + if (context == NULL || context->preauth_context == NULL) + return; + for (i = 0; i < context->preauth_context->n_modules; i++) { + mod = &context->preauth_context->modules[i]; + if (mod->client_fini != NULL) + mod->client_fini(context, mod->moddata); + zap(mod, sizeof(*mod)); + } + free(context->preauth_context->modules); + free(context->preauth_context); + context->preauth_context = NULL; } /* Initialize the per-AS-REQ context. This means calling the client_req_init @@ -274,19 +270,16 @@ void KRB5_CALLCONV krb5_preauth_request_context_init(krb5_context context) { int i; - void *rctx, *pctx; + struct krb5_preauth_context_module_st *mod; - /* Limit this to only one attempt per context? */ if (context->preauth_context == NULL) krb5_init_preauth_context(context); - if (context->preauth_context != NULL) { - for (i = 0; i < context->preauth_context->n_modules; i++) { - pctx = context->preauth_context->modules[i].plugin_context; - if (context->preauth_context->modules[i].client_req_init != NULL) { - rctx = context->preauth_context->modules[i].request_context_pp; - (*context->preauth_context->modules[i].client_req_init) (context, pctx, rctx); - } - } + if (context->preauth_context == NULL) + return; + for (i = 0; i < context->preauth_context->n_modules; i++) { + mod = &context->preauth_context->modules[i]; + if (mod->client_req_init != NULL) + mod->client_req_init(context, mod->moddata, mod->modreq_p); } } @@ -296,17 +289,16 @@ void KRB5_CALLCONV krb5_preauth_request_context_fini(krb5_context context) { int i; - void *rctx, *pctx; - if (context->preauth_context != NULL) { - for (i = 0; i < context->preauth_context->n_modules; i++) { - pctx = context->preauth_context->modules[i].plugin_context; - rctx = context->preauth_context->modules[i].request_context; - if (rctx != NULL) { - if (context->preauth_context->modules[i].client_req_fini != NULL) { - (*context->preauth_context->modules[i].client_req_fini)(context, pctx, rctx); - } - context->preauth_context->modules[i].request_context = NULL; - } + struct krb5_preauth_context_module_st *mod; + + if (context->preauth_context == NULL) + return; + for (i = 0; i < context->preauth_context->n_modules; i++) { + mod = &context->preauth_context->modules[i]; + if (mod->modreq != NULL) { + if (mod->client_req_fini != NULL) + mod->client_req_fini(context, mod->moddata, mod->modreq); + mod->modreq = NULL; } } } @@ -390,10 +382,8 @@ grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size, */ static krb5_error_code -client_data_proc(krb5_context kcontext, - krb5_preauth_client_rock *rock, - krb5_int32 request_type, - krb5_data **retdata) +client_data_proc(krb5_context kcontext, krb5_clpreauth_rock rock, + krb5_int32 request_type, krb5_data **retdata) { krb5_data *ret; krb5_error_code retval; @@ -405,7 +395,7 @@ client_data_proc(krb5_context kcontext, return EINVAL; switch (request_type) { - case krb5plugin_preauth_client_get_etype: + case krb5_clpreauth_get_etype: { krb5_enctype *eptr; ret = malloc(sizeof(krb5_data)); @@ -424,7 +414,7 @@ client_data_proc(krb5_context kcontext, return 0; } break; - case krb5plugin_preauth_client_free_etype: + case krb5_clpreauth_free_etype: ret = *retdata; if (ret == NULL) return 0; @@ -433,7 +423,7 @@ client_data_proc(krb5_context kcontext, free(ret); return 0; break; - case krb5plugin_preauth_client_fast_armor: { + case krb5_clpreauth_fast_armor: { krb5_keyblock *key = NULL; ret = calloc(1, sizeof(krb5_data)); if (ret == NULL) @@ -455,7 +445,7 @@ client_data_proc(krb5_context kcontext, free(ret); return retval; } - case krb5plugin_preauth_client_free_fast_armor: + case krb5_clpreauth_free_fast_armor: ret = *retdata; if (ret) { if (ret->data) @@ -508,11 +498,11 @@ run_preauth_plugins(krb5_context kcontext, krb5_pa_data *in_padata, krb5_prompter_fct prompter, void *prompter_data, - preauth_get_as_key_proc gak_fct, + krb5_clpreauth_get_as_key_fn gak_fct, krb5_data *salt, krb5_data *s2kparams, void *gak_data, - krb5_preauth_client_rock *get_data_rock, + krb5_clpreauth_rock preauth_rock, krb5_keyblock *as_key, krb5_pa_data ***out_pa_list, int *out_pa_list_size, @@ -523,7 +513,7 @@ run_preauth_plugins(krb5_context kcontext, int i; krb5_pa_data **out_pa_data; krb5_error_code ret; - struct _krb5_preauth_context_module *module; + struct krb5_preauth_context_module_st *module; if (kcontext->preauth_context == NULL) { return ENOENT; @@ -551,19 +541,14 @@ run_preauth_plugins(krb5_context kcontext, fprintf(stderr, "using module \"%s\" (%d), flags = %d\n", module->name, module->pa_type, module->flags); #endif - ret = module->client_process(kcontext, - module->plugin_context, - *module->request_context_pp, + ret = module->client_process(kcontext, module->moddata, + *module->modreq_p, (krb5_get_init_creds_opt *)opte, - client_data_proc, - get_data_rock, - request, - encoded_request_body, - encoded_previous_request, - in_padata, - prompter, prompter_data, - gak_fct, gak_data, salt, s2kparams, - as_key, + client_data_proc, preauth_rock, + request, encoded_request_body, + encoded_previous_request, in_padata, + prompter, prompter_data, gak_fct, + gak_data, salt, s2kparams, as_key, &out_pa_data); TRACE_PREAUTH_PROCESS(kcontext, module->name, module->pa_type, module->flags, ret); @@ -1517,13 +1502,13 @@ krb5_do_preauth_tryagain(krb5_context kcontext, krb5_keyblock *as_key, krb5_prompter_fct prompter, void *prompter_data, krb5_gic_get_as_key_fct gak_fct, void *gak_data, - krb5_preauth_client_rock *get_data_rock, + krb5_clpreauth_rock preauth_rock, krb5_gic_opt_ext *opte) { krb5_error_code ret; krb5_pa_data **out_padata; krb5_preauth_context *context; - struct _krb5_preauth_context_module *module; + struct krb5_preauth_context_module_st *module; int i, j; int out_pa_list_size = 0; @@ -1548,12 +1533,11 @@ krb5_do_preauth_tryagain(krb5_context kcontext, if (module->client_tryagain == NULL) { continue; } - if ((*module->client_tryagain)(kcontext, - module->plugin_context, - *module->request_context_pp, + if ((*module->client_tryagain)(kcontext, module->moddata, + *module->modreq_p, (krb5_get_init_creds_opt *)opte, client_data_proc, - get_data_rock, + preauth_rock, request, encoded_request_body, encoded_previous_request, @@ -1589,8 +1573,7 @@ krb5_do_preauth(krb5_context context, krb5_keyblock *as_key, krb5_prompter_fct prompter, void *prompter_data, krb5_gic_get_as_key_fct gak_fct, void *gak_data, - krb5_preauth_client_rock *get_data_rock, - krb5_gic_opt_ext *opte) + krb5_clpreauth_rock preauth_rock, krb5_gic_opt_ext *opte) { unsigned int h; int i, j, out_pa_list_size; @@ -1769,7 +1752,7 @@ krb5_do_preauth(krb5_context context, gak_fct, salt, s2kparams, gak_data, - get_data_rock, + preauth_rock, as_key, &out_pa_list, &out_pa_list_size, @@ -1803,3 +1786,47 @@ cleanup: krb5_free_etype_info(context, etype_info); return (ret); } + +/* + * Give all the preauth plugins a look at the preauth option which + * has just been set + */ +krb5_error_code +krb5_preauth_supply_preauth_data(krb5_context context, krb5_gic_opt_ext *opte, + const char *attr, const char *value) +{ + krb5_error_code retval = 0; + int i; + struct krb5_preauth_context_module_st *mod; + const char *emsg = NULL; + + if (context->preauth_context == NULL) + krb5_init_preauth_context(context); + if (context->preauth_context == NULL) { + retval = EINVAL; + krb5_set_error_message(context, retval, + _("Unable to initialize preauth context")); + return retval; + } + + /* + * Go down the list of preauth modules, and supply them with the + * attribute/value pair. + */ + for (i = 0; i < context->preauth_context->n_modules; i++) { + mod = &context->preauth_context->modules[i]; + if (mod->client_supply_gic_opts == NULL) + continue; + retval = mod->client_supply_gic_opts(context, mod->moddata, + (krb5_get_init_creds_opt *)opte, + attr, value); + if (retval) { + emsg = krb5_get_error_message(context, retval); + krb5_set_error_message(context, retval, _("Preauth plugin %s: %s"), + mod->name, emsg); + krb5_free_error_message(context, emsg); + break; + } + } + return retval; +} diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports index b531b70b5c..edc4b1fc58 100644 --- a/src/lib/krb5/libkrb5.exports +++ b/src/lib/krb5/libkrb5.exports @@ -114,6 +114,7 @@ k5_plugin_free_modules k5_plugin_load k5_plugin_load_all k5_plugin_register +k5_plugin_register_dyn krb524_convert_creds_kdc krb524_init_ets krb5_425_conv_principal diff --git a/src/lib/krb5/os/init_os_ctx.c b/src/lib/krb5/os/init_os_ctx.c index 6cb9b16803..9387cf8720 100644 --- a/src/lib/krb5/os/init_os_ctx.c +++ b/src/lib/krb5/os/init_os_ctx.c @@ -376,7 +376,6 @@ krb5_os_init_context(krb5_context ctx, krb5_boolean kdc) ctx->vtbl = 0; PLUGIN_DIR_INIT(&ctx->libkrb5_plugins); - PLUGIN_DIR_INIT(&ctx->preauth_plugins); ctx->preauth_context = NULL; retval = os_init_paths(ctx, kdc); @@ -477,7 +476,6 @@ krb5_os_free_context(krb5_context ctx) krb5_free_preauth_context(ctx); ctx->preauth_context = NULL; } - krb5int_close_plugin_dirs (&ctx->preauth_plugins); krb5int_close_plugin_dirs (&ctx->libkrb5_plugins); #ifdef _WIN32 diff --git a/src/plugins/preauth/cksum_body/cksum_body.exports b/src/plugins/preauth/cksum_body/cksum_body.exports index 98e96c399b..df335ca64b 100644 --- a/src/plugins/preauth/cksum_body/cksum_body.exports +++ b/src/plugins/preauth/cksum_body/cksum_body.exports @@ -1,2 +1,2 @@ -preauthentication_client_1 -preauthentication_server_1 +clpreauth_cksum_body_initvt +kdcpreauth_cksum_body_initvt diff --git a/src/plugins/preauth/cksum_body/cksum_body_main.c b/src/plugins/preauth/cksum_body/cksum_body_main.c index 2759045b09..e79b84a12a 100644 --- a/src/plugins/preauth/cksum_body/cksum_body_main.c +++ b/src/plugins/preauth/cksum_body/cksum_body_main.c @@ -80,18 +80,18 @@ client_get_flags(krb5_context kcontext, krb5_preauthtype pa_type) static krb5_error_code client_process(krb5_context kcontext, - void *client_plugin_context, - void *client_request_context, + krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc client_get_data_proc, - struct _krb5_preauth_client_rock *rock, + krb5_clpreauth_get_data_fn client_get_data_proc, + krb5_clpreauth_rock rock, 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_clpreauth_get_as_key_fn gak_fct, void *gak_data, krb5_data *salt, krb5_data *s2kparams, krb5_keyblock *as_key, @@ -229,7 +229,7 @@ client_process(krb5_context kcontext, static krb5_error_code client_gic_opt(krb5_context kcontext, - void *plugin_context, + krb5_clpreauth_moddata moddata, krb5_get_init_creds_opt *opt, const char *attr, const char *value) @@ -243,7 +243,8 @@ client_gic_opt(krb5_context kcontext, /* Initialize and tear down the server-side module, and do stat tracking. */ static krb5_error_code -server_init(krb5_context kcontext, void **module_context, const char **realmnames) +server_init(krb5_context kcontext, krb5_kdcpreauth_moddata *moddata_out, + const char **realmnames) { struct server_stats *stats; stats = malloc(sizeof(struct server_stats)); @@ -251,14 +252,14 @@ server_init(krb5_context kcontext, void **module_context, const char **realmname return ENOMEM; stats->successes = 0; stats->failures = 0; - *module_context = stats; + *moddata_out = (krb5_kdcpreauth_moddata)stats; return 0; } static void -server_fini(krb5_context kcontext, void *module_context) +server_fini(krb5_context kcontext, krb5_kdcpreauth_moddata moddata) { struct server_stats *stats; - stats = module_context; + stats = (struct server_stats *)moddata; if (stats != NULL) { #ifdef DEBUG fprintf(stderr, "Total: %d clients failed, %d succeeded.\n", @@ -275,8 +276,8 @@ 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_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) { krb5_data *key_data; @@ -287,7 +288,7 @@ server_get_edata(krb5_context kcontext, /* Retrieve the client's keys. */ key_data = NULL; if ((*server_get_entry_data)(kcontext, request, client, - krb5plugin_preauth_keys, &key_data) != 0) { + krb5_kdcpreauth_keys, &key_data) != 0) { #ifdef DEBUG fprintf(stderr, "Error retrieving client keys.\n"); #endif @@ -335,9 +336,9 @@ server_verify(krb5_context kcontext, 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_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq *modreq_out, krb5_data **e_data, krb5_authdata ***authz_data) { @@ -356,7 +357,7 @@ server_verify(krb5_context kcontext, test_svr_req_ctx *svr_req_ctx; krb5_authdata **my_authz_data = NULL; - stats = pa_module_context; + stats = (struct server_stats *)moddata; #ifdef DEBUG fprintf(stderr, "cksum_body: server_verify\n"); @@ -392,7 +393,7 @@ server_verify(krb5_context kcontext, /* Pull up the client's keys. */ key_data = NULL; if ((*server_get_entry_data)(kcontext, request, client, - krb5plugin_preauth_keys, &key_data) != 0) { + krb5_kdcpreauth_keys, &key_data) != 0) { #ifdef DEBUG fprintf(stderr, "Error retrieving client keys.\n"); #endif @@ -449,7 +450,7 @@ server_verify(krb5_context kcontext, * will probably work if it's us on both ends, though. */ req_body = NULL; if ((*server_get_entry_data)(kcontext, request, client, - krb5plugin_preauth_request_body, + krb5_kdcpreauth_request_body, &req_body) != 0) { krb5_free_keyblock(kcontext, key); stats->failures++; @@ -572,7 +573,7 @@ server_verify(krb5_context kcontext, svr_req_ctx); #endif } - *pa_request_context = svr_req_ctx; + *modreq_out = (krb5_kdcpreauth_modreq)svr_req_ctx; /* Note that preauthentication succeeded. */ enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; @@ -591,9 +592,9 @@ server_return(krb5_context kcontext, 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) + krb5_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq) { /* We don't need to send data back on the return trip. */ *send_pa = NULL; @@ -601,34 +602,32 @@ server_return(krb5_context kcontext, } /* Test server request context freeing */ -static krb5_error_code -server_free_reqctx(krb5_context kcontext, - void *pa_module_context, - void **pa_request_context) +static void +server_free_modreq(krb5_context kcontext, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq) { test_svr_req_ctx *svr_req_ctx; #ifdef DEBUG - fprintf(stderr, "server_free_reqctx: entered!\n"); + fprintf(stderr, "server_free_modreq: entered!\n"); #endif - if (pa_request_context == NULL) - return 0; + if (modreq == NULL) + return; - svr_req_ctx = *pa_request_context; + svr_req_ctx = (test_svr_req_ctx *)modreq; if (svr_req_ctx == NULL) - return 0; + return; if (svr_req_ctx->value1 != 111111 || svr_req_ctx->value2 != 222222) { - fprintf(stderr, "server_free_reqctx: got invalid req context " + fprintf(stderr, "server_free_modreq: got invalid req context " "at %p with values %d and %d\n", svr_req_ctx, svr_req_ctx->value1, svr_req_ctx->value2); - return EINVAL; + return; } #ifdef DEBUG - fprintf(stderr, "server_free_reqctx: freeing context at %p\n", svr_req_ctx); + fprintf(stderr, "server_free_modreq: freeing context at %p\n", svr_req_ctx); #endif free(svr_req_ctx); - *pa_request_context = NULL; - return 0; } static int @@ -644,28 +643,47 @@ static krb5_preauthtype supported_server_pa_types[] = { KRB5_PADATA_CKSUM_BODY_REQ, 0, }; -struct krb5plugin_preauth_client_ftable_v1 preauthentication_client_1 = { - "cksum_body", /* name */ - &supported_client_pa_types[0], /* pa_type_list */ - NULL, /* enctype_list */ - NULL, /* plugin init function */ - NULL, /* plugin fini function */ - client_get_flags, /* get flags function */ - NULL, /* request init function */ - NULL, /* request fini function */ - client_process, /* process function */ - NULL, /* try_again function */ - client_gic_opt /* get init creds opt function */ -}; +krb5_error_code +clpreauth_cksum_body_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable); +krb5_error_code +kdcpreauth_cksum_body_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable); -struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = { - "cksum_body", - &supported_server_pa_types[0], - server_init, - server_fini, - server_get_flags, - server_get_edata, - server_verify, - server_return, - server_free_reqctx -}; +krb5_error_code +clpreauth_cksum_body_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable) +{ + krb5_clpreauth_vtable vt; + + if (maj_ver != 1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_clpreauth_vtable)vtable; + vt->name = "cksum_body"; + vt->pa_type_list = supported_client_pa_types; + vt->flags = client_get_flags; + vt->process = client_process; + vt->gic_opts = client_gic_opt; + return 0; +} + +krb5_error_code +kdcpreauth_cksum_body_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable) +{ + krb5_kdcpreauth_vtable vt; + + if (maj_ver != -1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_kdcpreauth_vtable)vtable; + vt->name = "cksum_body"; + vt->pa_type_list = supported_server_pa_types; + vt->init = server_init; + vt->fini = server_fini; + vt->flags = server_get_flags; + vt->edata = server_get_edata; + vt->verify = server_verify; + vt->return_padata = server_return; + vt->free_modreq = server_free_modreq; + return 0; +} diff --git a/src/plugins/preauth/encrypted_challenge/encrypted_challenge.exports b/src/plugins/preauth/encrypted_challenge/encrypted_challenge.exports index 98e96c399b..651dcea1c4 100644 --- a/src/plugins/preauth/encrypted_challenge/encrypted_challenge.exports +++ b/src/plugins/preauth/encrypted_challenge/encrypted_challenge.exports @@ -1,2 +1,2 @@ -preauthentication_client_1 -preauthentication_server_1 +clpreauth_encrypted_challenge_initvt +kdcpreauth_encrypted_challenge_initvt diff --git a/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c b/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c index 833385c637..58a659246d 100644 --- a/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c +++ b/src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c @@ -41,14 +41,14 @@ preauth_flags(krb5_context context, krb5_preauthtype pa_type) } static krb5_error_code -process_preauth(krb5_context context, void *plugin_context, - void *request_context, krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc get_data_proc, - struct _krb5_preauth_client_rock *rock, krb5_kdc_req *request, +process_preauth(krb5_context context, krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, + krb5_clpreauth_get_data_fn get_data_proc, + krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_pa_data *padata, krb5_prompter_fct prompter, void *prompter_data, - preauth_get_as_key_proc gak_fct, void *gak_data, + krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data, krb5_data *salt, krb5_data *s2kparams, krb5_keyblock *as_key, krb5_pa_data ***out_padata) { @@ -63,7 +63,8 @@ process_preauth(krb5_context context, void *plugin_context, retval = fast_get_armor_key(context, get_data_proc, rock, &armor_key); if (retval || armor_key == NULL) return 0; - retval = get_data_proc(context, rock, krb5plugin_preauth_client_get_etype, &etype_data); + retval = get_data_proc(context, rock, krb5_clpreauth_get_etype, + &etype_data); if (retval == 0) { enctype = *((krb5_enctype *)etype_data->data); if (as_key->length == 0 ||as_key->enctype != enctype) @@ -163,8 +164,7 @@ process_preauth(krb5_context context, void *plugin_context, if (armor_key) krb5_free_keyblock(context, armor_key); if (etype_data != NULL) - get_data_proc(context, rock, krb5plugin_preauth_client_free_etype, - &etype_data); + get_data_proc(context, rock, krb5_clpreauth_free_etype, &etype_data); return retval; } @@ -173,12 +173,13 @@ static krb5_error_code kdc_include_padata(krb5_context context, krb5_kdc_req *request, struct _krb5_db_entry_new *client, struct _krb5_db_entry_new *server, - preauth_get_entry_data_proc get_entry_proc, - void *pa_module_context, krb5_pa_data *data) + krb5_kdcpreauth_get_data_fn get_data_proc, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) { krb5_error_code retval = 0; krb5_keyblock *armor_key = NULL; - retval = fast_kdc_get_armor_key(context, get_entry_proc, request, client, &armor_key); + retval = fast_kdc_get_armor_key(context, get_data_proc, request, client, + &armor_key); if (retval) return retval; if (armor_key == 0) @@ -191,8 +192,9 @@ static krb5_error_code kdc_verify_preauth(krb5_context context, 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 get_entry_proc, - void *pa_module_context, void **pa_request_context, + krb5_kdcpreauth_get_data_fn get_entry_proc, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq *modreq_out, krb5_data **e_data, krb5_authdata ***authz_data) { krb5_error_code retval = 0; @@ -205,6 +207,7 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, krb5_keyblock *client_keys = NULL; krb5_data *client_data = NULL; krb5_keyblock *challenge_key = NULL; + krb5_keyblock *kdc_challenge_key; int i = 0; plain.data = NULL; @@ -228,7 +231,7 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, } if (retval == 0) retval = get_entry_proc(context, request, client, - krb5plugin_preauth_keys, &client_data); + krb5_kdcpreauth_keys, &client_data); if (retval == 0) { client_keys = (krb5_keyblock *) client_data->data; for (i = 0; client_keys[i].enctype&& (retval == 0); i++ ) { @@ -273,9 +276,10 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, * considered this a success, so the return value is ignored. */ fast_kdc_replace_reply_key(context, get_entry_proc, request); - krb5_c_fx_cf2_simple(context, armor_key, "kdcchallengearmor", - &client_keys[i], "challengelongterm", - (krb5_keyblock **) pa_request_context); + if (krb5_c_fx_cf2_simple(context, armor_key, "kdcchallengearmor", + &client_keys[i], "challengelongterm", + &kdc_challenge_key) == 0) + *modreq_out = (krb5_kdcpreauth_modreq)kdc_challenge_key; } else { /*skew*/ retval = KRB5KRB_AP_ERR_SKEW; } @@ -302,11 +306,12 @@ kdc_return_preauth(krb5_context context, krb5_pa_data *padata, krb5_kdc_req *request, krb5_kdc_rep *reply, struct _krb5_key_data *client_keys, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa, - preauth_get_entry_data_proc get_entry_proc, - void *pa_module_context, void **pa_request_context) + krb5_kdcpreauth_get_data_fn get_entry_proc, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq) { krb5_error_code retval = 0; - krb5_keyblock *challenge_key = *pa_request_context; + krb5_keyblock *challenge_key = (krb5_keyblock *)modreq; krb5_pa_enc_ts ts; krb5_data *plain = NULL; krb5_enc_data enc; @@ -318,8 +323,6 @@ kdc_return_preauth(krb5_context context, krb5_pa_data *padata, return 0; if (challenge_key == NULL) return 0; - * pa_request_context = NULL; /*this function will free the - * challenge key*/ enc.ciphertext.data = NULL; /* In case of error pass through */ retval = krb5_us_timeofday(context, &ts.patimestamp, &ts.pausec); @@ -355,37 +358,45 @@ kdc_return_preauth(krb5_context context, krb5_pa_data *padata, return retval; } -static int -kdc_preauth_flags(krb5_context context, krb5_preauthtype patype) +krb5_preauthtype supported_pa_types[] = { + KRB5_PADATA_ENCRYPTED_CHALLENGE, 0}; + +krb5_error_code +kdcpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable); +krb5_error_code +clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable); + +krb5_error_code +kdcpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable) { + krb5_kdcpreauth_vtable vt; + + if (maj_ver != 1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_kdcpreauth_vtable)vtable; + vt->name = "encrypted_challenge"; + vt->pa_type_list = supported_pa_types; + vt->edata = kdc_include_padata; + vt->verify = kdc_verify_preauth; + vt->return_padata = kdc_return_preauth; return 0; } -krb5_preauthtype supported_pa_types[] = { - KRB5_PADATA_ENCRYPTED_CHALLENGE, 0}; - -struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = { - "Encrypted challenge", - &supported_pa_types[0], - NULL, - NULL, - kdc_preauth_flags, - kdc_include_padata, - kdc_verify_preauth, - kdc_return_preauth, - NULL -}; +krb5_error_code +clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable) +{ + krb5_clpreauth_vtable vt; -struct krb5plugin_preauth_client_ftable_v1 preauthentication_client_1 = { - "Encrypted Challenge", /* name */ - &supported_pa_types[0], /* pa_type_list */ - NULL, /* enctype_list */ - NULL, /* plugin init function */ - NULL, /* plugin fini function */ - preauth_flags, /* get flags function */ - NULL, /* request init function */ - NULL, /* request fini function */ - process_preauth, /* process function */ - NULL, /* try_again function */ - NULL /* get init creds opt function */ -}; + if (maj_ver != 1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_clpreauth_vtable)vtable; + vt->name = "encrypted_challenge"; + vt->pa_type_list = supported_pa_types; + vt->flags = preauth_flags; + vt->process = process_preauth; + return 0; +} diff --git a/src/plugins/preauth/fast_factor.h b/src/plugins/preauth/fast_factor.h index 52f4fa2e82..f585bc22c3 100644 --- a/src/plugins/preauth/fast_factor.h +++ b/src/plugins/preauth/fast_factor.h @@ -5,38 +5,36 @@ * Returns failure if the client library does not support FAST. */ static inline krb5_error_code -fast_get_armor_key(krb5_context context, preauth_get_client_data_proc get_data, - struct _krb5_preauth_client_rock *rock, - krb5_keyblock **armor_key) +fast_get_armor_key(krb5_context context, krb5_clpreauth_get_data_fn get_data, + krb5_clpreauth_rock rock, krb5_keyblock **armor_key) { krb5_error_code retval = 0; krb5_data *data; - retval = get_data(context, rock, krb5plugin_preauth_client_fast_armor, &data); + retval = get_data(context, rock, krb5_clpreauth_fast_armor, &data); if (retval == 0) { *armor_key = (krb5_keyblock *) data->data; data->data = NULL; - get_data(context, rock, krb5plugin_preauth_client_free_fast_armor, - &data); + get_data(context, rock, krb5_clpreauth_free_fast_armor, &data); } return retval; } static inline krb5_error_code fast_kdc_get_armor_key(krb5_context context, - preauth_get_entry_data_proc get_entry, + krb5_kdcpreauth_get_data_fn get_entry, krb5_kdc_req *request, struct _krb5_db_entry_new *client, krb5_keyblock **armor_key) { krb5_error_code retval; krb5_data *data; - retval = get_entry(context, request, client, krb5plugin_preauth_fast_armor, + retval = get_entry(context, request, client, krb5_kdcpreauth_fast_armor, &data); if (retval == 0) { *armor_key = (krb5_keyblock *) data->data; data->data = NULL; get_entry(context, request, client, - krb5plugin_preauth_free_fast_armor, &data); + krb5_kdcpreauth_free_fast_armor, &data); } return retval; } @@ -45,7 +43,7 @@ fast_kdc_get_armor_key(krb5_context context, static inline krb5_error_code fast_kdc_replace_reply_key(krb5_context context, - preauth_get_entry_data_proc get_data, + krb5_kdcpreauth_get_data_fn get_data, krb5_kdc_req *request) { return 0; @@ -53,8 +51,8 @@ fast_kdc_replace_reply_key(krb5_context context, static inline krb5_error_code fast_set_kdc_verified(krb5_context context, - preauth_get_client_data_proc get_data, - struct _krb5_preauth_client_rock *rock) + krb5_clpreauth_get_data_fn get_data, + krb5_clpreauth_rock rock) { return 0; } diff --git a/src/plugins/preauth/pkinit/pkinit.exports b/src/plugins/preauth/pkinit/pkinit.exports index 98e96c399b..e77fa3ef0b 100644 --- a/src/plugins/preauth/pkinit/pkinit.exports +++ b/src/plugins/preauth/pkinit/pkinit.exports @@ -1,2 +1,2 @@ -preauthentication_client_1 -preauthentication_server_1 +clpreauth_pkinit_initvt +kdcpreauth_pkinit_initvt diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c index 6888c1b07b..cf95bd57b2 100644 --- a/src/plugins/preauth/pkinit/pkinit_clnt.c +++ b/src/plugins/preauth/pkinit/pkinit_clnt.c @@ -71,7 +71,8 @@ pkinit_as_rep_parse(krb5_context context, pkinit_context plgctx, krb5_kdc_req *request, const krb5_data *as_rep, krb5_keyblock *key_block, krb5_enctype etype, krb5_data *); -static void pkinit_client_plugin_fini(krb5_context context, void *blob); +static void pkinit_client_plugin_fini(krb5_context context, + krb5_clpreauth_moddata moddata); static krb5_error_code pa_pkinit_gen_req(krb5_context context, @@ -975,31 +976,25 @@ pkinit_client_profile(krb5_context context, } static krb5_error_code -pkinit_client_process(krb5_context context, - void *plugin_context, - void *request_context, +pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *gic_opt, - preauth_get_client_data_proc get_data_proc, - struct _krb5_preauth_client_rock *rock, - krb5_kdc_req *request, + krb5_clpreauth_get_data_fn get_data_proc, + krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_pa_data *in_padata, - 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_padata) + krb5_prompter_fct prompter, void *prompter_data, + krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data, + krb5_data *salt, krb5_data *s2kparams, + krb5_keyblock *as_key, krb5_pa_data ***out_padata) { krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; krb5_enctype enctype = -1; krb5_data *cdata = NULL; int processing_request = 0; - pkinit_context plgctx = (pkinit_context)plugin_context; - pkinit_req_context reqctx = (pkinit_req_context)request_context; + pkinit_context plgctx = (pkinit_context)moddata; + pkinit_req_context reqctx = (pkinit_req_context)modreq; krb5_keyblock *armor_key = NULL; pkiDebug("pkinit_client_process %p %p %p %p\n", @@ -1061,16 +1056,15 @@ pkinit_client_process(krb5_context context, /* * Get the enctype of the reply. */ - retval = (*get_data_proc)(context, rock, - krb5plugin_preauth_client_get_etype, &cdata); + retval = (*get_data_proc)(context, rock, krb5_clpreauth_get_etype, + &cdata); if (retval) { pkiDebug("get_data_proc returned %d (%s)\n", retval, error_message(retval)); return retval; } enctype = *((krb5_enctype *)cdata->data); - (*get_data_proc)(context, rock, - krb5plugin_preauth_client_free_etype, &cdata); + (*get_data_proc)(context, rock, krb5_clpreauth_free_etype, &cdata); retval = pa_pkinit_parse_rep(context, plgctx, reqctx, request, in_padata, enctype, as_key, encoded_previous_request); @@ -1082,29 +1076,22 @@ pkinit_client_process(krb5_context context, } static krb5_error_code -pkinit_client_tryagain(krb5_context context, - void *plugin_context, - void *request_context, +pkinit_client_tryagain(krb5_context context, krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *gic_opt, - preauth_get_client_data_proc get_data_proc, - struct _krb5_preauth_client_rock *rock, - krb5_kdc_req *request, + krb5_clpreauth_get_data_fn get_data_proc, + krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, - krb5_pa_data *in_padata, - krb5_error *err_reply, - 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_padata) + krb5_pa_data *in_padata, krb5_error *err_reply, + krb5_prompter_fct prompter, void *prompter_data, + krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data, + krb5_data *salt, krb5_data *s2kparams, + krb5_keyblock *as_key, krb5_pa_data ***out_padata) { krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; - pkinit_context plgctx = (pkinit_context)plugin_context; - pkinit_req_context reqctx = (pkinit_req_context)request_context; + pkinit_context plgctx = (pkinit_context)moddata; + pkinit_req_context reqctx = (pkinit_req_context)modreq; krb5_typed_data **typed_data = NULL; krb5_data scratch; krb5_external_principal_identifier **krb5_trusted_certifiers = NULL; @@ -1202,14 +1189,14 @@ static krb5_preauthtype supported_client_pa_types[] = { static void pkinit_client_req_init(krb5_context context, - void *plugin_context, - void **request_context) + krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq *modreq_out) { krb5_error_code retval = ENOMEM; pkinit_req_context reqctx = NULL; - pkinit_context plgctx = plugin_context; + pkinit_context plgctx = (pkinit_context)moddata; - *request_context = NULL; + *modreq_out = NULL; reqctx = malloc(sizeof(*reqctx)); if (reqctx == NULL) @@ -1244,7 +1231,7 @@ pkinit_client_req_init(krb5_context context, if (retval) goto cleanup; - *request_context = (void *) reqctx; + *modreq_out = (krb5_clpreauth_modreq)reqctx; pkiDebug("%s: returning reqctx at %p\n", __FUNCTION__, reqctx); cleanup: @@ -1264,11 +1251,10 @@ cleanup: } static void -pkinit_client_req_fini(krb5_context context, - void *plugin_context, - void *request_context) +pkinit_client_req_fini(krb5_context context, krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq) { - pkinit_req_context reqctx = request_context; + pkinit_req_context reqctx = (pkinit_req_context)modreq; pkiDebug("%s: received reqctx at %p\n", __FUNCTION__, reqctx); if (reqctx == NULL) @@ -1295,7 +1281,8 @@ pkinit_client_req_fini(krb5_context context, } static int -pkinit_client_plugin_init(krb5_context context, void **blob) +pkinit_client_plugin_init(krb5_context context, + krb5_clpreauth_moddata *moddata_out) { krb5_error_code retval = ENOMEM; pkinit_context ctx = NULL; @@ -1325,21 +1312,21 @@ pkinit_client_plugin_init(krb5_context context, void **blob) if (retval) goto errout; - *blob = ctx; + *moddata_out = (krb5_clpreauth_moddata)ctx; pkiDebug("%s: returning plgctx at %p\n", __FUNCTION__, ctx); errout: if (retval) - pkinit_client_plugin_fini(context, ctx); + pkinit_client_plugin_fini(context, (krb5_clpreauth_moddata)ctx); return retval; } static void -pkinit_client_plugin_fini(krb5_context context, void *blob) +pkinit_client_plugin_fini(krb5_context context, krb5_clpreauth_moddata moddata) { - pkinit_context ctx = blob; + pkinit_context ctx = (pkinit_context)moddata; if (ctx == NULL || ctx->magic != PKINIT_CTX_MAGIC) { pkiDebug("pkinit_lib_fini: got bad plgctx (%p)!\n", ctx); @@ -1425,14 +1412,13 @@ handle_gic_opt(krb5_context context, } static krb5_error_code -pkinit_client_gic_opt(krb5_context context, - void *plugin_context, +pkinit_client_gic_opt(krb5_context context, krb5_clpreauth_moddata moddata, krb5_get_init_creds_opt *gic_opt, const char *attr, const char *value) { krb5_error_code retval; - pkinit_context plgctx = plugin_context; + pkinit_context plgctx = (pkinit_context)moddata; pkiDebug("(pkinit) received '%s' = '%s'\n", attr, value); retval = handle_gic_opt(context, plgctx, attr, value); @@ -1442,20 +1428,28 @@ pkinit_client_gic_opt(krb5_context context, return 0; } -/* Only necessary for static plugin linking support. */ -#include "k5-plugin.h" - -struct krb5plugin_preauth_client_ftable_v1 -PLUGIN_SYMBOL_NAME(krb5_preauth, preauthentication_client_1) = { - "pkinit", /* name */ - supported_client_pa_types, /* pa_type_list */ - NULL, /* enctype_list */ - pkinit_client_plugin_init, /* (*init) */ - pkinit_client_plugin_fini, /* (*fini) */ - pkinit_client_get_flags, /* (*flags) */ - pkinit_client_req_init, /* (*client_req_init) */ - pkinit_client_req_fini, /* (*client_req_fini) */ - pkinit_client_process, /* (*process) */ - pkinit_client_tryagain, /* (*tryagain) */ - pkinit_client_gic_opt /* (*gic_opt) */ -}; +krb5_error_code +clpreauth_pkinit_initvt(krb5_context context, int maj_ver, int min_ver, + krb5_plugin_vtable vtable); + +krb5_error_code +clpreauth_pkinit_initvt(krb5_context context, int maj_ver, int min_ver, + krb5_plugin_vtable vtable) +{ + krb5_clpreauth_vtable vt; + + if (maj_ver != 1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_clpreauth_vtable)vtable; + vt->name = "pkinit"; + vt->pa_type_list = supported_client_pa_types; + vt->init = pkinit_client_plugin_init; + vt->fini = pkinit_client_plugin_fini; + vt->flags = pkinit_client_get_flags; + vt->request_init = pkinit_client_req_init; + vt->request_fini = pkinit_client_req_fini; + vt->process = pkinit_client_process; + vt->tryagain = pkinit_client_tryagain; + vt->gic_opts = pkinit_client_gic_opt; + return 0; +} diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c index 2a33e93311..d87d570315 100644 --- a/src/plugins/preauth/pkinit/pkinit_srv.c +++ b/src/plugins/preauth/pkinit/pkinit_srv.c @@ -50,10 +50,12 @@ pkinit_server_plugin_fini_realm(krb5_context context, pkinit_kdc_context plgctx); static void -pkinit_server_plugin_fini(krb5_context context, void *blob); +pkinit_server_plugin_fini(krb5_context context, + krb5_kdcpreauth_moddata moddata); static pkinit_kdc_context -pkinit_find_realm_context(krb5_context context, void *pa_plugin_context, +pkinit_find_realm_context(krb5_context context, + krb5_kdcpreauth_moddata moddata, krb5_principal princ); static krb5_error_code @@ -97,12 +99,12 @@ cleanup: static krb5_error_code pkinit_server_get_edata(krb5_context context, - 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_plugin_context, - krb5_pa_data * data) + krb5_kdc_req *request, + struct _krb5_db_entry_new *client, + struct _krb5_db_entry_new *server, + krb5_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_pa_data *data) { krb5_error_code retval = 0; pkinit_kdc_context plgctx = NULL; @@ -123,8 +125,7 @@ pkinit_server_get_edata(krb5_context context, * If we don't have a realm context for the given realm, * don't tell the client that we support pkinit! */ - plgctx = pkinit_find_realm_context(context, pa_plugin_context, - request->server); + plgctx = pkinit_find_realm_context(context, moddata, request->server); if (plgctx == NULL) retval = EINVAL; @@ -292,9 +293,9 @@ pkinit_server_verify_padata(krb5_context context, 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_plugin_context, - void **pa_request_context, + krb5_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq *modreq_out, krb5_data **e_data, krb5_authdata ***authz_data) { @@ -328,11 +329,10 @@ pkinit_server_verify_padata(krb5_context context, return EINVAL; } - if (pa_plugin_context == NULL || e_data == NULL) + if (moddata == NULL || e_data == NULL) return EINVAL; - plgctx = pkinit_find_realm_context(context, pa_plugin_context, - request->server); + plgctx = pkinit_find_realm_context(context, moddata, request->server); if (plgctx == NULL) return 0; @@ -562,7 +562,7 @@ pkinit_server_verify_padata(krb5_context context, } /* remember to set the PREAUTH flag in the reply */ enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH; - *pa_request_context = reqctx; + *modreq_out = (krb5_kdcpreauth_modreq)reqctx; reqctx = NULL; cleanup: @@ -668,9 +668,9 @@ pkinit_server_return_padata(krb5_context context, 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_plugin_context, - void **pa_request_context) + krb5_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq) { krb5_error_code retval = 0; krb5_data scratch = {0, 0, NULL}; @@ -708,20 +708,19 @@ pkinit_server_return_padata(krb5_context context, if (padata->length <= 0 || padata->contents == NULL) return 0; - if (pa_request_context == NULL || *pa_request_context == NULL) { + if (modreq == NULL) { pkiDebug("missing request context \n"); return EINVAL; } - plgctx = pkinit_find_realm_context(context, pa_plugin_context, - request->server); + plgctx = pkinit_find_realm_context(context, moddata, request->server); if (plgctx == NULL) { pkiDebug("Unable to locate correct realm context\n"); return ENOENT; } pkiDebug("pkinit_return_padata: entered!\n"); - reqctx = (pkinit_kdc_req_context)*pa_request_context; + reqctx = (pkinit_kdc_req_context)modreq; if (encrypting_key->contents) { free(encrypting_key->contents); @@ -1169,13 +1168,14 @@ errout: } static pkinit_kdc_context -pkinit_find_realm_context(krb5_context context, void *pa_plugin_context, +pkinit_find_realm_context(krb5_context context, + krb5_kdcpreauth_moddata moddata, krb5_principal princ) { int i; - pkinit_kdc_context *realm_contexts = pa_plugin_context; + pkinit_kdc_context *realm_contexts = (pkinit_kdc_context *)moddata; - if (pa_plugin_context == NULL) + if (moddata == NULL) return NULL; for (i = 0; realm_contexts[i] != NULL; i++) { @@ -1254,7 +1254,8 @@ errout: } static int -pkinit_server_plugin_init(krb5_context context, void **blob, +pkinit_server_plugin_init(krb5_context context, + krb5_kdcpreauth_moddata *moddata_out, const char **realmnames) { krb5_error_code retval = ENOMEM; @@ -1289,13 +1290,15 @@ pkinit_server_plugin_init(krb5_context context, void **blob, goto errout; } - *blob = realm_contexts; + *moddata_out = (krb5_kdcpreauth_moddata)realm_contexts; retval = 0; pkiDebug("%s: returning context at %p\n", __FUNCTION__, realm_contexts); errout: - if (retval) - pkinit_server_plugin_fini(context, realm_contexts); + if (retval) { + pkinit_server_plugin_fini(context, + (krb5_kdcpreauth_moddata)realm_contexts); + } return retval; } @@ -1316,9 +1319,10 @@ pkinit_server_plugin_fini_realm(krb5_context context, pkinit_kdc_context plgctx) } static void -pkinit_server_plugin_fini(krb5_context context, void *blob) +pkinit_server_plugin_fini(krb5_context context, + krb5_kdcpreauth_moddata moddata) { - pkinit_kdc_context *realm_contexts = blob; + pkinit_kdc_context *realm_contexts = (pkinit_kdc_context *)moddata; int i; if (realm_contexts == NULL) @@ -1379,18 +1383,26 @@ pkinit_fini_kdc_req_context(krb5_context context, void *ctx) free(reqctx); } -/* Only necessary for static plugin linking support. */ -#include "k5-plugin.h" - -struct krb5plugin_preauth_server_ftable_v1 -PLUGIN_SYMBOL_NAME(krb5_pkinit, preauthentication_server_1) = { - "pkinit", /* name */ - supported_server_pa_types, /* pa_type_list */ - pkinit_server_plugin_init, /* (*init_proc) */ - pkinit_server_plugin_fini, /* (*fini_proc) */ - pkinit_server_get_flags, /* (*flags_proc) */ - pkinit_server_get_edata, /* (*edata_proc) */ - pkinit_server_verify_padata,/* (*verify_proc) */ - pkinit_server_return_padata,/* (*return_proc) */ - NULL, /* (*freepa_reqcontext_proc) */ -}; +krb5_error_code +kdcpreauth_pkinit_initvt(krb5_context context, int maj_ver, int min_ver, + krb5_plugin_vtable vtable); + +krb5_error_code +kdcpreauth_pkinit_initvt(krb5_context context, int maj_ver, int min_ver, + krb5_plugin_vtable vtable) +{ + krb5_kdcpreauth_vtable vt; + + if (maj_ver != 1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_kdcpreauth_vtable)vtable; + vt->name = "pkinit"; + vt->pa_type_list = supported_server_pa_types; + vt->init = pkinit_server_plugin_init; + vt->fini = pkinit_server_plugin_fini; + vt->flags = pkinit_server_get_flags; + vt->edata = pkinit_server_get_edata; + vt->verify = pkinit_server_verify_padata; + vt->return_padata = pkinit_server_return_padata; + return 0; +} diff --git a/src/plugins/preauth/securid_sam2/securid_sam2_main.c b/src/plugins/preauth/securid_sam2/securid_sam2_main.c index 49b497ef0e..6bc65e85ee 100644 --- a/src/plugins/preauth/securid_sam2/securid_sam2_main.c +++ b/src/plugins/preauth/securid_sam2/securid_sam2_main.c @@ -116,8 +116,8 @@ static krb5_error_code kdc_include_padata(krb5_context context, krb5_kdc_req *request, struct _krb5_db_entry_new *client, struct _krb5_db_entry_new *server, - preauth_get_entry_data_proc get_entry_proc, - void *pa_module_context, krb5_pa_data *pa_data) + krb5_kdcpreauth_get_data_fn get_entry_proc, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data) { krb5_error_code retval; krb5_data *client_keys_data = NULL; @@ -138,7 +138,7 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, if (retval) return retval; retval = get_entry_proc(context, request, client, - krb5plugin_preauth_keys, &client_keys_data); + krb5_kdcpreauth_keys, &client_keys_data); if (retval) goto cleanup; client_key = (krb5_keyblock *) client_keys_data->data; @@ -206,8 +206,9 @@ static krb5_error_code kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *pa_data, - preauth_get_entry_data_proc get_entry_proc, - void *pa_module_context, void **opaque, + krb5_kdcpreauth_get_data_fn get_entry_proc, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq *modreq_out, krb5_data **e_data, krb5_authdata ***authz_data) { krb5_error_code retval, saved_retval = 0; @@ -294,14 +295,23 @@ kdc_preauth_flags(krb5_context context, krb5_preauthtype patype) krb5_preauthtype supported_pa_types[] = { KRB5_PADATA_SAM_RESPONSE_2, 0}; -struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = { - "SAM2", - &supported_pa_types[0], - NULL, - NULL, - kdc_preauth_flags, - kdc_include_padata, - kdc_verify_preauth, - NULL, - NULL -}; +krb5_error_code +kdcpreauth_securid_sam2_initvt(krb5_context context, int maj_ver, int min_ver, + krb5_plugin_vtable vtable); + +krb5_error_code +kdcpreauth_securid_sam2_initvt(krb5_context context, int maj_ver, int min_ver, + krb5_plugin_vtable vtable) +{ + krb5_kdcpreauth_vtable vt; + + if (maj_ver != 1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_kdcpreauth_vtable)vtable; + vt->name = "securid_sam2"; + vt->pa_type_list = supported_pa_types; + vt->flags = kdc_preauth_flags; + vt->edata = kdc_include_padata; + vt->verify = kdc_verify_preauth; + return 0; +} diff --git a/src/plugins/preauth/wpse/wpse.exports b/src/plugins/preauth/wpse/wpse.exports index 98e96c399b..4cc48a8831 100644 --- a/src/plugins/preauth/wpse/wpse.exports +++ b/src/plugins/preauth/wpse/wpse.exports @@ -1,2 +1,2 @@ -preauthentication_client_1 -preauthentication_server_1 +clpreauth_wpse_initvt +kdcpreauth_wpse_initvt diff --git a/src/plugins/preauth/wpse/wpse_main.c b/src/plugins/preauth/wpse/wpse_main.c index 14e994d420..866286c1bc 100644 --- a/src/plugins/preauth/wpse/wpse_main.c +++ b/src/plugins/preauth/wpse/wpse_main.c @@ -59,7 +59,7 @@ client_get_flags(krb5_context kcontext, krb5_preauthtype pa_type) } static krb5_error_code -client_init(krb5_context kcontext, void **ctx) +client_init(krb5_context kcontext, krb5_clpreauth_moddata *moddata_out) { int *pctx; @@ -67,16 +67,16 @@ client_init(krb5_context kcontext, void **ctx) if (pctx == NULL) return ENOMEM; *pctx = 0; - *ctx = pctx; + *moddata_out = (krb5_clpreauth_moddata)pctx; return 0; } static void -client_fini(krb5_context kcontext, void *ctx) +client_fini(krb5_context kcontext, krb5_clpreauth_moddata moddata) { int *pctx; - pctx = ctx; + pctx = (int *)moddata; if (pctx) { #ifdef DEBUG fprintf(stderr, "wpse module called total of %d times\n", *pctx); @@ -87,18 +87,18 @@ client_fini(krb5_context kcontext, void *ctx) static krb5_error_code client_process(krb5_context kcontext, - void *plugin_context, - void *request_context, + krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, - preauth_get_client_data_proc client_get_data_proc, - struct _krb5_preauth_client_rock *rock, + krb5_clpreauth_get_data_fn client_get_data_proc, + krb5_clpreauth_rock rock, 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_clpreauth_get_as_key_fn gak_fct, void *gak_data, krb5_data *salt, krb5_data *s2kparams, krb5_keyblock *as_key, @@ -115,7 +115,7 @@ client_process(krb5_context kcontext, pa_data->length, pa_data->pa_type); #endif - pctx = plugin_context; + pctx = (int *)moddata; if (pctx) { (*pctx)++; } @@ -176,11 +176,12 @@ typedef struct _wpse_req_ctx } wpse_req_ctx; static void -client_req_init(krb5_context kcontext, void *plugin_context, void **req_context_p) +client_req_init(krb5_context kcontext, krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq *modreq_out) { wpse_req_ctx *ctx; - *req_context_p = NULL; + *modreq_out = NULL; /* Allocate a request context. Useful for verifying that we do in fact * do per-request cleanup. */ @@ -190,13 +191,14 @@ client_req_init(krb5_context kcontext, void *plugin_context, void **req_context_ ctx->magic = WPSE_MAGIC; ctx->value = 0xc0dec0de; - *req_context_p = ctx; + *modreq_out = (krb5_clpreauth_modreq)ctx; } static void -client_req_cleanup(krb5_context kcontext, void *plugin_context, void *req_context) +client_req_cleanup(krb5_context kcontext, krb5_clpreauth_moddata moddata, + krb5_clpreauth_modreq modreq) { - wpse_req_ctx *ctx = (wpse_req_ctx *)req_context; + wpse_req_ctx *ctx = (wpse_req_ctx *)modreq; if (ctx) { #ifdef DEBUG @@ -217,7 +219,7 @@ client_req_cleanup(krb5_context kcontext, void *plugin_context, void *req_contex static krb5_error_code client_gic_opt(krb5_context kcontext, - void *plugin_context, + krb5_clpreauth_moddata moddata, krb5_get_init_creds_opt *opt, const char *attr, const char *value) @@ -231,15 +233,12 @@ client_gic_opt(krb5_context kcontext, /* Free state. */ -static krb5_error_code -server_free_pa_request_context(krb5_context kcontext, void *plugin_context, - void **request_context) +static void +server_free_modreq(krb5_context kcontext, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq modreq) { - if (*request_context != NULL) { - free(*request_context); - *request_context = NULL; - } - return 0; + free(modreq); } /* Obtain and return any preauthentication data (which is destined for the @@ -249,8 +248,8 @@ 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_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, krb5_pa_data *data) { /* Return zero bytes of data. */ @@ -267,9 +266,9 @@ server_verify(krb5_context kcontext, 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_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, + krb5_kdcpreauth_modreq *modreq_out, krb5_data **e_data, krb5_authdata ***authz_data) { @@ -292,8 +291,7 @@ server_verify(krb5_context kcontext, 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); + *modreq_out = malloc(4); /* * Return some junk authorization data just to exercise the @@ -373,9 +371,8 @@ server_return(krb5_context kcontext, 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) + krb5_kdcpreauth_get_data_fn server_get_entry_data, + krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq) { /* 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 @@ -447,28 +444,49 @@ server_get_flags(krb5_context kcontext, krb5_preauthtype pa_type) 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_v1 preauthentication_client_1 = { - "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 */ - client_gic_opt /* get init creds opts function */ -}; - -struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = { - "wpse", - &supported_server_pa_types[0], - NULL, - NULL, - server_get_flags, - server_get_edata, - server_verify, - server_return, - server_free_pa_request_context, -}; +krb5_error_code +clpreauth_wpse_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable); +krb5_error_code +kdcpreauth_wpse_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable); + +krb5_error_code +clpreauth_wpse_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable) +{ + krb5_clpreauth_vtable vt; + + if (maj_ver != 1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_clpreauth_vtable)vtable; + vt->name = "wpse"; + vt->pa_type_list = supported_client_pa_types; + vt->init = client_init; + vt->fini = client_fini; + vt->flags = client_get_flags; + vt->request_init = client_req_init; + vt->request_fini = client_req_cleanup; + vt->process = client_process; + vt->gic_opts = client_gic_opt; + return 0; +} + +krb5_error_code +kdcpreauth_wpse_initvt(krb5_context context, int maj_ver, + int min_ver, krb5_plugin_vtable vtable) +{ + krb5_kdcpreauth_vtable vt; + + if (maj_ver != -1) + return KRB5_PLUGIN_VER_NOTSUPP; + vt = (krb5_kdcpreauth_vtable)vtable; + vt->name = "wpse"; + vt->pa_type_list = supported_server_pa_types; + vt->flags = server_get_flags; + vt->edata = server_get_edata; + vt->verify = server_verify; + vt->return_padata = server_return; + vt->free_modreq = server_free_modreq; + return 0; +} diff --git a/src/tests/dejagnu/Makefile.in b/src/tests/dejagnu/Makefile.in index 85c7ab9d1e..ffdfbd6175 100644 --- a/src/tests/dejagnu/Makefile.in +++ b/src/tests/dejagnu/Makefile.in @@ -41,6 +41,6 @@ site.exp: runenv.vals Makefile echo "set runvarlist [list `cat runenv.vals | tr '\n' ' '`]" | \ sed -e 's%=\.%='`pwd`'/.%g' > site.exp echo "set KRB5_DB_MODULE_DIR {$(KRB5_DB_MODULE_DIR)}" >> site.exp - echo "set KRB5_PA_MODULE_DIR {$(KRB5_PA_MODULE_DIR)}" >> site.exp + echo "set MODULE_DIR {$(MODULE_DIR)}" >> site.exp echo "set PRIOCNTL_HACK @PRIOCNTL_HACK@" >> site.exp diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp index cbe4600318..3a997e58d3 100644 --- a/src/tests/dejagnu/config/default.exp +++ b/src/tests/dejagnu/config/default.exp @@ -918,7 +918,7 @@ proc setup_krb5_conf { {type client} } { global mode global portbase global KRB5_DB_MODULE_DIR - global KRB5_PA_MODULE_DIR + global MODULE_DIR global srcdir set pkinit_certs [findfile "[pwd]/$srcdir/pkinit-certs" "[pwd]/$srcdir/pkinit-certs" "$srcdir/pkinit-certs"] @@ -950,7 +950,7 @@ proc setup_krb5_conf { {type client} } { if { $mode == "tcp" } { puts $conffile " udp_preference_limit = 1" } - puts $conffile " preauth_module_dir = $tmppwd/../../../util/fakedest$KRB5_PA_MODULE_DIR" + puts $conffile " plugin_base_dir = $tmppwd/../../../util/fakedest$MODULE_DIR" puts $conffile "" puts $conffile "\[realms\]" puts $conffile " $REALMNAME = \{" diff --git a/src/tests/dejagnu/krb-standalone/standalone.exp b/src/tests/dejagnu/krb-standalone/standalone.exp index dbaf95dbd7..03a5d52e08 100644 --- a/src/tests/dejagnu/krb-standalone/standalone.exp +++ b/src/tests/dejagnu/krb-standalone/standalone.exp @@ -139,7 +139,7 @@ proc doit { } { global portbase global mode global tmppwd - global KRB5_PA_MODULE_DIR + global MODULE_DIR setup_kerberos_env kdc @@ -235,7 +235,7 @@ proc doit { } { } # If we have anonymous then test it - if [file exists "$tmppwd/../../../util/fakedest$KRB5_PA_MODULE_DIR/pkinit.so" ] { + if [file exists "$tmppwd/../../../util/fakedest$MODULE_DIR/preauth/pkinit.so" ] { kinit_anonymous "WELLKNOWN/ANONYMOUS" } diff --git a/src/util/k5test.py b/src/util/k5test.py index 4a54ba6db0..89551dde59 100644 --- a/src/util/k5test.py +++ b/src/util/k5test.py @@ -915,7 +915,7 @@ _default_krb5_conf = { 'libdefaults' : { 'default_realm' : '$realm', 'dns_lookup_kdc' : 'false', - 'preauth_module_dir' : '$plugins/preauth' + 'plugin_base_dir' : '$plugins' }, 'realms' : { '$realm' : { |