Allow preauth mechs to work with clock skew
[krb5.git] / src / include / krb5 / preauth_plugin.h
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright (c) 2006 Red Hat, Inc.
4  * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology
5  * All Rights Reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  *  * Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *  * Neither the name of Red Hat, Inc., nor the names of its
17  *    contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /*
34  * Declarations for preauth plugin module implementors.
35  *
36  * This header defines two preauth interfaces, clpreauth and kdcpreauth.  A
37  * shared object can implement both interfaces or it can implement just one.
38  *
39  *
40  * The clpreauth interface has a single supported major version, which is
41  * 1.  Major version 1 has a current minor version of 1.  clpreauth modules
42  * should define a function named clpreauth_<modulename>_initvt, matching
43  * the signature:
44  *
45  *   krb5_error_code
46  *   clpreauth_modname_initvt(krb5_context context, int maj_ver,
47  *                            int min_ver, krb5_plugin_vtable vtable);
48  *
49  * The kdcpreauth interface has a single supported major version, which is 1.
50  * Major version 1 has a current minor version of 1.  kdcpreauth modules should
51  * define a function named kdcpreauth_<modulename>_initvt, matching the
52  * signature:
53  *
54  *   krb5_error_code
55  *   kdcpreauth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
56  *                             krb5_plugin_vtable vtable);
57  *
58  * For both interfaces, the initvt function should:
59  *
60  * - Check that the supplied maj_ver number is supported by the module, or
61  *   return KRB5_PLUGIN_VER_NOTSUPP if it is not.
62  *
63  * - Cast the vtable pointer as appropriate for the interface and maj_ver:
64  *     clpreauth, maj_ver == 1:  Cast to krb5_clpreauth_vtable
65  *     kdcpreauth, maj_ver == 1: Cast to krb5_kdcpreauth_vtable
66  *
67  * - Initialize the methods of the vtable, stopping as appropriate for the
68  *   supplied min_ver.  Optional methods may be left uninitialized.
69  *
70  * Memory for the vtable is allocated by the caller, not by the module.
71  */
72
73 #ifndef KRB5_PREAUTH_PLUGIN_H_INCLUDED
74 #define KRB5_PREAUTH_PLUGIN_H_INCLUDED
75 #include <krb5/krb5.h>
76 #include <krb5/plugin.h>
77
78 /*
79  * Preauth mechanism property flags, unified from previous definitions in the
80  * KDC and libkrb5 sources.
81  */
82
83 /* Provides a real answer which we can send back to the KDC (client-only).  The
84  * client assumes that one real answer will be enough. */
85 #define PA_REAL         0x00000001
86
87 /* Doesn't provide a real answer, but must be given a chance to run before any
88  * REAL mechanism callbacks (client-only). */
89 #define PA_INFO         0x00000002
90
91 /*
92  * Causes the KDC to include this mechanism in a list of supported preauth
93  * types if the user's DB entry flags the user as requiring hardware-based
94  * preauthentication (KDC-only).
95  */
96 #define PA_HARDWARE     0x00000004
97
98 /*
99  * Causes the KDC to include this mechanism in a list of supported preauth
100  * types if the user's DB entry flags the user as requiring preauthentication,
101  * and to fail preauthentication if we can't verify the client data.  The
102  * flipside of PA_SUFFICIENT (KDC-only).
103  */
104 #define PA_REQUIRED     0x00000008
105
106 /*
107  * Causes the KDC to include this mechanism in a list of supported preauth
108  * types if the user's DB entry flags the user as requiring preauthentication,
109  * and to mark preauthentication as successful if we can verify the client
110  * data.  The flipside of PA_REQUIRED (KDC-only).
111  */
112 #define PA_SUFFICIENT   0x00000010
113
114 /*
115  * Marks this preauthentication mechanism as one which changes the key which is
116  * used for encrypting the response to the client.  Modules which have this
117  * flag have their server_return_fn called before modules which do not, and are
118  * passed over if a previously-called module has modified the encrypting key
119  * (KDC-only).
120  */
121 #define PA_REPLACES_KEY 0x00000020
122
123 /*
124  * Not really a padata type, so don't include it in any list of preauth types
125  * which gets sent over the wire.
126  */
127 #define PA_PSEUDO       0x00000080
128
129 /*
130  * For kdcpreauth mechanisms, indicates that e_data in non-FAST errors should
131  * be encoded as typed data instead of padata.
132  */
133 #define PA_TYPED_E_DATA 0x00000100
134
135 /*
136  * clpreauth plugin interface definition.
137  */
138
139 /* Abstract type for a client request information handle. */
140 typedef struct krb5_clpreauth_rock_st *krb5_clpreauth_rock;
141
142 /* Abstract types for module data and per-request module data. */
143 typedef struct krb5_clpreauth_moddata_st *krb5_clpreauth_moddata;
144 typedef struct krb5_clpreauth_modreq_st *krb5_clpreauth_modreq;
145
146 /* Before using a callback after version 1, modules must check the vers
147  * field of the callback structure. */
148 typedef struct krb5_clpreauth_callbacks_st {
149     int vers;
150
151     /*
152      * Get the enctype expected to be used to encrypt the encrypted portion of
153      * the AS_REP packet.  When handling a PREAUTH_REQUIRED error, this
154      * typically comes from etype-info2.  When handling an AS reply, it is
155      * initialized from the AS reply itself.
156      */
157     krb5_enctype (*get_etype)(krb5_context context, krb5_clpreauth_rock rock);
158
159     /* Get a pointer to the FAST armor key, or NULL if the client is not using
160      * FAST.  The returned pointer is an alias and should not be freed. */
161     krb5_keyblock *(*fast_armor)(krb5_context context,
162                                  krb5_clpreauth_rock rock);
163
164     /*
165      * Get a pointer to the client-supplied reply key, possibly invoking the
166      * prompter to ask for a password if this has not already been done.  The
167      * returned pointer is an alias and should not be freed.
168      */
169     krb5_error_code (*get_as_key)(krb5_context context,
170                                   krb5_clpreauth_rock rock,
171                                   krb5_keyblock **keyblock);
172
173     /* Replace the reply key to be used to decrypt the AS response. */
174     krb5_error_code (*set_as_key)(krb5_context context,
175                                   krb5_clpreauth_rock rock,
176                                   const krb5_keyblock *keyblock);
177
178     /* End of version 1 clpreauth callbacks. */
179
180     /*
181      * Get the current time for use in a preauth response.  If
182      * allow_unauth_time is true and the library has been configured to allow
183      * it, the current time will be offset using unauthenticated timestamp
184      * information received from the KDC in the preauth-required error, if one
185      * has been received.  Otherwise, the timestamp in a preauth-required error
186      * will only be used if it is protected by a FAST channel.  Only set
187      * allow_unauth_time if using an unauthenticated time offset would not
188      * create a security issue.
189      */
190     krb5_error_code (*get_preauth_time)(krb5_context context,
191                                         krb5_clpreauth_rock rock,
192                                         krb5_boolean allow_unauth_time,
193                                         krb5_timestamp *time_out,
194                                         krb5_int32 *usec_out);
195
196     /* End of version 2 clpreauth callbacks (added in 1.11). */
197 } *krb5_clpreauth_callbacks;
198
199 /*
200  * Optional: per-plugin initialization/cleanup.  The init function is called by
201  * libkrb5 when the plugin is loaded, and the fini function is called before
202  * the plugin is unloaded.  These may be called multiple times in case the
203  * plugin is used in multiple contexts.  The returned context lives the
204  * lifetime of the krb5_context.
205  */
206 typedef krb5_error_code
207 (*krb5_clpreauth_init_fn)(krb5_context context,
208                           krb5_clpreauth_moddata *moddata_out);
209 typedef void
210 (*krb5_clpreauth_fini_fn)(krb5_context context,
211                           krb5_clpreauth_moddata moddata);
212
213 /*
214  * Mandatory: Return flags indicating if the module is a "real" or an "info"
215  * mechanism, and so on.  This function is called for each entry in the
216  * client_pa_type_list.
217  */
218 typedef int
219 (*krb5_clpreauth_get_flags_fn)(krb5_context context, krb5_preauthtype pa_type);
220
221 /*
222  * Optional: per-request initialization/cleanup.  The request_init function is
223  * called when beginning to process a get_init_creds request and the
224  * request_fini function is called when processing of the request is complete.
225  * This is optional.  It may be called multiple times in the lifetime of a
226  * krb5_context.
227  */
228 typedef void
229 (*krb5_clpreauth_request_init_fn)(krb5_context context,
230                                   krb5_clpreauth_moddata moddata,
231                                   krb5_clpreauth_modreq *modreq_out);
232 typedef void
233 (*krb5_clpreauth_request_fini_fn)(krb5_context context,
234                                   krb5_clpreauth_moddata moddata,
235                                   krb5_clpreauth_modreq modreq);
236
237 /*
238  * Mandatory: process server-supplied data in pa_data and return created data
239  * in pa_data_out.  Also called after the AS-REP is received if the AS-REP
240  * includes preauthentication data of the associated type.
241  *
242  * as_key contains the client-supplied key if known, or an empty keyblock if
243  * not.  If it is empty, the module may use gak_fct to fill it in.
244  *
245  * encoded_previous_request may be NULL if there has been no previous request
246  * in the AS exchange.
247  */
248 typedef krb5_error_code
249 (*krb5_clpreauth_process_fn)(krb5_context context,
250                              krb5_clpreauth_moddata moddata,
251                              krb5_clpreauth_modreq modreq,
252                              krb5_get_init_creds_opt *opt,
253                              krb5_clpreauth_callbacks cb,
254                              krb5_clpreauth_rock rock,
255                              krb5_kdc_req *request,
256                              krb5_data *encoded_request_body,
257                              krb5_data *encoded_previous_request,
258                              krb5_pa_data *pa_data,
259                              krb5_prompter_fct prompter, void *prompter_data,
260                              krb5_pa_data ***pa_data_out);
261
262 /*
263  * Optional: Attempt to use error and error_padata to try to recover from the
264  * given error.  To work with both FAST and non-FAST errors, an implementation
265  * should generally consult error_padata rather than decoding error->e_data.
266  * For non-FAST errors, it contains the e_data decoded as either pa-data or
267  * typed-data.
268  *
269  * If this function is provided, and it returns 0 and stores data in
270  * pa_data_out, then the client library will retransmit the request.
271  */
272 typedef krb5_error_code
273 (*krb5_clpreauth_tryagain_fn)(krb5_context context,
274                               krb5_clpreauth_moddata moddata,
275                               krb5_clpreauth_modreq modreq,
276                               krb5_get_init_creds_opt *opt,
277                               krb5_clpreauth_callbacks cb,
278                               krb5_clpreauth_rock rock,
279                               krb5_kdc_req *request,
280                               krb5_data *encoded_request_body,
281                               krb5_data *encoded_previous_request,
282                               krb5_preauthtype pa_type,
283                               krb5_error *error,
284                               krb5_pa_data **error_padata,
285                               krb5_prompter_fct prompter, void *prompter_data,
286                               krb5_pa_data ***pa_data_out);
287
288 /*
289  * Optional: receive krb5_get_init_creds_opt information.  The attr and value
290  * information supplied should be copied into moddata by the module if it
291  * wishes to reference it after returning from this call.
292  */
293 typedef krb5_error_code
294 (*krb5_clpreauth_supply_gic_opts_fn)(krb5_context context,
295                                      krb5_clpreauth_moddata moddata,
296                                      krb5_get_init_creds_opt *opt,
297                                      const char *attr, const char *value);
298
299 typedef struct krb5_clpreauth_vtable_st {
300     /* Mandatory: name of module. */
301     char *name;
302
303     /* Mandatory: pointer to zero-terminated list of pa_types which this module
304      * can provide services for. */
305     krb5_preauthtype *pa_type_list;
306
307     /* Optional: pointer to zero-terminated list of enc_types which this module
308      * claims to add support for. */
309     krb5_enctype *enctype_list;
310
311     krb5_clpreauth_init_fn init;
312     krb5_clpreauth_fini_fn fini;
313     krb5_clpreauth_get_flags_fn flags;
314     krb5_clpreauth_request_init_fn request_init;
315     krb5_clpreauth_request_fini_fn request_fini;
316     krb5_clpreauth_process_fn process;
317     krb5_clpreauth_tryagain_fn tryagain;
318     krb5_clpreauth_supply_gic_opts_fn gic_opts;
319     /* Minor version 1 ends here. */
320 } *krb5_clpreauth_vtable;
321
322 /*
323  * This function allows a clpreauth plugin to obtain preauth options.  The
324  * preauth_data returned from this function should be freed by calling
325  * krb5_get_init_creds_opt_free_pa().
326  */
327 krb5_error_code KRB5_CALLCONV
328 krb5_get_init_creds_opt_get_pa(krb5_context context,
329                                krb5_get_init_creds_opt *opt,
330                                int *num_preauth_data,
331                                krb5_gic_opt_pa_data **preauth_data);
332
333 /*
334  * This function frees the preauth_data that was returned by
335  * krb5_get_init_creds_opt_get_pa().
336  */
337 void KRB5_CALLCONV
338 krb5_get_init_creds_opt_free_pa(krb5_context context,
339                                 int num_preauth_data,
340                                 krb5_gic_opt_pa_data *preauth_data);
341
342
343 /*
344  * kdcpreauth plugin interface definition.
345  */
346
347 /* Abstract type for a KDC callback data handle. */
348 typedef struct krb5_kdcpreauth_rock_st *krb5_kdcpreauth_rock;
349
350 /* Abstract type for module data and per-request module data. */
351 typedef struct krb5_kdcpreauth_moddata_st *krb5_kdcpreauth_moddata;
352 typedef struct krb5_kdcpreauth_modreq_st *krb5_kdcpreauth_modreq;
353
354 /* The verto context structure type (typedef is in verto.h; we want to avoid a
355  * header dependency for the moment). */
356 struct verto_context;
357
358 /* Before using a callback after version 1, modules must check the vers
359  * field of the callback structure. */
360 typedef struct krb5_kdcpreauth_callbacks_st {
361     int vers;
362
363     krb5_deltat (*max_time_skew)(krb5_context context,
364                                  krb5_kdcpreauth_rock rock);
365
366     /*
367      * Get an array of krb5_keyblock structures containing the client keys
368      * matching the request enctypes, terminated by an entry with key type = 0.
369      * Returns ENOENT if no keys are available for the request enctypes.  Free
370      * the resulting object with the free_keys callback.
371      */
372     krb5_error_code (*client_keys)(krb5_context context,
373                                    krb5_kdcpreauth_rock rock,
374                                    krb5_keyblock **keys_out);
375
376     /* Free the result of client_keys. */
377     void (*free_keys)(krb5_context context, krb5_kdcpreauth_rock rock,
378                       krb5_keyblock *keys);
379
380     /*
381      * Get the encoded request body, which is sometimes needed for checksums.
382      * For a FAST request this is the encoded inner request body.  The returned
383      * pointer is an alias and should not be freed.
384      */
385     krb5_data *(*request_body)(krb5_context context,
386                                krb5_kdcpreauth_rock rock);
387
388     /* Get a pointer to the FAST armor key, or NULL if the request did not use
389      * FAST.  The returned pointer is an alias and should not be freed. */
390     krb5_keyblock *(*fast_armor)(krb5_context context,
391                                  krb5_kdcpreauth_rock rock);
392
393     /* Retrieve a string attribute from the client DB entry, or NULL if no such
394      * attribute is set.  Free the result with the free_string callback. */
395     krb5_error_code (*get_string)(krb5_context context,
396                                   krb5_kdcpreauth_rock rock, const char *key,
397                                   char **value_out);
398
399     /* Free the result of get_string. */
400     void (*free_string)(krb5_context context, krb5_kdcpreauth_rock rock,
401                         char *string);
402
403     /* Get a pointer to the client DB entry (returned as a void pointer to
404      * avoid a dependency on a libkdb5 type). */
405     void *(*client_entry)(krb5_context context, krb5_kdcpreauth_rock rock);
406
407     /* Get a pointer to the verto context which should be used by an
408      * asynchronous edata or verify method. */
409     struct verto_ctx *(*event_context)(krb5_context context,
410                                        krb5_kdcpreauth_rock rock);
411
412     /* End of version 1 kdcpreauth callbacks. */
413 } *krb5_kdcpreauth_callbacks;
414
415 /* Optional: preauth plugin initialization function. */
416 typedef krb5_error_code
417 (*krb5_kdcpreauth_init_fn)(krb5_context context,
418                            krb5_kdcpreauth_moddata *moddata_out,
419                            const char **realmnames);
420
421 /* Optional: preauth plugin cleanup function. */
422 typedef void
423 (*krb5_kdcpreauth_fini_fn)(krb5_context context,
424                            krb5_kdcpreauth_moddata moddata);
425
426 /*
427  * Optional: return the flags which the KDC should use for this module.  This
428  * is a callback instead of a static value because the module may or may not
429  * wish to count itself as a hardware preauthentication module (in other words,
430  * the flags may be affected by the configuration, for example if a site
431  * administrator can force a particular preauthentication type to be supported
432  * using only hardware).  This function is called for each entry entry in the
433  * server_pa_type_list.
434  */
435 typedef int
436 (*krb5_kdcpreauth_flags_fn)(krb5_context context, krb5_preauthtype pa_type);
437
438 /*
439  * Responder for krb5_kdcpreauth_edata_fn.  If invoked with a non-zero code, pa
440  * will be ignored and the padata type will not be included in the hint list.
441  * If invoked with a zero code and a null pa value, the padata type will be
442  * included in the list with an empty value.  If invoked with a zero code and a
443  * non-null pa value, pa will be included in the hint list and will later be
444  * freed by the KDC.
445  */
446 typedef void
447 (*krb5_kdcpreauth_edata_respond_fn)(void *arg, krb5_error_code code,
448                                     krb5_pa_data *pa);
449
450 /*
451  * Optional: provide pa_data to send to the client as part of the "you need to
452  * use preauthentication" error.  The implementation must invoke the respond
453  * when complete, whether successful or not, either before returning or
454  * asynchronously using the verto context returned by cb->event_context().
455  *
456  * This function is not allowed to create a modreq object because we have no
457  * guarantee that the client will ever make a follow-up request, or that it
458  * will hit this KDC if it does.
459  */
460 typedef void
461 (*krb5_kdcpreauth_edata_fn)(krb5_context context, krb5_kdc_req *request,
462                             krb5_kdcpreauth_callbacks cb,
463                             krb5_kdcpreauth_rock rock,
464                             krb5_kdcpreauth_moddata moddata,
465                             krb5_preauthtype pa_type,
466                             krb5_kdcpreauth_edata_respond_fn respond,
467                             void *arg);
468
469 /*
470  * Responder for krb5_kdcpreauth_verify_fn.  Invoke with the arg parameter
471  * supplied to verify, the error code (0 for success), an optional module
472  * request state object to be consumed by return_fn or free_modreq_fn, optional
473  * e_data to be passed to the caller if code is nonzero, and optional
474  * authorization data to be included in the ticket.  In non-FAST replies,
475  * e_data will be encoded as typed-data if the module sets the PA_TYPED_E_DATA
476  * flag, and as pa-data otherwise.  e_data and authz_data will be freed by the
477  * KDC.
478  */
479 typedef void
480 (*krb5_kdcpreauth_verify_respond_fn)(void *arg, krb5_error_code code,
481                                      krb5_kdcpreauth_modreq modreq,
482                                      krb5_pa_data **e_data,
483                                      krb5_authdata **authz_data);
484
485 /*
486  * Optional: verify preauthentication data sent by the client, setting the
487  * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
488  * field as appropriate.  The implementation must invoke the respond function
489  * when complete, whether successful or not, either before returning or
490  * asynchronously using the verto context returned by cb->event_context().
491  */
492 typedef void
493 (*krb5_kdcpreauth_verify_fn)(krb5_context context,
494                              krb5_data *req_pkt, krb5_kdc_req *request,
495                              krb5_enc_tkt_part *enc_tkt_reply,
496                              krb5_pa_data *data,
497                              krb5_kdcpreauth_callbacks cb,
498                              krb5_kdcpreauth_rock rock,
499                              krb5_kdcpreauth_moddata moddata,
500                              krb5_kdcpreauth_verify_respond_fn respond,
501                              void *arg);
502
503 /*
504  * Optional: generate preauthentication response data to send to the client as
505  * part of the AS-REP.  If it needs to override the key which is used to
506  * encrypt the response, it can do so.
507  */
508 typedef krb5_error_code
509 (*krb5_kdcpreauth_return_fn)(krb5_context context,
510                              krb5_pa_data *padata,
511                              krb5_data *req_pkt,
512                              krb5_kdc_req *request,
513                              krb5_kdc_rep *reply,
514                              krb5_keyblock *encrypting_key,
515                              krb5_pa_data **send_pa_out,
516                              krb5_kdcpreauth_callbacks cb,
517                              krb5_kdcpreauth_rock rock,
518                              krb5_kdcpreauth_moddata moddata,
519                              krb5_kdcpreauth_modreq modreq);
520
521 /* Optional: free a per-request context. */
522 typedef void
523 (*krb5_kdcpreauth_free_modreq_fn)(krb5_context,
524                                   krb5_kdcpreauth_moddata moddata,
525                                   krb5_kdcpreauth_modreq modreq);
526
527 typedef struct krb5_kdcpreauth_vtable_st {
528     /* Mandatory: name of module. */
529     char *name;
530
531     /* Mandatory: pointer to zero-terminated list of pa_types which this module
532      * can provide services for. */
533     krb5_preauthtype *pa_type_list;
534
535     krb5_kdcpreauth_init_fn init;
536     krb5_kdcpreauth_fini_fn fini;
537     krb5_kdcpreauth_flags_fn flags;
538     krb5_kdcpreauth_edata_fn edata;
539     krb5_kdcpreauth_verify_fn verify;
540     krb5_kdcpreauth_return_fn return_padata;
541     krb5_kdcpreauth_free_modreq_fn free_modreq;
542 } *krb5_kdcpreauth_vtable;
543
544 #endif /* KRB5_PREAUTH_PLUGIN_H_INCLUDED */