3 * <krb5/preauth_plugin.h>
5 * Copyright (c) 2006 Red Hat, Inc.
6 * Portions copyright (c) 2006 Massachusetts Institute of Technology
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
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
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.
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.
34 * Preauthentication plugin definitions for Kerberos 5.
37 #ifndef KRB5_PREAUTH_PLUGIN_H_INCLUDED
38 #define KRB5_PREAUTH_PLUGIN_H_INCLUDED
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
46 struct _krb5_db_entry_new
;
47 struct _krb5_key_data
;
48 struct _krb5_preauth_client_rock
;
51 * Preauth mechanism property flags, unified from previous definitions in the
52 * KDC and libkrb5 sources.
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
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
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
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
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
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
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) */
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
98 /***************************************************************************
100 * Client-side preauthentication plugin interface definition.
102 ***************************************************************************/
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.
111 typedef krb5_error_code
112 (*preauth_get_as_key_proc
)(krb5_context
,
118 krb5_data
*s2kparams
,
119 krb5_keyblock
*as_key
,
123 * A client module's callback functions are allowed to request various
124 * information to enable it to process a request.
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
133 typedef krb5_error_code
134 (*preauth_get_client_data_proc
)(krb5_context
,
135 struct _krb5_preauth_client_rock
*,
136 krb5_int32 request_type
,
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
);
149 (*preauth_client_plugin_fini_proc
)(krb5_context context
,
150 void *plugin_context
);
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. */
156 (*preauth_client_get_flags_proc
)(krb5_context context
,
157 krb5_preauthtype pa_type
);
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. */
165 (*preauth_client_request_init_proc
)(krb5_context context
,
166 void *plugin_context
,
167 void **request_context
);
169 (*preauth_client_request_fini_proc
)(krb5_context context
,
170 void *plugin_context
,
171 void *request_context
);
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
,
194 preauth_get_as_key_proc gak_fct
,
197 krb5_data
*s2kparams
,
198 krb5_keyblock
*as_key
,
199 krb5_pa_data
***out_pa_data
);
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
,
217 krb5_prompter_fct prompter
,
219 preauth_get_as_key_proc gak_fct
,
222 krb5_data
*s2kparams
,
223 krb5_keyblock
*as_key
,
224 krb5_pa_data
***out_pa_data
);
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.
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
,
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.
244 typedef struct krb5plugin_preauth_client_ftable_v1
{
245 /* Not-usually-visible name. */
248 /* Pointer to zero-terminated list of pa_types which this module can
249 * provide services for. */
250 krb5_preauthtype
*pa_type_list
;
252 /* Pointer to zero-terminated list of enc_types which this module claims
253 * to add support for. */
254 krb5_enctype
*enctype_list
;
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
;
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
;
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
;
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
;
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
;
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.
299 preauth_client_supply_gic_opts_proc gic_opts
;
301 } krb5plugin_preauth_client_ftable_v1
;
304 /***************************************************************************
306 * Server-side preauthentication plugin interface definition.
308 ***************************************************************************/
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.
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
333 typedef krb5_error_code
334 (*preauth_get_entry_data_proc
)(krb5_context
,
336 struct _krb5_db_entry_new
*,
337 krb5_int32 request_type
,
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
);
346 /* Preauth plugin cleanup function */
348 (*preauth_server_fini_proc
)(krb5_context context
, void *plugin_context
);
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. */
358 (*preauth_server_flags_proc
)(krb5_context context
, krb5_preauthtype patype
);
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
,
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
,
385 krb5_kdc_req
*request
,
386 krb5_enc_tkt_part
*enc_tkt_reply
,
388 preauth_get_entry_data_proc
,
389 void *pa_module_context
,
390 void **pa_request_context
,
392 krb5_authdata
***authz_data
);
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
,
404 krb5_kdc_req
*request
,
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
);
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.
416 typedef krb5_error_code
417 (*preauth_server_free_reqcontext_proc
)(krb5_context
,
418 void *pa_module_context
,
419 void **request_pa_context
);
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
429 typedef struct krb5plugin_preauth_server_ftable_v1
{
430 /* Not-usually-visible name. */
433 /* Pointer to zero-terminated list of pa_types which this module can
434 * provide services for. */
435 krb5_preauthtype
*pa_type_list
;
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
;
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
;
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
;
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
;
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
;
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.
478 preauth_server_free_reqcontext_proc freepa_reqcontext_proc
;
480 } krb5plugin_preauth_server_ftable_v1
;
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().
488 * The 'opt' pointer supplied to this function must have been
489 * obtained using krb5_get_init_creds_opt_alloc()
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
);
499 * This function frees the preauth_data that was returned by
500 * krb5_get_init_creds_opt_get_pa().
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
);
508 #endif /* KRB5_PREAUTH_PLUGIN_H_INCLUDED */