From 62880787886fadd5dfb8f350779369795319fa21 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Mon, 12 Jul 2010 18:33:05 +0000 Subject: [PATCH] Add sign_authdata to the DAL table with a corresponding libkdb5 API, replacing the SIGN_AUTH_DATA method of db_invoke. ticket: 6749 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24182 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/kdb.h | 109 ++++++++++++++++++++++---------- src/kdc/kdc_authdata.c | 21 ++---- src/kdc/kdc_util.c | 54 ---------------- src/kdc/kdc_util.h | 15 ----- src/lib/kdb/kdb5.c | 24 +++++++ src/lib/kdb/libkdb5.exports | 1 + src/plugins/kdb/db2/db2_exp.c | 2 +- src/plugins/kdb/ldap/ldap_exp.c | 1 + 8 files changed, 111 insertions(+), 116 deletions(-) diff --git a/src/include/kdb.h b/src/include/kdb.h index 49d77aa49..3012b028f 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -323,7 +323,6 @@ extern char *krb5_mkey_pwd_prompt2; #define KRB5_DB_LOCKMODE_PERMANENT 0x0008 /* db_invoke methods */ -#define KRB5_KDB_METHOD_SIGN_AUTH_DATA 0x00000010 #define KRB5_KDB_METHOD_CHECK_TRANSITED_REALMS 0x00000020 #define KRB5_KDB_METHOD_CHECK_POLICY_AS 0x00000030 #define KRB5_KDB_METHOD_CHECK_POLICY_TGS 0x00000040 @@ -332,26 +331,6 @@ extern char *krb5_mkey_pwd_prompt2; #define KRB5_KDB_METHOD_REFRESH_POLICY 0x00000070 #define KRB5_KDB_METHOD_CHECK_ALLOWED_TO_DELEGATE 0x00000080 -typedef struct _kdb_sign_auth_data_req { - krb5_magic magic; - unsigned int flags; /* KRB5_KDB flags */ - krb5_const_principal client_princ; /* Client name used in ticket */ - krb5_db_entry *client; /* DB entry for client principal */ - krb5_db_entry *server; /* DB entry for server principal */ - krb5_db_entry *krbtgt; /* DB entry for ticket granting service principal */ - krb5_keyblock *client_key; /* Reply key, valid for AS-REQ only */ - krb5_keyblock *server_key; /* Key used to generate server signature */ - krb5_timestamp authtime; /* Authtime of TGT */ - krb5_authdata **auth_data; /* Authorization data from TGT */ - krb5_keyblock *session_key; /* Reply session key */ - krb5_keyblock *krbtgt_key; /* Key used to decrypt TGT, valid for TGS-REQ only */ -} kdb_sign_auth_data_req; - -typedef struct _kdb_sign_auth_data_rep { - krb5_magic magic; - krb5_authdata **auth_data; /* Signed authorization data */ -} kdb_sign_auth_data_rep; - typedef struct _kdb_check_transited_realms_req { krb5_magic magic; const krb5_data *tr_contents; @@ -659,12 +638,25 @@ krb5_db_get_key_data_kvno( krb5_context context, int count, krb5_key_data * data); +krb5_error_code krb5_db_sign_authdata(krb5_context kcontext, + unsigned int flags, + krb5_const_principal client_princ, + krb5_db_entry *client, + krb5_db_entry *server, + krb5_db_entry *krbtgt, + krb5_keyblock *client_key, + krb5_keyblock *server_key, + krb5_keyblock *krbtgt_key, + krb5_keyblock *session_key, + krb5_timestamp authtime, + krb5_authdata **tgt_auth_data, + krb5_authdata ***signed_auth_data); + krb5_error_code krb5_db_invoke ( krb5_context kcontext, unsigned int method, const krb5_data *req, krb5_data *rep ); - /* default functions. Should not be directly called */ /* * Default functions prototype @@ -796,7 +788,7 @@ krb5_dbe_free_tl_data(krb5_context, krb5_tl_data *); * DAL. It is passed to init_library to allow KDB modules to detect when * they are being loaded by an incompatible version of the KDC. */ -#define KRB5_KDB_DAL_VERSION 20100702 +#define KRB5_KDB_DAL_VERSION 20100712 /* * A krb5_context can hold one database object. Modules should use @@ -1201,20 +1193,73 @@ typedef struct _kdb_vftabl { const krb5_keysalt *keysalt, int keyver, krb5_key_data *key_data); + /* + * Optional: Generate signed authorization data, such as a Windows PAC, for + * the ticket to be returned to the client. Place the signed authorization + * data, if any, in *signed_auth_data. This function will be invoked for + * an AS request if the client included padata requesting a PAC. This + * function will be invoked for a TGS request if there is authorization + * data in the TGT, if the client is from another realm, or if the TGS + * request is an S4U2Self or S4U2Proxy request. This function will not be + * invoked during TGS requests if the server principal has the + * no_auth_data_required attribute set. Input parameters are: + * + * flags: The flags used to look up the client principal. + * + * client_princ: For S4U2Proxy TGS requests, the client principal + * requested by the service; for regular TGS requests, the + * possibly-canonicalized client principal. + * + * client: The DB entry of the client. For S4U2Self, this will be the DB + * entry for the client principal requested by the service). + * + * server: The DB entry of the service principal. + * + * krbtgt: For TGS requests, the DB entry of the (possibly foreign) + * ticket granting service of the TGT. For AS requests, the DB entry + * of the service principal. + * + * client_key: The reply key for the KDC request, before any FAST armor + * is applied. For AS requests, this may be the client's long-term key + * or a key chosen by a preauth mechanism. For TGS requests, this may + * be the subkey found in the AP-REQ or the session key of the TGT. + * + * server_key: The server key used to encrypt the returned ticket. + * + * krbtgt_key: For TGS requests, the key of the (possibly foreign) ticket + * granting service of the TGT. for AS requests, the service + * principal's key. + * + * session_key: The session key of the ticket being granted to the + * requestor. + * + * authtime: The timestamp of the original client authentication time. + * For AS requests, this is the current time. For TGS requests, this + * is the authtime of the subject ticket (TGT or S4U2Proxy evidence + * ticket). + * + * tgt_auth_data: For TGS requests, the authorization data present in the + * subject ticket. For AS requests, NULL. + */ + krb5_error_code (*sign_authdata)(krb5_context kcontext, + unsigned int flags, + krb5_const_principal client_princ, + krb5_db_entry *client, + krb5_db_entry *server, + krb5_db_entry *krbtgt, + krb5_keyblock *client_key, + krb5_keyblock *server_key, + krb5_keyblock *krbtgt_key, + krb5_keyblock *session_key, + krb5_timestamp authtime, + krb5_authdata **tgt_auth_data, + krb5_authdata ***signed_auth_data); + /* * Optional: Perform an operation on input data req with output stored in * rep. Return KRB5_PLUGIN_OP_NOTSUPP if the module does not implement the * method. Defined methods are: * - * KRB5_KDB_METHOD_SIGN_AUTH_DATA: req contains a krb5_sign_auth_data_req - * structure. Generate signed authorization data, such as a Windows - * PAC, for the ticket to be returned to the client. Place the signed - * authorization data in rep using a krb5_sign_auth_data_rep structure. - * This function will be invoked for an AS request if the client - * included padata requesting a PAC. This function will be invoked for - * a TGS request if there is authorization data in the TGT, if the - * client is from another realm, or if the TGS request is an S4U2Self - * or S4U2Proxy request. * * KRB5_KDB_METHOD_CHECK_TRANSITED_REALMS: req contains a * kdb_check_transited_realms_req structure. Perform a policy check on diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c index 90deae5b5..f46fa15fc 100644 --- a/src/kdc/kdc_authdata.c +++ b/src/kdc/kdc_authdata.c @@ -680,7 +680,7 @@ handle_kdb_authdata (krb5_context context, krb5_enc_tkt_part *enc_tkt_reply) { krb5_error_code code; - krb5_authdata **db_authdata = NULL; + krb5_authdata **tgt_authdata, **db_authdata = NULL; krb5_boolean tgs_req = (request->msg_type == KRB5_TGS_REQ); krb5_const_principal actual_client; @@ -720,19 +720,12 @@ handle_kdb_authdata (krb5_context context, else actual_client = enc_tkt_reply->client; - code = sign_db_authdata(context, - flags, - actual_client, - client, - server, - krbtgt, - client_key, - server_key, /* U2U or server key */ - krbtgt_key, - enc_tkt_reply->times.authtime, - tgs_req ? enc_tkt_request->authorization_data : NULL, - enc_tkt_reply->session, - &db_authdata); + tgt_authdata = tgs_req ? enc_tkt_request->authorization_data : NULL; + code = krb5_db_sign_authdata(context, flags, actual_client, client, + server, krbtgt, client_key, server_key, + krbtgt_key, enc_tkt_reply->session, + enc_tkt_reply->times.authtime, tgt_authdata, + &db_authdata); if (code == 0) { code = merge_authdata(context, db_authdata, diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index 3d03ca3ed..7bc097ebf 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -1720,60 +1720,6 @@ rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep) return; } -krb5_error_code -sign_db_authdata (krb5_context context, - unsigned int flags, - krb5_const_principal client_princ, - krb5_db_entry *client, - krb5_db_entry *server, - krb5_db_entry *krbtgt, - krb5_keyblock *client_key, - krb5_keyblock *server_key, - krb5_keyblock *krbtgt_key, - krb5_timestamp authtime, - krb5_authdata **tgs_authdata, - krb5_keyblock *session_key, - krb5_authdata ***ret_authdata) -{ - krb5_error_code code; - kdb_sign_auth_data_req req; - kdb_sign_auth_data_rep rep; - krb5_data req_data; - krb5_data rep_data; - - *ret_authdata = NULL; - - memset(&req, 0, sizeof(req)); - memset(&rep, 0, sizeof(rep)); - - req.flags = flags; - req.client_princ = client_princ; - req.client = client; - req.server = server; - req.krbtgt = krbtgt; - req.client_key = client_key; - req.server_key = server_key; - req.authtime = authtime; - req.auth_data = tgs_authdata; - req.session_key = session_key; - req.krbtgt_key = krbtgt_key; - - req_data.data = (void *)&req; - req_data.length = sizeof(req); - - rep_data.data = (void *)&rep; - rep_data.length = sizeof(rep); - - code = krb5_db_invoke(context, - KRB5_KDB_METHOD_SIGN_AUTH_DATA, - &req_data, - &rep_data); - - *ret_authdata = rep.auth_data; - - return code; -} - static krb5_error_code verify_for_user_checksum(krb5_context context, krb5_keyblock *key, diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index a1bde886c..e969c9db4 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -245,21 +245,6 @@ return_enc_padata(krb5_context context, krb5_enc_kdc_rep_part *reply_encpart, krb5_boolean is_referral); -krb5_error_code -sign_db_authdata (krb5_context context, - unsigned int flags, - krb5_const_principal client_princ, - krb5_db_entry *client, - krb5_db_entry *server, - krb5_db_entry *krbtgt, - krb5_keyblock *client_key, - krb5_keyblock *server_key, - krb5_keyblock *krbtgt_key, - krb5_timestamp authtime, - krb5_authdata **tgs_authdata, - krb5_keyblock *session_key, - krb5_authdata ***ret_authdata); - krb5_error_code kdc_process_s4u2self_req (krb5_context context, krb5_kdc_req *request, diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index af81d37bf..882e98cfc 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -2222,6 +2222,30 @@ krb5_db_set_context(krb5_context context, void *db_context) return 0; } +krb5_error_code +krb5_db_sign_authdata(krb5_context kcontext, unsigned int flags, + krb5_const_principal client_princ, krb5_db_entry *client, + krb5_db_entry *server, krb5_db_entry *krbtgt, + krb5_keyblock *client_key, krb5_keyblock *server_key, + krb5_keyblock *krbtgt_key, krb5_keyblock *session_key, + krb5_timestamp authtime, krb5_authdata **tgt_auth_data, + krb5_authdata ***signed_auth_data) +{ + krb5_error_code status = 0; + kdb_vftabl *v; + + *signed_auth_data = NULL; + status = get_vftabl(kcontext, &v); + if (status) + return status; + if (v->sign_authdata == NULL) + return KRB5_PLUGIN_OP_NOTSUPP; + return v->sign_authdata(kcontext, flags, client_princ, client, server, + krbtgt, client_key, server_key, krbtgt_key, + session_key, authtime, tgt_auth_data, + signed_auth_data); +} + krb5_error_code krb5_db_invoke(krb5_context kcontext, unsigned int method, diff --git a/src/lib/kdb/libkdb5.exports b/src/lib/kdb/libkdb5.exports index 4719a6431..4f0eca753 100644 --- a/src/lib/kdb/libkdb5.exports +++ b/src/lib/kdb/libkdb5.exports @@ -23,6 +23,7 @@ krb5_db_put_principal krb5_db_set_context krb5_db_set_mkey_list krb5_db_setup_mkey_name +krb5_db_sign_authdata krb5_db_unlock krb5_db_store_master_key krb5_db_store_master_key_list diff --git a/src/plugins/kdb/db2/db2_exp.c b/src/plugins/kdb/db2/db2_exp.c index fe4f6e96d..26e1fd93d 100644 --- a/src/plugins/kdb/db2/db2_exp.c +++ b/src/plugins/kdb/db2/db2_exp.c @@ -242,6 +242,6 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_db2, kdb_function_table) = { /* get_master_key_list */ wrap_krb5_db2_get_mkey_list, /* blah blah blah */ 0,0,0,0,0, /* promote_db */ wrap_krb5_db2_promote_db, - 0, 0, + 0, 0, 0, /* invoke */ wrap_krb5_db2_invoke }; diff --git a/src/plugins/kdb/ldap/ldap_exp.c b/src/plugins/kdb/ldap/ldap_exp.c index a6a6830b6..9facefb90 100644 --- a/src/plugins/kdb/ldap/ldap_exp.c +++ b/src/plugins/kdb/ldap/ldap_exp.c @@ -82,6 +82,7 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_ldap, kdb_function_table) = { /* promote_db */ NULL, /* decrypt_key_data */ NULL, /* encrypt_key_data */ NULL, + /* sign_authdata */ NULL, /* invoke */ krb5_ldap_invoke, }; -- 2.26.2