Home | History | Annotate | Download | only in include
      1 
      2 /*
      3  * <krb5/preauth_plugin.h>
      4  *
      5  * Copyright (c) 2006 Red Hat, Inc.
      6  * Portions copyright (c) 2006 Massachusetts Institute of Technology
      7  * All Rights Reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions are met:
     11  *
     12  *  * Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *  * Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in
     16  *    the documentation and/or other materials provided with the
     17  *    distribution.
     18  *  * Neither the name of Red Hat, Inc., nor the names of its
     19  *    contributors may be used to endorse or promote products derived
     20  *    from this software without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     23  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  *
     34  * Preauthentication plugin definitions for Kerberos 5.
     35  */
     36 
     37 #ifndef KRB5_PREAUTH_PLUGIN_H_INCLUDED
     38 #define KRB5_PREAUTH_PLUGIN_H_INCLUDED
     39 #include <krb5.h>
     40 
     41 /*
     42  * While arguments of these types are passed-in, for the most part a preauth
     43  * module can treat them as opaque.  If we need keying data, we can ask for
     44  * it directly.
     45  */
     46 struct _krb5_db_entry_new;
     47 struct _krb5_key_data;
     48 struct _krb5_preauth_client_rock;
     49 
     50 /*
     51  * Preauth mechanism property flags, unified from previous definitions in the
     52  * KDC and libkrb5 sources.
     53  */
     54 
     55 /* Provides a real answer which we can send back to the KDC (client-only).  The
     56  * client assumes that one real answer will be enough. */
     57 #define PA_REAL		0x00000001
     58 
     59 /* Doesn't provide a real answer, but must be given a chance to run before any
     60  * REAL mechanism callbacks (client-only). */
     61 #define PA_INFO		0x00000002
     62 
     63 /* Causes the KDC to include this mechanism in a list of supported preauth
     64  * types if the user's DB entry flags the user as requiring hardware-based
     65  * preauthentication (server-only). */
     66 #define PA_HARDWARE	0x00000004
     67 
     68 /* Causes the KDC to include this mechanism in a list of supported preauth
     69  * types if the user's DB entry flags the user as requiring preauthentication,
     70  * and to fail preauthentication if we can't verify the client data.  The
     71  * flipside of PA_SUFFICIENT (server-only). */
     72 #define PA_REQUIRED	0x00000008
     73 
     74 /* Causes the KDC to include this mechanism in a list of supported preauth
     75  * types if the user's DB entry flags the user as requiring preauthentication,
     76  * and to mark preauthentication as successful if we can verify the client
     77  * data.  The flipside of PA_REQUIRED (server-only). */
     78 #define PA_SUFFICIENT	0x00000010
     79 
     80 /* Marks this preauthentication mechanism as one which changes the key which is
     81  * used for encrypting the response to the client.  Modules which have this
     82  * flag have their server_return_proc called before modules which do not, and
     83  * are passed over if a previously-called module has modified the encrypting
     84  * key (server-only). */
     85 #define PA_REPLACES_KEY	0x00000020
     86 
     87 /* Causes the KDC to check with this preauthentication module even if the
     88  * client has no entry in the realm database.  If the module returns a success
     89  * code, continue processing and assume that its return_padata callback will
     90  * supply us with a key for encrypting the AS reply (server-only). */
     91 /* #define PA_VIRTUAL	(0x00000040 | PA_REPLACES_KEY) */
     92 
     93 /* Not really a padata type, so don't include it in any list of preauth types
     94  * which gets sent over the wire. */
     95 #define PA_PSEUDO	0x00000080
     96 
     97 
     98 /***************************************************************************
     99  *
    100  * Client-side preauthentication plugin interface definition.
    101  *
    102  ***************************************************************************/
    103 
    104 /*
    105  * A callback which will obtain the user's long-term AS key by prompting the
    106  * user for the password, then salting it properly, and so on.  For the moment,
    107  * it's identical to the get_as_key callback used inside of libkrb5, but we
    108  * define a new typedef here instead of making the existing one public to
    109  * isolate ourselves from potential future changes.
    110  */
    111 typedef krb5_error_code
    112 (*preauth_get_as_key_proc)(krb5_context,
    113 			   krb5_principal,
    114 			   krb5_enctype,
    115 			   krb5_prompter_fct,
    116 			   void *prompter_data,
    117 			   krb5_data *salt,
    118 			   krb5_data *s2kparams,
    119 			   krb5_keyblock *as_key,
    120 			   void *gak_data);
    121 
    122 /*
    123  * A client module's callback functions are allowed to request various
    124  * information to enable it to process a request.
    125  */
    126 enum krb5plugin_preauth_client_request_type {
    127     /* The returned krb5_data item holds the enctype used to encrypt the
    128      * encrypted portion of the AS_REP packet. */
    129     krb5plugin_preauth_client_get_etype = 1,
    130     /* Free the data returned from krb5plugin_preauth_client_req_get_etype */
    131     krb5plugin_preauth_client_free_etype = 2
    132 };
    133 typedef krb5_error_code
    134 (*preauth_get_client_data_proc)(krb5_context,
    135 				struct _krb5_preauth_client_rock *,
    136 				krb5_int32 request_type,
    137 				krb5_data **);
    138 
    139 /* Per-plugin initialization/cleanup.  The init function is called
    140  * by libkrb5 when the plugin is loaded, and the fini function is
    141  * called before the plugin is unloaded.  Both are optional and
    142  * may be called multiple times in case the plugin is used in
    143  * multiple contexts.  The returned context lives the lifetime of
    144  * the krb5_context */
    145 typedef krb5_error_code
    146 (*preauth_client_plugin_init_proc)(krb5_context context,
    147 				   void **plugin_context);
    148 typedef void
    149 (*preauth_client_plugin_fini_proc)(krb5_context context,
    150 				   void *plugin_context);
    151 
    152 /* A callback which returns flags indicating if the module is a "real" or
    153  * an "info" mechanism, and so on.  This function is called for each entry
    154  * in the client_pa_type_list. */
    155 typedef int
    156 (*preauth_client_get_flags_proc)(krb5_context context,
    157 				 krb5_preauthtype pa_type);
    158 
    159 /* Per-request initialization/cleanup.  The request_init function is
    160  * called when beginning to process a get_init_creds request and the
    161  * request_fini function is called when processing of the request is
    162  * complete.  This is optional.  It may be called multiple times in
    163  * the lifetime of a krb5_context. */
    164 typedef void
    165 (*preauth_client_request_init_proc)(krb5_context context,
    166 				    void *plugin_context,
    167 				    void **request_context);
    168 typedef void
    169 (*preauth_client_request_fini_proc)(krb5_context context,
    170 				    void *plugin_context,
    171 				    void *request_context);
    172 
    173 /* Client function which processes server-supplied data in pa_data,
    174  * returns created data in out_pa_data, storing any of its own state in
    175  * client_context if data for the associated preauthentication type is
    176  * needed.  It is also called after the AS-REP is received if the AS-REP
    177  * includes preauthentication data of the associated type.
    178  * NOTE! the encoded_previous_request will be NULL the first time this
    179  * function is called, because it is expected to only ever contain the data
    180  * obtained from a previous call to this function. */
    181 typedef krb5_error_code
    182 (*preauth_client_process_proc)(krb5_context context,
    183 			       void *plugin_context,
    184 			       void *request_context,
    185 			       krb5_get_init_creds_opt *opt,
    186 			       preauth_get_client_data_proc get_data_proc,
    187 			       struct _krb5_preauth_client_rock *rock,
    188 			       krb5_kdc_req *request,
    189 			       krb5_data *encoded_request_body,
    190 			       krb5_data *encoded_previous_request,
    191 			       krb5_pa_data *pa_data,
    192 			       krb5_prompter_fct prompter,
    193 			       void *prompter_data,
    194 			       preauth_get_as_key_proc gak_fct,
    195 			       void *gak_data,
    196 			       krb5_data *salt,
    197 			       krb5_data *s2kparams,
    198 			       krb5_keyblock *as_key,
    199 			       krb5_pa_data ***out_pa_data);
    200 
    201 /* Client function which can attempt to use e-data in the error response to
    202  * try to recover from the given error.  If this function is not NULL, and
    203  * it stores data in out_pa_data which is different data from the contents
    204  * of in_pa_data, then the client library will retransmit the request. */
    205 typedef krb5_error_code
    206 (*preauth_client_tryagain_proc)(krb5_context context,
    207 				void *plugin_context,
    208 				void *request_context,
    209 				krb5_get_init_creds_opt *opt,
    210 				preauth_get_client_data_proc get_data_proc,
    211 				struct _krb5_preauth_client_rock *rock,
    212 				krb5_kdc_req *request,
    213 				krb5_data *encoded_request_body,
    214 				krb5_data *encoded_previous_request,
    215 				krb5_pa_data *in_pa_data,
    216 				krb5_error *error,
    217 				krb5_prompter_fct prompter,
    218 				void *prompter_data,
    219 				preauth_get_as_key_proc gak_fct,
    220 				void *gak_data,
    221 				krb5_data *salt,
    222 				krb5_data *s2kparams,
    223 				krb5_keyblock *as_key,
    224 				krb5_pa_data ***out_pa_data);
    225 
    226 /*
    227  * Client function which receives krb5_get_init_creds_opt information.
    228  * The attr and value information supplied should be copied locally by
    229  * the module if it wishes to reference it after returning from this call.
    230  */
    231 typedef krb5_error_code
    232 (*preauth_client_supply_gic_opts_proc)(krb5_context context,
    233 				       void *plugin_context,
    234 				       krb5_get_init_creds_opt *opt,
    235 				       const char *attr,
    236 				       const char *value);
    237 
    238 /*
    239  * The function table / structure which a preauth client module must export as
    240  * "preauthentication_client_0".  If the interfaces work correctly, future
    241  * versions of the table will add either more callbacks or more arguments to
    242  * callbacks, and in both cases we'll be able to wrap the v0 functions.
    243  */
    244 typedef struct krb5plugin_preauth_client_ftable_v1 {
    245     /* Not-usually-visible name. */
    246     char *name;
    247 
    248     /* Pointer to zero-terminated list of pa_types which this module can
    249      * provide services for. */
    250     krb5_preauthtype *pa_type_list;
    251 
    252     /* Pointer to zero-terminated list of enc_types which this module claims
    253      * to add support for. */
    254     krb5_enctype *enctype_list;
    255 
    256     /* Per-plugin initialization/cleanup.  The init function is called
    257      * by libkrb5 when the plugin is loaded, and the fini function is
    258      * called before the plugin is unloaded.  Both are optional and
    259      * may be called multiple times in case the plugin is used in
    260      * multiple contexts.  The returned context lives the lifetime of
    261      * the krb5_context */
    262     preauth_client_plugin_init_proc init;
    263     preauth_client_plugin_fini_proc fini;
    264 
    265     /* A callback which returns flags indicating if the module is a "real" or
    266      * an "info" mechanism, and so on.  This function is called for each entry
    267      * in the client_pa_type_list. */
    268     preauth_client_get_flags_proc flags;
    269 
    270     /* Per-request initialization/cleanup.  The request_init function is
    271      * called when beginning to process a get_init_creds request and the
    272      * request_fini function is called when processing of the request is
    273      * complete.  This is optional.  It may be called multiple times in
    274      * the lifetime of a krb5_context. */
    275     preauth_client_request_init_proc request_init;
    276     preauth_client_request_fini_proc request_fini;
    277 
    278     /* Client function which processes server-supplied data in pa_data,
    279      * returns created data in out_pa_data, storing any of its own state in
    280      * client_context if data for the associated preauthentication type is
    281      * needed.  It is also called after the AS-REP is received if the AS-REP
    282      * includes preauthentication data of the associated type.
    283      * NOTE! the encoded_previous_request will be NULL the first time this
    284      * function is called, because it is expected to only ever contain the data
    285      * obtained from a previous call to this function. */
    286     preauth_client_process_proc process;
    287 
    288     /* Client function which can attempt to use e-data in the error response to
    289      * try to recover from the given error.  If this function is not NULL, and
    290      * it stores data in out_pa_data which is different data from the contents
    291      * of in_pa_data, then the client library will retransmit the request. */
    292     preauth_client_tryagain_proc tryagain;
    293 
    294     /*
    295      * Client function which receives krb5_get_init_creds_opt information.
    296      * The attr and value information supplied should be copied locally by
    297      * the module if it wishes to reference it after returning from this call.
    298      */
    299     preauth_client_supply_gic_opts_proc gic_opts;
    300 
    301 } krb5plugin_preauth_client_ftable_v1;
    302 
    303 
    304 /***************************************************************************
    305  *
    306  * Server-side preauthentication plugin interface definition.
    307  *
    308  ***************************************************************************/
    309 
    310 /*
    311  * A server module's callback functions are allowed to request specific types
    312  * of information about the given client or server record or request, even
    313  * though the database records themselves are opaque to the module.
    314  */
    315 enum krb5plugin_preauth_entry_request_type {
    316     /* The returned krb5_data item holds a DER-encoded X.509 certificate. */
    317     krb5plugin_preauth_entry_request_certificate = 1,
    318     /* The returned krb5_data_item holds a krb5_deltat. */
    319     krb5plugin_preauth_entry_max_time_skew = 2,
    320     /* The returned krb5_data_item holds an array of krb5_keyblock structures,
    321      * terminated by an entry with key type = 0.
    322      * Each keyblock should have its contents freed in turn, and then the data
    323      * item itself should be freed. */
    324     krb5plugin_preauth_keys = 3,
    325     /* The returned krb5_data_item holds the request structure, re-encoded
    326      * using DER.  Unless the client implementation is the same as the server
    327      * implementation, there's a good chance that the result will not match
    328      * what the client sent, so don't go creating any fatal errors if it
    329      * doesn't match up. */
    330     krb5plugin_preauth_request_body = 4
    331 };
    332 
    333 typedef krb5_error_code
    334 (*preauth_get_entry_data_proc)(krb5_context,
    335 			       krb5_kdc_req *,
    336 			       struct _krb5_db_entry_new *,
    337 			       krb5_int32 request_type,
    338 			       krb5_data **);
    339 
    340 /* Preauth plugin initialization function */
    341 typedef krb5_error_code
    342 (*preauth_server_init_proc)(krb5_context context,
    343 			    void **plugin_context,
    344 			    const char** realmnames);
    345 
    346 /* Preauth plugin cleanup function */
    347 typedef void
    348 (*preauth_server_fini_proc)(krb5_context context, void *plugin_context);
    349 
    350 /* Return the flags which the KDC should use for this module.  This is a
    351  * callback instead of a static value because the module may or may not
    352  * wish to count itself as a hardware preauthentication module (in other
    353  * words, the flags may be affected by the configuration, for example if a
    354  * site administrator can force a particular preauthentication type to be
    355  * supported using only hardware).  This function is called for each entry
    356  * entry in the server_pa_type_list. */
    357 typedef int
    358 (*preauth_server_flags_proc)(krb5_context context, krb5_preauthtype patype);
    359 
    360 /* Get preauthentication data to send to the client as part of the "you
    361  * need to use preauthentication" error.  The module doesn't need to
    362  * actually provide data if the protocol doesn't require it, but it should
    363  * return either zero or non-zero to control whether its padata type is
    364  * included in the list which is sent back to the client.  Is not allowed
    365  * to create a context because we have no guarantee that the client will
    366  * ever call again (or that it will hit this server if it does), in which
    367  * case a context might otherwise hang around forever. */
    368 typedef krb5_error_code
    369 (*preauth_server_edata_proc)(krb5_context,
    370 			     krb5_kdc_req *request,
    371 			     struct _krb5_db_entry_new *client,
    372 			     struct _krb5_db_entry_new *server,
    373 			     preauth_get_entry_data_proc,
    374 			     void *pa_module_context,
    375 			     krb5_pa_data *data);
    376 
    377 /* Verify preauthentication data sent by the client, setting the
    378  * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
    379  * field as appropriate, and returning nonzero on failure.  Can create
    380  * context data for consumption by the return_proc or freepa_proc below. */
    381 typedef krb5_error_code
    382 (*preauth_server_verify_proc)(krb5_context context,
    383 			      struct _krb5_db_entry_new *client,
    384 			      krb5_data *req_pkt,
    385 			      krb5_kdc_req *request,
    386 			      krb5_enc_tkt_part *enc_tkt_reply,
    387 			      krb5_pa_data *data,
    388 			      preauth_get_entry_data_proc,
    389 			      void *pa_module_context,
    390 			      void **pa_request_context,
    391 			      krb5_data **e_data,
    392 			      krb5_authdata ***authz_data);
    393 
    394 /* Generate preauthentication response data to send to the client as part
    395  * of the AS-REP.  If it needs to override the key which is used to encrypt
    396  * the response, it can do so.  The module is expected (but not required,
    397  * if a preauth_server_free_reqcontext_proc is also provided) to free any
    398  * context data it saved in "pa_request_context". */
    399 typedef krb5_error_code
    400 (*preauth_server_return_proc)(krb5_context context,
    401 			      krb5_pa_data * padata,
    402 			      struct _krb5_db_entry_new *client,
    403 			      krb5_data *req_pkt,
    404 			      krb5_kdc_req *request,
    405 			      krb5_kdc_rep *reply,
    406 			      struct _krb5_key_data *client_keys,
    407 			      krb5_keyblock *encrypting_key,
    408 			      krb5_pa_data **send_pa,
    409 			      preauth_get_entry_data_proc,
    410 			      void *pa_module_context,
    411 			      void **pa_request_context);
    412 
    413 /* Free up the server-side per-request context, in cases where
    414  * server_return_proc() didn't or for whatever reason was not called.
    415  * Can be NULL. */
    416 typedef krb5_error_code
    417 (*preauth_server_free_reqcontext_proc)(krb5_context,
    418 				       void *pa_module_context,
    419 				       void **request_pa_context);
    420 
    421 /*
    422  * The function table / structure which a preauth server module must export as
    423  * "preauthentication_server_0".  NOTE: replace "0" with "1" for the type and
    424  * variable names if this gets picked up by upstream.  If the interfaces work
    425  * correctly, future versions of the table will add either more callbacks or
    426  * more arguments to callbacks, and in both cases we'll be able to wrap the v0
    427  * functions.
    428  */
    429 typedef struct krb5plugin_preauth_server_ftable_v1 {
    430     /* Not-usually-visible name. */
    431     char *name;
    432 
    433     /* Pointer to zero-terminated list of pa_types which this module can
    434      * provide services for. */
    435     krb5_preauthtype *pa_type_list;
    436 
    437     /* Per-plugin initialization/cleanup.  The init function is called by the
    438      * KDC when the plugin is loaded, and the fini function is called before
    439      * the plugin is unloaded.  Both are optional. */
    440     preauth_server_init_proc init_proc;
    441     preauth_server_fini_proc fini_proc;
    442 
    443     /* Return the flags which the KDC should use for this module.  This is a
    444      * callback instead of a static value because the module may or may not
    445      * wish to count itself as a hardware preauthentication module (in other
    446      * words, the flags may be affected by the configuration, for example if a
    447      * site administrator can force a particular preauthentication type to be
    448      * supported using only hardware).  This function is called for each entry
    449      * entry in the server_pa_type_list. */
    450     preauth_server_flags_proc flags_proc;
    451 
    452     /* Get preauthentication data to send to the client as part of the "you
    453      * need to use preauthentication" error.  The module doesn't need to
    454      * actually provide data if the protocol doesn't require it, but it should
    455      * return either zero or non-zero to control whether its padata type is
    456      * included in the list which is sent back to the client.  Is not allowed
    457      * to create a context because we have no guarantee that the client will
    458      * ever call again (or that it will hit this server if it does), in which
    459      * case a context might otherwise hang around forever. */
    460     preauth_server_edata_proc edata_proc;
    461 
    462     /* Verify preauthentication data sent by the client, setting the
    463      * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
    464      * field as appropriate, and returning nonzero on failure.  Can create
    465      * context data for consumption by the return_proc or freepa_proc below. */
    466     preauth_server_verify_proc verify_proc;
    467 
    468     /* Generate preauthentication response data to send to the client as part
    469      * of the AS-REP.  If it needs to override the key which is used to encrypt
    470      * the response, it can do so.  The module is expected (but not required,
    471      * if a freepa_proc is also provided) to free any context data it saved in
    472      * "request_pa_context". */
    473     preauth_server_return_proc return_proc;
    474 
    475     /* Free up the server-side per-request context, in cases where
    476      * server_return_proc() didn't or for whatever reason was not called.
    477      * Can be NULL. */
    478     preauth_server_free_reqcontext_proc freepa_reqcontext_proc;
    479 
    480 } krb5plugin_preauth_server_ftable_v1;
    481 
    482 
    483 /*
    484  * This function allows a preauth plugin to obtain preauth
    485  * options.  The preauth_data returned from this function
    486  * should be freed by calling krb5_get_init_creds_opt_free_pa().
    487  *
    488  * The 'opt' pointer supplied to this function must have been
    489  * obtained using krb5_get_init_creds_opt_alloc()
    490  */
    491 krb5_error_code KRB5_CALLCONV
    492 krb5_get_init_creds_opt_get_pa
    493 		(krb5_context context,
    494 		krb5_get_init_creds_opt *opt,
    495 		int *num_preauth_data,
    496 		krb5_gic_opt_pa_data **preauth_data);
    497 
    498 /*
    499  * This function frees the preauth_data that was returned by
    500  * krb5_get_init_creds_opt_get_pa().
    501  */
    502 void KRB5_CALLCONV
    503 krb5_get_init_creds_opt_free_pa
    504 		(krb5_context context,
    505 		 int num_preauth_data,
    506 		 krb5_gic_opt_pa_data *preauth_data);
    507 
    508 #endif /* KRB5_PREAUTH_PLUGIN_H_INCLUDED */
    509