jpayne@69: /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ jpayne@69: /* jpayne@69: * Copyright (c) 2006 Red Hat, Inc. jpayne@69: * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology jpayne@69: * All Rights Reserved. jpayne@69: * jpayne@69: * Redistribution and use in source and binary forms, with or without jpayne@69: * modification, are permitted provided that the following conditions are met: jpayne@69: * jpayne@69: * * Redistributions of source code must retain the above copyright jpayne@69: * notice, this list of conditions and the following disclaimer. jpayne@69: * * Redistributions in binary form must reproduce the above copyright jpayne@69: * notice, this list of conditions and the following disclaimer in jpayne@69: * the documentation and/or other materials provided with the jpayne@69: * distribution. jpayne@69: * * Neither the name of Red Hat, Inc., nor the names of its jpayne@69: * contributors may be used to endorse or promote products derived jpayne@69: * from this software without specific prior written permission. jpayne@69: * jpayne@69: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS jpayne@69: * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED jpayne@69: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A jpayne@69: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER jpayne@69: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, jpayne@69: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, jpayne@69: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jpayne@69: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF jpayne@69: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING jpayne@69: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS jpayne@69: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * Declarations for clpreauth plugin module implementors. jpayne@69: * jpayne@69: * The clpreauth interface has a single supported major version, which is jpayne@69: * 1. Major version 1 has a current minor version of 2. clpreauth modules jpayne@69: * should define a function named clpreauth__initvt, matching jpayne@69: * the signature: jpayne@69: * jpayne@69: * krb5_error_code jpayne@69: * clpreauth_modname_initvt(krb5_context context, int maj_ver, jpayne@69: * int min_ver, krb5_plugin_vtable vtable); jpayne@69: * The initvt function should: jpayne@69: * jpayne@69: * - Check that the supplied maj_ver number is supported by the module, or jpayne@69: * return KRB5_PLUGIN_VER_NOTSUPP if it is not. jpayne@69: * jpayne@69: * - Cast the vtable pointer as appropriate for the interface and maj_ver: jpayne@69: * maj_ver == 1: Cast to krb5_clpreauth_vtable jpayne@69: * jpayne@69: * - Initialize the methods of the vtable, stopping as appropriate for the jpayne@69: * supplied min_ver. Optional methods may be left uninitialized. jpayne@69: * jpayne@69: * Memory for the vtable is allocated by the caller, not by the module. jpayne@69: */ jpayne@69: jpayne@69: #ifndef KRB5_CLPREAUTH_PLUGIN_H jpayne@69: #define KRB5_CLPREAUTH_PLUGIN_H jpayne@69: jpayne@69: #include jpayne@69: #include jpayne@69: jpayne@69: /* clpreauth mechanism property flags */ jpayne@69: jpayne@69: /* Provides a real answer which we can send back to the KDC. The client jpayne@69: * assumes that one real answer will be enough. */ jpayne@69: #define PA_REAL 0x00000001 jpayne@69: jpayne@69: /* Doesn't provide a real answer, but must be given a chance to run before any jpayne@69: * REAL mechanism callbacks. */ jpayne@69: #define PA_INFO 0x00000002 jpayne@69: jpayne@69: /* Abstract type for a client request information handle. */ jpayne@69: typedef struct krb5_clpreauth_rock_st *krb5_clpreauth_rock; jpayne@69: jpayne@69: /* Abstract types for module data and per-request module data. */ jpayne@69: typedef struct krb5_clpreauth_moddata_st *krb5_clpreauth_moddata; jpayne@69: typedef struct krb5_clpreauth_modreq_st *krb5_clpreauth_modreq; jpayne@69: jpayne@69: /* Before using a callback after version 1, modules must check the vers jpayne@69: * field of the callback structure. */ jpayne@69: typedef struct krb5_clpreauth_callbacks_st { jpayne@69: int vers; jpayne@69: jpayne@69: /* jpayne@69: * If an AS-REP has been received, return the enctype of the AS-REP jpayne@69: * encrypted part. Otherwise return the enctype chosen from etype-info, or jpayne@69: * the first requested enctype if no etype-info was received. jpayne@69: */ jpayne@69: krb5_enctype (*get_etype)(krb5_context context, krb5_clpreauth_rock rock); jpayne@69: jpayne@69: /* Get a pointer to the FAST armor key, or NULL if the client is not using jpayne@69: * FAST. The returned pointer is an alias and should not be freed. */ jpayne@69: krb5_keyblock *(*fast_armor)(krb5_context context, jpayne@69: krb5_clpreauth_rock rock); jpayne@69: jpayne@69: /* jpayne@69: * Get a pointer to the client-supplied reply key, possibly invoking the jpayne@69: * prompter to ask for a password if this has not already been done. The jpayne@69: * returned pointer is an alias and should not be freed. jpayne@69: */ jpayne@69: krb5_error_code (*get_as_key)(krb5_context context, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: krb5_keyblock **keyblock); jpayne@69: jpayne@69: /* Replace the reply key to be used to decrypt the AS response. */ jpayne@69: krb5_error_code (*set_as_key)(krb5_context context, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: const krb5_keyblock *keyblock); jpayne@69: jpayne@69: /* End of version 1 clpreauth callbacks. */ jpayne@69: jpayne@69: /* jpayne@69: * Get the current time for use in a preauth response. If jpayne@69: * allow_unauth_time is true and the library has been configured to allow jpayne@69: * it, the current time will be offset using unauthenticated timestamp jpayne@69: * information received from the KDC in the preauth-required error, if one jpayne@69: * has been received. Otherwise, the timestamp in a preauth-required error jpayne@69: * will only be used if it is protected by a FAST channel. Only set jpayne@69: * allow_unauth_time if using an unauthenticated time offset would not jpayne@69: * create a security issue. jpayne@69: */ jpayne@69: krb5_error_code (*get_preauth_time)(krb5_context context, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: krb5_boolean allow_unauth_time, jpayne@69: krb5_timestamp *time_out, jpayne@69: krb5_int32 *usec_out); jpayne@69: jpayne@69: /* Set a question to be answered by the responder and optionally provide jpayne@69: * a challenge. */ jpayne@69: krb5_error_code (*ask_responder_question)(krb5_context context, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: const char *question, jpayne@69: const char *challenge); jpayne@69: jpayne@69: /* Get an answer from the responder, or NULL if the question was jpayne@69: * unanswered. */ jpayne@69: const char *(*get_responder_answer)(krb5_context context, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: const char *question); jpayne@69: jpayne@69: /* Indicate interest in the AS key through the responder interface. */ jpayne@69: void (*need_as_key)(krb5_context context, krb5_clpreauth_rock rock); jpayne@69: jpayne@69: /* jpayne@69: * Get a configuration/state item from an input ccache, which may allow it jpayne@69: * to retrace the steps it took last time. The returned data string is an jpayne@69: * alias and should not be freed. jpayne@69: */ jpayne@69: const char *(*get_cc_config)(krb5_context context, jpayne@69: krb5_clpreauth_rock rock, const char *key); jpayne@69: jpayne@69: /* jpayne@69: * Set a configuration/state item which will be recorded to an output jpayne@69: * ccache, if the calling application supplied one. Both key and data jpayne@69: * should be valid UTF-8 text. jpayne@69: */ jpayne@69: krb5_error_code (*set_cc_config)(krb5_context context, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: const char *key, const char *data); jpayne@69: jpayne@69: /* End of version 2 clpreauth callbacks (added in 1.11). */ jpayne@69: jpayne@69: /* jpayne@69: * Prevent further fallbacks to other preauth mechanisms if the KDC replies jpayne@69: * with an error. (The module itself can still respond to errors with its jpayne@69: * tryagain method, or continue after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED jpayne@69: * errors with its process method.) A module should invoke this callback jpayne@69: * from the process method when it generates an authenticated request using jpayne@69: * credentials; often this will be the first or only client message jpayne@69: * generated by the mechanism. jpayne@69: */ jpayne@69: void (*disable_fallback)(krb5_context context, krb5_clpreauth_rock rock); jpayne@69: jpayne@69: /* End of version 3 clpreauth callbacks (added in 1.17). */ jpayne@69: } *krb5_clpreauth_callbacks; jpayne@69: jpayne@69: /* jpayne@69: * Optional: per-plugin initialization/cleanup. The init function is called by jpayne@69: * libkrb5 when the plugin is loaded, and the fini function is called before jpayne@69: * the plugin is unloaded. These may be called multiple times in case the jpayne@69: * plugin is used in multiple contexts. The returned context lives the jpayne@69: * lifetime of the krb5_context. jpayne@69: */ jpayne@69: typedef krb5_error_code jpayne@69: (*krb5_clpreauth_init_fn)(krb5_context context, jpayne@69: krb5_clpreauth_moddata *moddata_out); jpayne@69: typedef void jpayne@69: (*krb5_clpreauth_fini_fn)(krb5_context context, jpayne@69: krb5_clpreauth_moddata moddata); jpayne@69: jpayne@69: /* jpayne@69: * Optional (mandatory before MIT krb5 1.12): pa_type will be a member of the jpayne@69: * vtable's pa_type_list. Return PA_REAL if pa_type is a real jpayne@69: * preauthentication type or PA_INFO if it is an informational type. If this jpayne@69: * function is not defined in 1.12 or later, all pa_type values advertised by jpayne@69: * the module will be assumed to be real. jpayne@69: */ jpayne@69: typedef int jpayne@69: (*krb5_clpreauth_get_flags_fn)(krb5_context context, krb5_preauthtype pa_type); jpayne@69: jpayne@69: /* jpayne@69: * Optional: per-request initialization/cleanup. The request_init function is jpayne@69: * called when beginning to process a get_init_creds request and the jpayne@69: * request_fini function is called when processing of the request is complete. jpayne@69: * This is optional. It may be called multiple times in the lifetime of a jpayne@69: * krb5_context. jpayne@69: */ jpayne@69: typedef void jpayne@69: (*krb5_clpreauth_request_init_fn)(krb5_context context, jpayne@69: krb5_clpreauth_moddata moddata, jpayne@69: krb5_clpreauth_modreq *modreq_out); jpayne@69: typedef void jpayne@69: (*krb5_clpreauth_request_fini_fn)(krb5_context context, jpayne@69: krb5_clpreauth_moddata moddata, jpayne@69: krb5_clpreauth_modreq modreq); jpayne@69: jpayne@69: /* jpayne@69: * Optional: process server-supplied data in pa_data and set responder jpayne@69: * questions. jpayne@69: * jpayne@69: * encoded_previous_request may be NULL if there has been no previous request jpayne@69: * in the AS exchange. jpayne@69: */ jpayne@69: typedef krb5_error_code jpayne@69: (*krb5_clpreauth_prep_questions_fn)(krb5_context context, jpayne@69: krb5_clpreauth_moddata moddata, jpayne@69: krb5_clpreauth_modreq modreq, jpayne@69: krb5_get_init_creds_opt *opt, jpayne@69: krb5_clpreauth_callbacks cb, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: krb5_kdc_req *request, jpayne@69: krb5_data *encoded_request_body, jpayne@69: krb5_data *encoded_previous_request, jpayne@69: krb5_pa_data *pa_data); jpayne@69: jpayne@69: /* jpayne@69: * Mandatory: process server-supplied data in pa_data and return created data jpayne@69: * in pa_data_out. Also called after the AS-REP is received if the AS-REP jpayne@69: * includes preauthentication data of the associated type. jpayne@69: * jpayne@69: * as_key contains the client-supplied key if known, or an empty keyblock if jpayne@69: * not. If it is empty, the module may use gak_fct to fill it in. jpayne@69: * jpayne@69: * encoded_previous_request may be NULL if there has been no previous request jpayne@69: * in the AS exchange. jpayne@69: */ jpayne@69: typedef krb5_error_code jpayne@69: (*krb5_clpreauth_process_fn)(krb5_context context, jpayne@69: krb5_clpreauth_moddata moddata, jpayne@69: krb5_clpreauth_modreq modreq, jpayne@69: krb5_get_init_creds_opt *opt, jpayne@69: krb5_clpreauth_callbacks cb, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: krb5_kdc_req *request, jpayne@69: krb5_data *encoded_request_body, jpayne@69: krb5_data *encoded_previous_request, jpayne@69: krb5_pa_data *pa_data, jpayne@69: krb5_prompter_fct prompter, void *prompter_data, jpayne@69: krb5_pa_data ***pa_data_out); jpayne@69: jpayne@69: /* jpayne@69: * Optional: Attempt to use error and error_padata to try to recover from the jpayne@69: * given error. To work with both FAST and non-FAST errors, an implementation jpayne@69: * should generally consult error_padata rather than decoding error->e_data. jpayne@69: * For non-FAST errors, it contains the e_data decoded as either pa-data or jpayne@69: * typed-data. jpayne@69: * jpayne@69: * If this function is provided, and it returns 0 and stores data in jpayne@69: * pa_data_out, then the client library will retransmit the request. jpayne@69: */ jpayne@69: typedef krb5_error_code jpayne@69: (*krb5_clpreauth_tryagain_fn)(krb5_context context, jpayne@69: krb5_clpreauth_moddata moddata, jpayne@69: krb5_clpreauth_modreq modreq, jpayne@69: krb5_get_init_creds_opt *opt, jpayne@69: krb5_clpreauth_callbacks cb, jpayne@69: krb5_clpreauth_rock rock, jpayne@69: krb5_kdc_req *request, jpayne@69: krb5_data *encoded_request_body, jpayne@69: krb5_data *encoded_previous_request, jpayne@69: krb5_preauthtype pa_type, jpayne@69: krb5_error *error, jpayne@69: krb5_pa_data **error_padata, jpayne@69: krb5_prompter_fct prompter, void *prompter_data, jpayne@69: krb5_pa_data ***pa_data_out); jpayne@69: jpayne@69: /* jpayne@69: * Optional: receive krb5_get_init_creds_opt information. The attr and value jpayne@69: * information supplied should be copied into moddata by the module if it jpayne@69: * wishes to reference it after returning from this call. jpayne@69: */ jpayne@69: typedef krb5_error_code jpayne@69: (*krb5_clpreauth_supply_gic_opts_fn)(krb5_context context, jpayne@69: krb5_clpreauth_moddata moddata, jpayne@69: krb5_get_init_creds_opt *opt, jpayne@69: const char *attr, const char *value); jpayne@69: jpayne@69: typedef struct krb5_clpreauth_vtable_st { jpayne@69: /* Mandatory: name of module. */ jpayne@69: const char *name; jpayne@69: jpayne@69: /* Mandatory: pointer to zero-terminated list of pa_types which this module jpayne@69: * can provide services for. */ jpayne@69: krb5_preauthtype *pa_type_list; jpayne@69: jpayne@69: /* Optional: pointer to zero-terminated list of enc_types which this module jpayne@69: * claims to add support for. */ jpayne@69: krb5_enctype *enctype_list; jpayne@69: jpayne@69: krb5_clpreauth_init_fn init; jpayne@69: krb5_clpreauth_fini_fn fini; jpayne@69: krb5_clpreauth_get_flags_fn flags; jpayne@69: krb5_clpreauth_request_init_fn request_init; jpayne@69: krb5_clpreauth_request_fini_fn request_fini; jpayne@69: krb5_clpreauth_process_fn process; jpayne@69: krb5_clpreauth_tryagain_fn tryagain; jpayne@69: krb5_clpreauth_supply_gic_opts_fn gic_opts; jpayne@69: /* Minor version 1 ends here. */ jpayne@69: jpayne@69: krb5_clpreauth_prep_questions_fn prep_questions; jpayne@69: /* Minor version 2 ends here. */ jpayne@69: } *krb5_clpreauth_vtable; jpayne@69: jpayne@69: /* jpayne@69: * This function allows a clpreauth plugin to obtain preauth options. The jpayne@69: * preauth_data returned from this function should be freed by calling jpayne@69: * krb5_get_init_creds_opt_free_pa(). jpayne@69: */ jpayne@69: krb5_error_code KRB5_CALLCONV jpayne@69: krb5_get_init_creds_opt_get_pa(krb5_context context, jpayne@69: krb5_get_init_creds_opt *opt, jpayne@69: int *num_preauth_data, jpayne@69: krb5_gic_opt_pa_data **preauth_data); jpayne@69: jpayne@69: /* jpayne@69: * This function frees the preauth_data that was returned by jpayne@69: * krb5_get_init_creds_opt_get_pa(). jpayne@69: */ jpayne@69: void KRB5_CALLCONV jpayne@69: krb5_get_init_creds_opt_free_pa(krb5_context context, jpayne@69: int num_preauth_data, jpayne@69: krb5_gic_opt_pa_data *preauth_data); jpayne@69: jpayne@69: #endif /* KRB5_CLPREAUTH_PLUGIN_H */