krb5 commit: Get rid of static KDC authdata systems
Greg Hudson
ghudson at mit.edu
Mon Jun 15 12:56:00 EDT 2015
https://github.com/krb5/krb5/commit/c96fe6c87a69122e6b699385f52a959d375ca4bb
commit c96fe6c87a69122e6b699385f52a959d375ca4bb
Author: Greg Hudson <ghudson at mit.edu>
Date: Tue Sep 23 12:36:20 2014 -0400
Get rid of static KDC authdata systems
Remove the static_authdata_systems table from kdc_authdata.c and
instead call the relevant functions explicitly in handle_authdata.
Eliminate the flags field from krb5_authdata_systems as it is no
longer used. Rename the functions to be more descriptive. Move
simple conditionals on authdata processing to handle_authdata for
clarity. Move handle_authdata to the end of the file to avoid the
need for static function declarations.
src/kdc/kdc_authdata.c | 383 ++++++++++++++++--------------------------------
1 files changed, 123 insertions(+), 260 deletions(-)
diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
index e70a27b..410a57a 100644
--- a/src/kdc/kdc_authdata.c
+++ b/src/kdc/kdc_authdata.c
@@ -66,67 +66,12 @@ typedef krb5_error_code (*authdata_proc_2)(
typedef krb5_error_code (*init_proc)(krb5_context, void **);
typedef void (*fini_proc)(krb5_context, void *);
-static krb5_error_code handle_request_authdata(
- krb5_context context,
- unsigned int flags,
- 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_data *req_pkt,
- krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply);
-
-static krb5_error_code handle_tgt_authdata(
- krb5_context context,
- unsigned int flags,
- 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_data *req_pkt,
- krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply);
-
-static krb5_error_code
-handle_kdb_authdata(krb5_context context, unsigned int flags,
- 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_data *req_pkt, krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply);
-
-static krb5_error_code
-handle_signedpath_authdata(krb5_context context, unsigned int flags,
- 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_data *req_pkt, krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply);
-
typedef struct _krb5_authdata_systems {
const char *name;
#define AUTHDATA_SYSTEM_UNKNOWN -1
#define AUTHDATA_SYSTEM_V0 0
#define AUTHDATA_SYSTEM_V2 2
int type;
-#define AUTHDATA_FLAG_CRITICAL 0x1
-#define AUTHDATA_FLAG_PRE_PLUGIN 0x2
-#define AUTHDATA_FLAG_ANONYMOUS 0x4 /* Use plugin even for anonymous tickets */
- int flags;
void *plugin_context;
init_proc init;
fini_proc fini;
@@ -136,50 +81,6 @@ typedef struct _krb5_authdata_systems {
} handle_authdata;
} krb5_authdata_systems;
-static krb5_authdata_systems static_authdata_systems[] = {
- {
- /* Propagate client-submitted authdata */
- "tgs_req",
- AUTHDATA_SYSTEM_V2,
- AUTHDATA_FLAG_CRITICAL | AUTHDATA_FLAG_PRE_PLUGIN |
- AUTHDATA_FLAG_ANONYMOUS,
- NULL,
- NULL,
- NULL,
- { handle_request_authdata }
- },
- {
- /* Propagate TGT authdata */
- "tgt",
- AUTHDATA_SYSTEM_V2,
- AUTHDATA_FLAG_CRITICAL | AUTHDATA_FLAG_ANONYMOUS,
- NULL,
- NULL,
- NULL,
- { handle_tgt_authdata }
- },
- {
- /* Verify and issue KDB issued authdata */
- "kdb",
- AUTHDATA_SYSTEM_V2,
- AUTHDATA_FLAG_CRITICAL,
- NULL,
- NULL,
- NULL,
- { handle_kdb_authdata }
- },
- {
- /* Verify and issue signed delegation path */
- "signedpath",
- AUTHDATA_SYSTEM_V2,
- AUTHDATA_FLAG_CRITICAL,
- NULL,
- NULL,
- NULL,
- { handle_signedpath_authdata }
- }
-};
-
static krb5_authdata_systems *authdata_systems;
static int n_authdata_systems;
static struct plugin_dir_handle authdata_plugins;
@@ -244,9 +145,6 @@ load_authdata_plugins(krb5_context context)
}
}
- module_count += sizeof(static_authdata_systems)
- / sizeof(static_authdata_systems[0]);
-
/* Build the complete list of supported authdata options, and
* leave room for a terminator entry.
*/
@@ -258,19 +156,6 @@ load_authdata_plugins(krb5_context context)
k = 0;
- /*
- * Special case to ensure that handle_request_authdata is
- * first in the list, to make unenc_authdata available to
- * plugins.
- */
- for (i = 0; i < (sizeof(static_authdata_systems) /
- sizeof(static_authdata_systems[0])); i++) {
- if ((static_authdata_systems[i].flags & AUTHDATA_FLAG_PRE_PLUGIN) == 0)
- continue;
- assert(static_authdata_systems[i].init == NULL);
- authdata_systems[k++] = static_authdata_systems[i];
- }
-
/* Add dynamically loaded V2 plugins */
if (authdata_plugins_ftables_v2 != NULL) {
struct krb5plugin_authdata_server_ftable_v2 *ftable;
@@ -343,15 +228,6 @@ load_authdata_plugins(krb5_context context)
}
}
- for (i = 0;
- i < sizeof(static_authdata_systems) / sizeof(static_authdata_systems[0]);
- i++) {
- if (static_authdata_systems[i].flags & AUTHDATA_FLAG_PRE_PLUGIN)
- continue;
- assert(static_authdata_systems[i].init == NULL);
- authdata_systems[k++] = static_authdata_systems[i];
- }
-
n_authdata_systems = k;
/* Add the end-of-list marker. */
authdata_systems[k].name = "[end]";
@@ -539,29 +415,16 @@ merge_authdata (krb5_context context,
return 0;
}
-/* Handle copying TGS-REQ authorization data into reply */
+/* Copy TGS-REQ authorization data into the ticket authdata. */
static krb5_error_code
-handle_request_authdata (krb5_context context,
- unsigned int flags,
- 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_data *req_pkt,
- krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply)
+copy_request_authdata(krb5_context context, krb5_keyblock *client_key,
+ krb5_kdc_req *request,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_authdata ***tkt_authdata)
{
krb5_error_code code;
krb5_data scratch;
- if (request->msg_type != KRB5_TGS_REQ ||
- request->authorization_data.ciphertext.data == NULL)
- return 0;
-
assert(enc_tkt_request != NULL);
scratch.length = request->authorization_data.ciphertext.length;
@@ -613,58 +476,37 @@ handle_request_authdata (krb5_context context,
code = merge_authdata(context,
request->unenc_authdata,
- &enc_tkt_reply->authorization_data,
+ tkt_authdata,
TRUE, /* copy */
TRUE); /* ignore_kdc_issued */
return code;
}
-/* Handle copying TGT authorization data into reply */
+/* Copy TGT authorization data into the ticket authdata. */
static krb5_error_code
-handle_tgt_authdata (krb5_context context,
- unsigned int flags,
- 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_data *req_pkt,
- krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply)
+copy_tgt_authdata(krb5_context context, krb5_kdc_req *request,
+ krb5_authdata **tgt_authdata, krb5_authdata ***tkt_authdata)
{
- if (request->msg_type != KRB5_TGS_REQ)
- return 0;
-
- if (has_mandatory_for_kdc_authdata(context,
- enc_tkt_request->authorization_data))
+ if (has_mandatory_for_kdc_authdata(context, tgt_authdata))
return KRB5KDC_ERR_POLICY;
return merge_authdata(context,
- enc_tkt_request->authorization_data,
- &enc_tkt_reply->authorization_data,
+ tgt_authdata,
+ tkt_authdata,
TRUE, /* copy */
TRUE); /* ignore_kdc_issued */
}
-/* Handle backend-managed authorization data */
+/* Fetch authorization data from KDB module. */
static krb5_error_code
-handle_kdb_authdata (krb5_context context,
- unsigned int flags,
- 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_data *req_pkt,
- krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply)
+fetch_kdb_authdata(krb5_context context, unsigned int flags,
+ 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_kdc_req *request, krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_enc_tkt_part *enc_tkt_reply)
{
krb5_error_code code;
krb5_authdata **tgt_authdata, **db_authdata = NULL;
@@ -727,67 +569,6 @@ handle_kdb_authdata (krb5_context context,
return code;
}
-krb5_error_code
-handle_authdata (krb5_context context,
- unsigned int flags,
- 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_data *req_pkt,
- krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply)
-{
- krb5_error_code code = 0;
- int i;
-
- for (i = 0; i < n_authdata_systems; i++) {
- const krb5_authdata_systems *asys = &authdata_systems[i];
- if (isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS) &&
- !isflagset(asys->flags, AUTHDATA_FLAG_ANONYMOUS))
- continue;
-
- switch (asys->type) {
- case AUTHDATA_SYSTEM_V0:
- /* V0 was only in AS-REQ code path */
- if (request->msg_type != KRB5_AS_REQ)
- continue;
-
- code = (*asys->handle_authdata.v0)(context, client, req_pkt,
- request, enc_tkt_reply);
- break;
- case AUTHDATA_SYSTEM_V2:
- code = (*asys->handle_authdata.v2)(context, flags,
- client, server, krbtgt,
- client_key, server_key, krbtgt_key,
- req_pkt, request, for_user_princ,
- enc_tkt_request,
- enc_tkt_reply);
- break;
- default:
- code = 0;
- break;
- }
- if (code != 0) {
- const char *emsg;
-
- emsg = krb5_get_error_message (context, code);
- krb5_klog_syslog(LOG_INFO, _("authdata (%s) handling failure: %s"),
- asys->name, emsg);
- krb5_free_error_message (context, emsg);
-
- if (asys->flags & AUTHDATA_FLAG_CRITICAL)
- break;
- }
- }
-
- return code;
-}
-
static krb5_error_code
make_ad_signedpath_data(krb5_context context,
krb5_const_principal client,
@@ -842,7 +623,6 @@ make_ad_signedpath_data(krb5_context context,
static krb5_error_code
verify_ad_signedpath_checksum(krb5_context context,
- const krb5_db_entry *krbtgt,
krb5_keyblock *krbtgt_key,
krb5_enc_tkt_part *enc_tkt_part,
krb5_principal *deleg_path,
@@ -882,7 +662,6 @@ verify_ad_signedpath_checksum(krb5_context context,
static krb5_error_code
verify_ad_signedpath(krb5_context context,
- krb5_db_entry *krbtgt,
krb5_keyblock *krbtgt_key,
krb5_enc_tkt_part *enc_tkt_part,
krb5_principal **pdelegated,
@@ -918,7 +697,6 @@ verify_ad_signedpath(krb5_context context,
}
code = verify_ad_signedpath_checksum(context,
- krbtgt,
krbtgt_key,
enc_tkt_part,
sp->delegated,
@@ -943,7 +721,6 @@ cleanup:
static krb5_error_code
make_ad_signedpath_checksum(krb5_context context,
krb5_const_principal for_user_princ,
- const krb5_db_entry *krbtgt,
krb5_keyblock *krbtgt_key,
krb5_enc_tkt_part *enc_tkt_part,
krb5_principal *deleg_path,
@@ -996,7 +773,6 @@ static krb5_error_code
make_ad_signedpath(krb5_context context,
krb5_const_principal for_user_princ,
krb5_principal server,
- const krb5_db_entry *krbtgt,
krb5_keyblock *krbtgt_key,
krb5_principal *deleg_path,
krb5_enc_tkt_part *enc_tkt_reply)
@@ -1033,7 +809,6 @@ make_ad_signedpath(krb5_context context,
code = make_ad_signedpath_checksum(context,
for_user_princ,
- krbtgt,
krbtgt_key,
enc_tkt_reply,
sp.delegated,
@@ -1114,20 +889,15 @@ only_pac_p(krb5_context context, krb5_authdata **authdata)
(authdata[1] == NULL);
}
+/* Verify AD-SIGNTICKET authdata if we need to, and insert an AD-SIGNEDPATH
+ * element if we should. */
static krb5_error_code
-handle_signedpath_authdata (krb5_context context,
- unsigned int flags,
- 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_data *req_pkt,
- krb5_kdc_req *request,
- krb5_const_principal for_user_princ,
- krb5_enc_tkt_part *enc_tkt_request,
- krb5_enc_tkt_part *enc_tkt_reply)
+handle_signticket(krb5_context context, unsigned int flags,
+ krb5_db_entry *client, krb5_db_entry *server,
+ krb5_keyblock *krbtgt_key, krb5_kdc_req *request,
+ krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_enc_tkt_part *enc_tkt_reply)
{
krb5_error_code code = 0;
krb5_principal *deleg_path = NULL;
@@ -1143,7 +913,6 @@ handle_signedpath_authdata (krb5_context context,
if (request->msg_type == KRB5_TGS_REQ &&
!only_pac_p(context, enc_tkt_request->authorization_data)) {
code = verify_ad_signedpath(context,
- krbtgt,
krbtgt_key,
enc_tkt_request,
&deleg_path,
@@ -1165,7 +934,6 @@ handle_signedpath_authdata (krb5_context context,
code = make_ad_signedpath(context,
for_user_princ,
s4u2proxy ? client->princ : NULL,
- krbtgt,
krbtgt_key,
deleg_path,
enc_tkt_reply);
@@ -1178,3 +946,98 @@ cleanup:
return code;
}
+
+krb5_error_code
+handle_authdata (krb5_context context,
+ unsigned int flags,
+ 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_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_const_principal for_user_princ,
+ krb5_enc_tkt_part *enc_tkt_request,
+ krb5_enc_tkt_part *enc_tkt_reply)
+{
+ krb5_error_code code = 0;
+ int i;
+
+ if (request->msg_type == KRB5_TGS_REQ &&
+ request->authorization_data.ciphertext.data != NULL) {
+ /* Copy TGS request authdata. This must be done first so that modules
+ * have access to the unencrypted request authdata. */
+ code = copy_request_authdata(context, client_key, request,
+ enc_tkt_request,
+ &enc_tkt_reply->authorization_data);
+ if (code)
+ return code;
+ }
+
+ for (i = 0; i < n_authdata_systems; i++) {
+ const krb5_authdata_systems *asys = &authdata_systems[i];
+ if (isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS))
+ continue;
+
+ switch (asys->type) {
+ case AUTHDATA_SYSTEM_V0:
+ /* V0 was only in AS-REQ code path */
+ if (request->msg_type != KRB5_AS_REQ)
+ continue;
+
+ code = (*asys->handle_authdata.v0)(context, client, req_pkt,
+ request, enc_tkt_reply);
+ break;
+ case AUTHDATA_SYSTEM_V2:
+ code = (*asys->handle_authdata.v2)(context, flags,
+ client, server, krbtgt,
+ client_key, server_key, krbtgt_key,
+ req_pkt, request, for_user_princ,
+ enc_tkt_request,
+ enc_tkt_reply);
+ break;
+ default:
+ code = 0;
+ break;
+ }
+ if (code != 0) {
+ const char *emsg;
+
+ emsg = krb5_get_error_message (context, code);
+ krb5_klog_syslog(LOG_INFO, _("authdata (%s) handling failure: %s"),
+ asys->name, emsg);
+ krb5_free_error_message (context, emsg);
+ }
+ }
+
+ if (request->msg_type == KRB5_TGS_REQ) {
+ /* Copy authdata from the TGT to the issued ticket. */
+ code = copy_tgt_authdata(context, request,
+ enc_tkt_request->authorization_data,
+ &enc_tkt_reply->authorization_data);
+ if (code)
+ return code;
+ }
+
+ if (!isflagset(enc_tkt_reply->flags, TKT_FLG_ANONYMOUS)) {
+ /* Fetch authdata from the KDB if appropriate. */
+ code = fetch_kdb_authdata(context, flags, client, server, krbtgt,
+ client_key, server_key, krbtgt_key, request,
+ for_user_princ, enc_tkt_request,
+ enc_tkt_reply);
+ if (code)
+ return code;
+
+ /* Validate and insert AD-SIGNTICKET authdata. This must happen last
+ * since it contains a signature over the other authdata. */
+ code = handle_signticket(context, flags, client, server, krbtgt_key,
+ request, for_user_princ, enc_tkt_request,
+ enc_tkt_reply);
+ if (code)
+ return code;
+ }
+
+ return 0;
+}
More information about the cvs-krb5
mailing list