Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:04:39

0001 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
0002 /*
0003  * Copyright (c) 2006 Red Hat, Inc.
0004  * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology
0005  * All Rights Reserved.
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions are met:
0009  *
0010  *  * Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  *  * Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in
0014  *    the documentation and/or other materials provided with the
0015  *    distribution.
0016  *  * Neither the name of Red Hat, Inc., nor the names of its
0017  *    contributors may be used to endorse or promote products derived
0018  *    from this software without specific prior written permission.
0019  *
0020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
0021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
0022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
0023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
0024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0031  */
0032 
0033 /*
0034  * Declarations for kdcpreauth plugin module implementors.
0035  *
0036  * The kdcpreauth interface has a single supported major version, which is 1.
0037  * Major version 1 has a current minor version of 2.  kdcpreauth modules should
0038  * define a function named kdcpreauth_<modulename>_initvt, matching the
0039  * signature:
0040  *
0041  *   krb5_error_code
0042  *   kdcpreauth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
0043  *                             krb5_plugin_vtable vtable);
0044  *
0045  * The initvt function should:
0046  *
0047  * - Check that the supplied maj_ver number is supported by the module, or
0048  *   return KRB5_PLUGIN_VER_NOTSUPP if it is not.
0049  *
0050  * - Cast the vtable pointer as appropriate for the interface and maj_ver:
0051  *     kdcpreauth, maj_ver == 1: Cast to krb5_kdcpreauth_vtable
0052  *
0053  * - Initialize the methods of the vtable, stopping as appropriate for the
0054  *   supplied min_ver.  Optional methods may be left uninitialized.
0055  *
0056  * Memory for the vtable is allocated by the caller, not by the module.
0057  */
0058 
0059 #ifndef KRB5_KDCPREAUTH_PLUGIN_H
0060 #define KRB5_KDCPREAUTH_PLUGIN_H
0061 
0062 #include <krb5/krb5.h>
0063 #include <krb5/plugin.h>
0064 
0065 /* kdcpreauth mechanism property flags */
0066 
0067 /*
0068  * Causes the KDC to include this mechanism in a list of supported preauth
0069  * types if the user's DB entry flags the user as requiring hardware-based
0070  * preauthentication.
0071  */
0072 #define PA_HARDWARE     0x00000004
0073 
0074 /*
0075  * Causes the KDC to include this mechanism in a list of supported preauth
0076  * types if the user's DB entry flags the user as requiring preauthentication,
0077  * and to fail preauthentication if we can't verify the client data.  The
0078  * flipside of PA_SUFFICIENT.
0079  */
0080 #define PA_REQUIRED     0x00000008
0081 
0082 /*
0083  * Causes the KDC to include this mechanism in a list of supported preauth
0084  * types if the user's DB entry flags the user as requiring preauthentication,
0085  * and to mark preauthentication as successful if we can verify the client
0086  * data.  The flipside of PA_REQUIRED.
0087  */
0088 #define PA_SUFFICIENT   0x00000010
0089 
0090 /*
0091  * Marks this preauthentication mechanism as one which changes the key which is
0092  * used for encrypting the response to the client.  Modules which have this
0093  * flag have their server_return_fn called before modules which do not, and are
0094  * passed over if a previously-called module has modified the encrypting key.
0095  */
0096 #define PA_REPLACES_KEY 0x00000020
0097 
0098 /*
0099  * Not really a padata type, so don't include it in any list of preauth types
0100  * which gets sent over the wire.
0101  */
0102 #define PA_PSEUDO       0x00000080
0103 
0104 /*
0105  * Indicates that e_data in non-FAST errors should be encoded as typed data
0106  * instead of padata.
0107  */
0108 #define PA_TYPED_E_DATA 0x00000100
0109 
0110 /* Abstract type for a KDC callback data handle. */
0111 typedef struct krb5_kdcpreauth_rock_st *krb5_kdcpreauth_rock;
0112 
0113 /* Abstract type for module data and per-request module data. */
0114 typedef struct krb5_kdcpreauth_moddata_st *krb5_kdcpreauth_moddata;
0115 typedef struct krb5_kdcpreauth_modreq_st *krb5_kdcpreauth_modreq;
0116 
0117 /* The verto context structure type (typedef is in verto.h; we want to avoid a
0118  * header dependency for the moment). */
0119 struct verto_ctx;
0120 
0121 /* Before using a callback after version 1, modules must check the vers
0122  * field of the callback structure. */
0123 typedef struct krb5_kdcpreauth_callbacks_st {
0124     int vers;
0125 
0126     krb5_deltat (*max_time_skew)(krb5_context context,
0127                                  krb5_kdcpreauth_rock rock);
0128 
0129     /*
0130      * Get an array of krb5_keyblock structures containing the client keys
0131      * matching the request enctypes, terminated by an entry with key type = 0.
0132      * Returns ENOENT if no keys are available for the request enctypes.  Free
0133      * the resulting object with the free_keys callback.
0134      */
0135     krb5_error_code (*client_keys)(krb5_context context,
0136                                    krb5_kdcpreauth_rock rock,
0137                                    krb5_keyblock **keys_out);
0138 
0139     /* Free the result of client_keys. */
0140     void (*free_keys)(krb5_context context, krb5_kdcpreauth_rock rock,
0141                       krb5_keyblock *keys);
0142 
0143     /*
0144      * Get the encoded request body, which is sometimes needed for checksums.
0145      * For a FAST request this is the encoded inner request body.  The returned
0146      * pointer is an alias and should not be freed.
0147      */
0148     krb5_data *(*request_body)(krb5_context context,
0149                                krb5_kdcpreauth_rock rock);
0150 
0151     /* Get a pointer to the FAST armor key, or NULL if the request did not use
0152      * FAST.  The returned pointer is an alias and should not be freed. */
0153     krb5_keyblock *(*fast_armor)(krb5_context context,
0154                                  krb5_kdcpreauth_rock rock);
0155 
0156     /* Retrieve a string attribute from the client DB entry, or NULL if no such
0157      * attribute is set.  Free the result with the free_string callback. */
0158     krb5_error_code (*get_string)(krb5_context context,
0159                                   krb5_kdcpreauth_rock rock, const char *key,
0160                                   char **value_out);
0161 
0162     /* Free the result of get_string. */
0163     void (*free_string)(krb5_context context, krb5_kdcpreauth_rock rock,
0164                         char *string);
0165 
0166     /* Get a pointer to the client DB entry (returned as a void pointer to
0167      * avoid a dependency on a libkdb5 type). */
0168     void *(*client_entry)(krb5_context context, krb5_kdcpreauth_rock rock);
0169 
0170     /* Get a pointer to the verto context which should be used by an
0171      * asynchronous edata or verify method. */
0172     struct verto_ctx *(*event_context)(krb5_context context,
0173                                        krb5_kdcpreauth_rock rock);
0174 
0175     /* End of version 1 kdcpreauth callbacks. */
0176 
0177     /* Return true if the client DB entry contains any keys matching the
0178      * request enctypes. */
0179     krb5_boolean (*have_client_keys)(krb5_context context,
0180                                      krb5_kdcpreauth_rock rock);
0181 
0182     /* End of version 2 kdcpreauth callbacks. */
0183 
0184     /*
0185      * Get the current reply key.  Initially the reply key is the decrypted
0186      * client long-term key chosen according to the request enctype list, or
0187      * NULL if no matching key was found.  The value may be changed by the
0188      * replace_reply_key callback or a return_padata method modifying
0189      * encrypting_key.  The returned pointer is an alias and should not be
0190      * freed.
0191      */
0192     const krb5_keyblock *(*client_keyblock)(krb5_context context,
0193                                             krb5_kdcpreauth_rock rock);
0194 
0195     /* Assert an authentication indicator in the AS-REP authdata.  Duplicate
0196      * indicators will be ignored. */
0197     krb5_error_code (*add_auth_indicator)(krb5_context context,
0198                                           krb5_kdcpreauth_rock rock,
0199                                           const char *indicator);
0200 
0201     /*
0202      * Read a data value for pa_type from the request cookie, placing it in
0203      * *out.  The value placed there is an alias and must not be freed.
0204      * Returns true if a value for pa_type was retrieved, false if not.
0205      */
0206     krb5_boolean (*get_cookie)(krb5_context context, krb5_kdcpreauth_rock rock,
0207                                krb5_preauthtype pa_type, krb5_data *out);
0208 
0209     /*
0210      * Set a data value for pa_type to be sent in a secure cookie in the next
0211      * error response.  If pa_type is already present, the value is ignored.
0212      * If the preauth mechanism has different preauth types for requests and
0213      * responses, use the request type.  Secure cookies are encrypted in a key
0214      * known only to the KDCs, but can be replayed within a short time window
0215      * for requests using the same client principal.
0216      */
0217     krb5_error_code (*set_cookie)(krb5_context context,
0218                                   krb5_kdcpreauth_rock rock,
0219                                   krb5_preauthtype pa_type,
0220                                   const krb5_data *data);
0221 
0222     /* End of version 3 kdcpreauth callbacks. */
0223 
0224     /*
0225      * Return true if princ matches the principal named in the request or the
0226      * client principal (possibly canonicalized).  If princ does not match,
0227      * attempt a database lookup of princ with aliases allowed and compare the
0228      * result to the client principal, returning true if it matches.
0229      * Otherwise, return false.
0230      */
0231     krb5_boolean (*match_client)(krb5_context context,
0232                                  krb5_kdcpreauth_rock rock,
0233                                  krb5_principal princ);
0234 
0235     /*
0236      * Get an alias to the client DB entry principal (possibly canonicalized).
0237      */
0238     krb5_principal (*client_name)(krb5_context context,
0239                                   krb5_kdcpreauth_rock rock);
0240 
0241     /* End of version 4 kdcpreauth callbacks. */
0242 
0243     /*
0244      * Instruct the KDC to send a freshness token in the method data
0245      * accompanying a PREAUTH_REQUIRED or PREAUTH_FAILED error, if the client
0246      * indicated support for freshness tokens.  This callback should only be
0247      * invoked from the edata method.
0248      */
0249     void (*send_freshness_token)(krb5_context context,
0250                                  krb5_kdcpreauth_rock rock);
0251 
0252     /* Validate a freshness token sent by the client.  Return 0 on success,
0253      * KRB5KDC_ERR_PREAUTH_EXPIRED on error. */
0254     krb5_error_code (*check_freshness_token)(krb5_context context,
0255                                              krb5_kdcpreauth_rock rock,
0256                                              const krb5_data *token);
0257 
0258     /* End of version 5 kdcpreauth callbacks. */
0259 
0260     /*
0261      * Replace the reply key with key.  If is_strengthen is true, key must be a
0262      * derivative of the client long-term key.  This callback may be invoked
0263      * from the verify or return_padata methods.  If it is invoked from the
0264      * verify method, the new key will appear as the encrypting_key input to
0265      * return_padata.
0266      */
0267     krb5_error_code (*replace_reply_key)(krb5_context context,
0268                                          krb5_kdcpreauth_rock rock,
0269                                          const krb5_keyblock *key,
0270                                          krb5_boolean is_strengthen);
0271 
0272     /* End of version 6 kdcpreauth callbacks. */
0273 
0274 } *krb5_kdcpreauth_callbacks;
0275 
0276 /* Optional: preauth plugin initialization function. */
0277 typedef krb5_error_code
0278 (*krb5_kdcpreauth_init_fn)(krb5_context context,
0279                            krb5_kdcpreauth_moddata *moddata_out,
0280                            const char **realmnames);
0281 
0282 /* Optional: preauth plugin cleanup function. */
0283 typedef void
0284 (*krb5_kdcpreauth_fini_fn)(krb5_context context,
0285                            krb5_kdcpreauth_moddata moddata);
0286 
0287 /*
0288  * Optional: return the flags which the KDC should use for this module.  This
0289  * is a callback instead of a static value because the module may or may not
0290  * wish to count itself as a hardware preauthentication module (in other words,
0291  * the flags may be affected by the configuration, for example if a site
0292  * administrator can force a particular preauthentication type to be supported
0293  * using only hardware).  This function is called for each entry entry in the
0294  * server_pa_type_list.
0295  */
0296 typedef int
0297 (*krb5_kdcpreauth_flags_fn)(krb5_context context, krb5_preauthtype pa_type);
0298 
0299 /*
0300  * Responder for krb5_kdcpreauth_edata_fn.  If invoked with a non-zero code, pa
0301  * will be ignored and the padata type will not be included in the hint list.
0302  * If invoked with a zero code and a null pa value, the padata type will be
0303  * included in the list with an empty value.  If invoked with a zero code and a
0304  * non-null pa value, pa will be included in the hint list and will later be
0305  * freed by the KDC.
0306  */
0307 typedef void
0308 (*krb5_kdcpreauth_edata_respond_fn)(void *arg, krb5_error_code code,
0309                                     krb5_pa_data *pa);
0310 
0311 /*
0312  * Optional: provide pa_data to send to the client as part of the "you need to
0313  * use preauthentication" error.  The implementation must invoke the respond
0314  * when complete, whether successful or not, either before returning or
0315  * asynchronously using the verto context returned by cb->event_context().
0316  *
0317  * This function is not allowed to create a modreq object because we have no
0318  * guarantee that the client will ever make a follow-up request, or that it
0319  * will hit this KDC if it does.
0320  */
0321 typedef void
0322 (*krb5_kdcpreauth_edata_fn)(krb5_context context, krb5_kdc_req *request,
0323                             krb5_kdcpreauth_callbacks cb,
0324                             krb5_kdcpreauth_rock rock,
0325                             krb5_kdcpreauth_moddata moddata,
0326                             krb5_preauthtype pa_type,
0327                             krb5_kdcpreauth_edata_respond_fn respond,
0328                             void *arg);
0329 
0330 /*
0331  * Responder for krb5_kdcpreauth_verify_fn.  Invoke with the arg parameter
0332  * supplied to verify, the error code (0 for success), an optional module
0333  * request state object to be consumed by return_fn or free_modreq_fn, optional
0334  * e_data to be passed to the caller if code is nonzero, and optional
0335  * authorization data to be included in the ticket.  In non-FAST replies,
0336  * e_data will be encoded as typed-data if the module sets the PA_TYPED_E_DATA
0337  * flag, and as pa-data otherwise.  e_data and authz_data will be freed by the
0338  * KDC.
0339  */
0340 typedef void
0341 (*krb5_kdcpreauth_verify_respond_fn)(void *arg, krb5_error_code code,
0342                                      krb5_kdcpreauth_modreq modreq,
0343                                      krb5_pa_data **e_data,
0344                                      krb5_authdata **authz_data);
0345 
0346 /*
0347  * Optional: verify preauthentication data sent by the client, setting the
0348  * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
0349  * field as appropriate.  The implementation must invoke the respond function
0350  * when complete, whether successful or not, either before returning or
0351  * asynchronously using the verto context returned by cb->event_context().
0352  */
0353 typedef void
0354 (*krb5_kdcpreauth_verify_fn)(krb5_context context,
0355                              krb5_data *req_pkt, krb5_kdc_req *request,
0356                              krb5_enc_tkt_part *enc_tkt_reply,
0357                              krb5_pa_data *data,
0358                              krb5_kdcpreauth_callbacks cb,
0359                              krb5_kdcpreauth_rock rock,
0360                              krb5_kdcpreauth_moddata moddata,
0361                              krb5_kdcpreauth_verify_respond_fn respond,
0362                              void *arg);
0363 
0364 /*
0365  * Optional: generate preauthentication response data to send to the client as
0366  * part of the AS-REP.  If it needs to override the key which is used to
0367  * encrypt the response, it can do so by modifying encrypting_key, but it is
0368  * preferrable to use the replace_reply_key callback.
0369  */
0370 typedef krb5_error_code
0371 (*krb5_kdcpreauth_return_fn)(krb5_context context,
0372                              krb5_pa_data *padata,
0373                              krb5_data *req_pkt,
0374                              krb5_kdc_req *request,
0375                              krb5_kdc_rep *reply,
0376                              krb5_keyblock *encrypting_key,
0377                              krb5_pa_data **send_pa_out,
0378                              krb5_kdcpreauth_callbacks cb,
0379                              krb5_kdcpreauth_rock rock,
0380                              krb5_kdcpreauth_moddata moddata,
0381                              krb5_kdcpreauth_modreq modreq);
0382 
0383 /* Optional: free a per-request context. */
0384 typedef void
0385 (*krb5_kdcpreauth_free_modreq_fn)(krb5_context,
0386                                   krb5_kdcpreauth_moddata moddata,
0387                                   krb5_kdcpreauth_modreq modreq);
0388 
0389 /* Optional: invoked after init_fn to provide the module with a pointer to the
0390  * verto main loop. */
0391 typedef krb5_error_code
0392 (*krb5_kdcpreauth_loop_fn)(krb5_context context,
0393                            krb5_kdcpreauth_moddata moddata,
0394                            struct verto_ctx *ctx);
0395 
0396 typedef struct krb5_kdcpreauth_vtable_st {
0397     /* Mandatory: name of module. */
0398     const char *name;
0399 
0400     /* Mandatory: pointer to zero-terminated list of pa_types which this module
0401      * can provide services for. */
0402     krb5_preauthtype *pa_type_list;
0403 
0404     krb5_kdcpreauth_init_fn init;
0405     krb5_kdcpreauth_fini_fn fini;
0406     krb5_kdcpreauth_flags_fn flags;
0407     krb5_kdcpreauth_edata_fn edata;
0408     krb5_kdcpreauth_verify_fn verify;
0409     krb5_kdcpreauth_return_fn return_padata;
0410     krb5_kdcpreauth_free_modreq_fn free_modreq;
0411     /* Minor 1 ends here. */
0412 
0413     krb5_kdcpreauth_loop_fn loop;
0414     /* Minor 2 ends here. */
0415 } *krb5_kdcpreauth_vtable;
0416 
0417 #endif /* KRB5_KDCPREAUTH_PLUGIN_H */