1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright (c) 2006 Red Hat, Inc.
4 * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
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
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.
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.
34 * Declarations for preauth plugin module implementors.
36 * This header defines two preauth interfaces, clpreauth and kdcpreauth. A
37 * shared object can implement both interfaces or it can implement just one.
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
46 * clpreauth_modname_initvt(krb5_context context, int maj_ver,
47 * int min_ver, krb5_plugin_vtable vtable);
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
55 * kdcpreauth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
56 * krb5_plugin_vtable vtable);
58 * For both interfaces, the initvt function should:
60 * - Check that the supplied maj_ver number is supported by the module, or
61 * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
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
67 * - Initialize the methods of the vtable, stopping as appropriate for the
68 * supplied min_ver. Optional methods may be left uninitialized.
70 * Memory for the vtable is allocated by the caller, not by the module.
73 #ifndef KRB5_PREAUTH_PLUGIN_H_INCLUDED
74 #define KRB5_PREAUTH_PLUGIN_H_INCLUDED
75 #include <krb5/krb5.h>
76 #include <krb5/plugin.h>
79 * Preauth mechanism property flags, unified from previous definitions in the
80 * KDC and libkrb5 sources.
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
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
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).
96 #define PA_HARDWARE 0x00000004
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).
104 #define PA_REQUIRED 0x00000008
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).
112 #define PA_SUFFICIENT 0x00000010
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
121 #define PA_REPLACES_KEY 0x00000020
124 * Not really a padata type, so don't include it in any list of preauth types
125 * which gets sent over the wire.
127 #define PA_PSEUDO 0x00000080
130 * For kdcpreauth mechanisms, indicates that e_data in non-FAST errors should
131 * be encoded as typed data instead of padata.
133 #define PA_TYPED_E_DATA 0x00000100
136 * clpreauth plugin interface definition.
139 /* Abstract type for a client request information handle. */
140 typedef struct krb5_clpreauth_rock_st *krb5_clpreauth_rock;
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;
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 {
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.
157 krb5_enctype (*get_etype)(krb5_context context, krb5_clpreauth_rock rock);
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);
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.
169 krb5_error_code (*get_as_key)(krb5_context context,
170 krb5_clpreauth_rock rock,
171 krb5_keyblock **keyblock);
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);
178 /* End of version 1 clpreauth callbacks. */
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.
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);
196 /* End of version 2 clpreauth callbacks (added in 1.11). */
197 } *krb5_clpreauth_callbacks;
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.
206 typedef krb5_error_code
207 (*krb5_clpreauth_init_fn)(krb5_context context,
208 krb5_clpreauth_moddata *moddata_out);
210 (*krb5_clpreauth_fini_fn)(krb5_context context,
211 krb5_clpreauth_moddata moddata);
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.
219 (*krb5_clpreauth_get_flags_fn)(krb5_context context, krb5_preauthtype pa_type);
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
229 (*krb5_clpreauth_request_init_fn)(krb5_context context,
230 krb5_clpreauth_moddata moddata,
231 krb5_clpreauth_modreq *modreq_out);
233 (*krb5_clpreauth_request_fini_fn)(krb5_context context,
234 krb5_clpreauth_moddata moddata,
235 krb5_clpreauth_modreq modreq);
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.
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.
245 * encoded_previous_request may be NULL if there has been no previous request
246 * in the AS exchange.
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);
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
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.
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,
284 krb5_pa_data **error_padata,
285 krb5_prompter_fct prompter, void *prompter_data,
286 krb5_pa_data ***pa_data_out);
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.
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);
299 typedef struct krb5_clpreauth_vtable_st {
300 /* Mandatory: name of module. */
303 /* Mandatory: pointer to zero-terminated list of pa_types which this module
304 * can provide services for. */
305 krb5_preauthtype *pa_type_list;
307 /* Optional: pointer to zero-terminated list of enc_types which this module
308 * claims to add support for. */
309 krb5_enctype *enctype_list;
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;
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().
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);
334 * This function frees the preauth_data that was returned by
335 * krb5_get_init_creds_opt_get_pa().
338 krb5_get_init_creds_opt_free_pa(krb5_context context,
339 int num_preauth_data,
340 krb5_gic_opt_pa_data *preauth_data);
344 * kdcpreauth plugin interface definition.
347 /* Abstract type for a KDC callback data handle. */
348 typedef struct krb5_kdcpreauth_rock_st *krb5_kdcpreauth_rock;
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;
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;
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 {
363 krb5_deltat (*max_time_skew)(krb5_context context,
364 krb5_kdcpreauth_rock rock);
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.
372 krb5_error_code (*client_keys)(krb5_context context,
373 krb5_kdcpreauth_rock rock,
374 krb5_keyblock **keys_out);
376 /* Free the result of client_keys. */
377 void (*free_keys)(krb5_context context, krb5_kdcpreauth_rock rock,
378 krb5_keyblock *keys);
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.
385 krb5_data *(*request_body)(krb5_context context,
386 krb5_kdcpreauth_rock rock);
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);
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,
399 /* Free the result of get_string. */
400 void (*free_string)(krb5_context context, krb5_kdcpreauth_rock rock,
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);
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);
412 /* End of version 1 kdcpreauth callbacks. */
413 } *krb5_kdcpreauth_callbacks;
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);
421 /* Optional: preauth plugin cleanup function. */
423 (*krb5_kdcpreauth_fini_fn)(krb5_context context,
424 krb5_kdcpreauth_moddata moddata);
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.
436 (*krb5_kdcpreauth_flags_fn)(krb5_context context, krb5_preauthtype pa_type);
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
447 (*krb5_kdcpreauth_edata_respond_fn)(void *arg, krb5_error_code code,
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().
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.
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,
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
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);
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().
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,
497 krb5_kdcpreauth_callbacks cb,
498 krb5_kdcpreauth_rock rock,
499 krb5_kdcpreauth_moddata moddata,
500 krb5_kdcpreauth_verify_respond_fn respond,
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.
508 typedef krb5_error_code
509 (*krb5_kdcpreauth_return_fn)(krb5_context context,
510 krb5_pa_data *padata,
512 krb5_kdc_req *request,
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);
521 /* Optional: free a per-request context. */
523 (*krb5_kdcpreauth_free_modreq_fn)(krb5_context,
524 krb5_kdcpreauth_moddata moddata,
525 krb5_kdcpreauth_modreq modreq);
527 typedef struct krb5_kdcpreauth_vtable_st {
528 /* Mandatory: name of module. */
531 /* Mandatory: pointer to zero-terminated list of pa_types which this module
532 * can provide services for. */
533 krb5_preauthtype *pa_type_list;
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;
544 #endif /* KRB5_PREAUTH_PLUGIN_H_INCLUDED */