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