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