Spaces:
Sleeping
Sleeping
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ | |
/* | |
* Copyright (c) 2006 Red Hat, Inc. | |
* Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology | |
* All Rights Reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are met: | |
* | |
* * Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* * Redistributions in binary form must reproduce the above copyright | |
* notice, this list of conditions and the following disclaimer in | |
* the documentation and/or other materials provided with the | |
* distribution. | |
* * Neither the name of Red Hat, Inc., nor the names of its | |
* contributors may be used to endorse or promote products derived | |
* from this software without specific prior written permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | |
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
*/ | |
/* | |
* Declarations for kdcpreauth plugin module implementors. | |
* | |
* The kdcpreauth interface has a single supported major version, which is 1. | |
* Major version 1 has a current minor version of 2. 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); | |
* | |
* 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: | |
* 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. | |
*/ | |
/* kdcpreauth mechanism property flags */ | |
/* | |
* 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. | |
*/ | |
/* | |
* 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. | |
*/ | |
/* | |
* 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. | |
*/ | |
/* | |
* 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_fn called before modules which do not, and are | |
* passed over if a previously-called module has modified the encrypting key. | |
*/ | |
/* | |
* Not really a padata type, so don't include it in any list of preauth types | |
* which gets sent over the wire. | |
*/ | |
/* | |
* Indicates that e_data in non-FAST errors should be encoded as typed data | |
* instead of padata. | |
*/ | |
/* Abstract type for a KDC callback data handle. */ | |
typedef struct krb5_kdcpreauth_rock_st *krb5_kdcpreauth_rock; | |
/* 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; | |
/* The verto context structure type (typedef is in verto.h; we want to avoid a | |
* header dependency for the moment). */ | |
struct verto_ctx; | |
/* Before using a callback after version 1, modules must check the vers | |
* field of the callback structure. */ | |
typedef struct krb5_kdcpreauth_callbacks_st { | |
int vers; | |
krb5_deltat (*max_time_skew)(krb5_context context, | |
krb5_kdcpreauth_rock rock); | |
/* | |
* Get an array of krb5_keyblock structures containing the client keys | |
* matching the request enctypes, terminated by an entry with key type = 0. | |
* Returns ENOENT if no keys are available for the request enctypes. Free | |
* the resulting object with the free_keys callback. | |
*/ | |
krb5_error_code (*client_keys)(krb5_context context, | |
krb5_kdcpreauth_rock rock, | |
krb5_keyblock **keys_out); | |
/* Free the result of client_keys. */ | |
void (*free_keys)(krb5_context context, krb5_kdcpreauth_rock rock, | |
krb5_keyblock *keys); | |
/* | |
* Get the encoded request body, which is sometimes needed for checksums. | |
* For a FAST request this is the encoded inner request body. The returned | |
* pointer is an alias and should not be freed. | |
*/ | |
krb5_data *(*request_body)(krb5_context context, | |
krb5_kdcpreauth_rock rock); | |
/* Get a pointer to the FAST armor key, or NULL if the request did not use | |
* FAST. The returned pointer is an alias and should not be freed. */ | |
krb5_keyblock *(*fast_armor)(krb5_context context, | |
krb5_kdcpreauth_rock rock); | |
/* Retrieve a string attribute from the client DB entry, or NULL if no such | |
* attribute is set. Free the result with the free_string callback. */ | |
krb5_error_code (*get_string)(krb5_context context, | |
krb5_kdcpreauth_rock rock, const char *key, | |
char **value_out); | |
/* Free the result of get_string. */ | |
void (*free_string)(krb5_context context, krb5_kdcpreauth_rock rock, | |
char *string); | |
/* Get a pointer to the client DB entry (returned as a void pointer to | |
* avoid a dependency on a libkdb5 type). */ | |
void *(*client_entry)(krb5_context context, krb5_kdcpreauth_rock rock); | |
/* Get a pointer to the verto context which should be used by an | |
* asynchronous edata or verify method. */ | |
struct verto_ctx *(*event_context)(krb5_context context, | |
krb5_kdcpreauth_rock rock); | |
/* End of version 1 kdcpreauth callbacks. */ | |
/* Return true if the client DB entry contains any keys matching the | |
* request enctypes. */ | |
krb5_boolean (*have_client_keys)(krb5_context context, | |
krb5_kdcpreauth_rock rock); | |
/* End of version 2 kdcpreauth callbacks. */ | |
/* | |
* Get the current reply key. Initially the reply key is the decrypted | |
* client long-term key chosen according to the request enctype list, or | |
* NULL if no matching key was found. The value may be changed by the | |
* replace_reply_key callback or a return_padata method modifying | |
* encrypting_key. The returned pointer is an alias and should not be | |
* freed. | |
*/ | |
const krb5_keyblock *(*client_keyblock)(krb5_context context, | |
krb5_kdcpreauth_rock rock); | |
/* Assert an authentication indicator in the AS-REP authdata. Duplicate | |
* indicators will be ignored. */ | |
krb5_error_code (*add_auth_indicator)(krb5_context context, | |
krb5_kdcpreauth_rock rock, | |
const char *indicator); | |
/* | |
* Read a data value for pa_type from the request cookie, placing it in | |
* *out. The value placed there is an alias and must not be freed. | |
* Returns true if a value for pa_type was retrieved, false if not. | |
*/ | |
krb5_boolean (*get_cookie)(krb5_context context, krb5_kdcpreauth_rock rock, | |
krb5_preauthtype pa_type, krb5_data *out); | |
/* | |
* Set a data value for pa_type to be sent in a secure cookie in the next | |
* error response. If pa_type is already present, the value is ignored. | |
* If the preauth mechanism has different preauth types for requests and | |
* responses, use the request type. Secure cookies are encrypted in a key | |
* known only to the KDCs, but can be replayed within a short time window | |
* for requests using the same client principal. | |
*/ | |
krb5_error_code (*set_cookie)(krb5_context context, | |
krb5_kdcpreauth_rock rock, | |
krb5_preauthtype pa_type, | |
const krb5_data *data); | |
/* End of version 3 kdcpreauth callbacks. */ | |
/* | |
* Return true if princ matches the principal named in the request or the | |
* client principal (possibly canonicalized). If princ does not match, | |
* attempt a database lookup of princ with aliases allowed and compare the | |
* result to the client principal, returning true if it matches. | |
* Otherwise, return false. | |
*/ | |
krb5_boolean (*match_client)(krb5_context context, | |
krb5_kdcpreauth_rock rock, | |
krb5_principal princ); | |
/* | |
* Get an alias to the client DB entry principal (possibly canonicalized). | |
*/ | |
krb5_principal (*client_name)(krb5_context context, | |
krb5_kdcpreauth_rock rock); | |
/* End of version 4 kdcpreauth callbacks. */ | |
/* | |
* Instruct the KDC to send a freshness token in the method data | |
* accompanying a PREAUTH_REQUIRED or PREAUTH_FAILED error, if the client | |
* indicated support for freshness tokens. This callback should only be | |
* invoked from the edata method. | |
*/ | |
void (*send_freshness_token)(krb5_context context, | |
krb5_kdcpreauth_rock rock); | |
/* Validate a freshness token sent by the client. Return 0 on success, | |
* KRB5KDC_ERR_PREAUTH_EXPIRED on error. */ | |
krb5_error_code (*check_freshness_token)(krb5_context context, | |
krb5_kdcpreauth_rock rock, | |
const krb5_data *token); | |
/* End of version 5 kdcpreauth callbacks. */ | |
/* | |
* Replace the reply key with key. If is_strengthen is true, key must be a | |
* derivative of the client long-term key. This callback may be invoked | |
* from the verify or return_padata methods. If it is invoked from the | |
* verify method, the new key will appear as the encrypting_key input to | |
* return_padata. | |
*/ | |
krb5_error_code (*replace_reply_key)(krb5_context context, | |
krb5_kdcpreauth_rock rock, | |
const krb5_keyblock *key, | |
krb5_boolean is_strengthen); | |
/* End of version 6 kdcpreauth callbacks. */ | |
} *krb5_kdcpreauth_callbacks; | |
/* Optional: preauth plugin initialization function. */ | |
typedef krb5_error_code | |
(*krb5_kdcpreauth_init_fn)(krb5_context context, | |
krb5_kdcpreauth_moddata *moddata_out, | |
const char **realmnames); | |
/* Optional: preauth plugin cleanup function. */ | |
typedef void | |
(*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 | |
(*krb5_kdcpreauth_flags_fn)(krb5_context context, krb5_preauthtype pa_type); | |
/* | |
* Responder for krb5_kdcpreauth_edata_fn. If invoked with a non-zero code, pa | |
* will be ignored and the padata type will not be included in the hint list. | |
* If invoked with a zero code and a null pa value, the padata type will be | |
* included in the list with an empty value. If invoked with a zero code and a | |
* non-null pa value, pa will be included in the hint list and will later be | |
* freed by the KDC. | |
*/ | |
typedef void | |
(*krb5_kdcpreauth_edata_respond_fn)(void *arg, krb5_error_code code, | |
krb5_pa_data *pa); | |
/* | |
* Optional: provide pa_data to send to the client as part of the "you need to | |
* use preauthentication" error. The implementation must invoke the respond | |
* when complete, whether successful or not, either before returning or | |
* asynchronously using the verto context returned by cb->event_context(). | |
* | |
* This function is not allowed to create a modreq object because we have no | |
* guarantee that the client will ever make a follow-up request, or that it | |
* will hit this KDC if it does. | |
*/ | |
typedef void | |
(*krb5_kdcpreauth_edata_fn)(krb5_context context, krb5_kdc_req *request, | |
krb5_kdcpreauth_callbacks cb, | |
krb5_kdcpreauth_rock rock, | |
krb5_kdcpreauth_moddata moddata, | |
krb5_preauthtype pa_type, | |
krb5_kdcpreauth_edata_respond_fn respond, | |
void *arg); | |
/* | |
* Responder for krb5_kdcpreauth_verify_fn. Invoke with the arg parameter | |
* supplied to verify, the error code (0 for success), an optional module | |
* request state object to be consumed by return_fn or free_modreq_fn, optional | |
* e_data to be passed to the caller if code is nonzero, and optional | |
* authorization data to be included in the ticket. In non-FAST replies, | |
* e_data will be encoded as typed-data if the module sets the PA_TYPED_E_DATA | |
* flag, and as pa-data otherwise. e_data and authz_data will be freed by the | |
* KDC. | |
*/ | |
typedef void | |
(*krb5_kdcpreauth_verify_respond_fn)(void *arg, krb5_error_code code, | |
krb5_kdcpreauth_modreq modreq, | |
krb5_pa_data **e_data, | |
krb5_authdata **authz_data); | |
/* | |
* 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. The implementation must invoke the respond function | |
* when complete, whether successful or not, either before returning or | |
* asynchronously using the verto context returned by cb->event_context(). | |
*/ | |
typedef void | |
(*krb5_kdcpreauth_verify_fn)(krb5_context context, | |
krb5_data *req_pkt, krb5_kdc_req *request, | |
krb5_enc_tkt_part *enc_tkt_reply, | |
krb5_pa_data *data, | |
krb5_kdcpreauth_callbacks cb, | |
krb5_kdcpreauth_rock rock, | |
krb5_kdcpreauth_moddata moddata, | |
krb5_kdcpreauth_verify_respond_fn respond, | |
void *arg); | |
/* | |
* 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 by modifying encrypting_key, but it is | |
* preferrable to use the replace_reply_key callback. | |
*/ | |
typedef krb5_error_code | |
(*krb5_kdcpreauth_return_fn)(krb5_context context, | |
krb5_pa_data *padata, | |
krb5_data *req_pkt, | |
krb5_kdc_req *request, | |
krb5_kdc_rep *reply, | |
krb5_keyblock *encrypting_key, | |
krb5_pa_data **send_pa_out, | |
krb5_kdcpreauth_callbacks cb, | |
krb5_kdcpreauth_rock rock, | |
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); | |
/* Optional: invoked after init_fn to provide the module with a pointer to the | |
* verto main loop. */ | |
typedef krb5_error_code | |
(*krb5_kdcpreauth_loop_fn)(krb5_context context, | |
krb5_kdcpreauth_moddata moddata, | |
struct verto_ctx *ctx); | |
typedef struct krb5_kdcpreauth_vtable_st { | |
/* Mandatory: name of module. */ | |
const char *name; | |
/* Mandatory: pointer to zero-terminated list of pa_types which this module | |
* can provide services for. */ | |
krb5_preauthtype *pa_type_list; | |
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; | |
/* Minor 1 ends here. */ | |
krb5_kdcpreauth_loop_fn loop; | |
/* Minor 2 ends here. */ | |
} *krb5_kdcpreauth_vtable; | |