From: Greg Hudson Date: Sat, 1 Jun 2019 17:37:14 +0000 (-0400) Subject: Simplify and modernize replay cache interface X-Git-Tag: krb5-1.18-beta1~113 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcb853ac32779b173f39e19c0f24b0087de85771;p=thirdparty%2Fkrb5.git Simplify and modernize replay cache interface Remove all of the replay cache methods except for resolve, close, and store. Rename the dispatch functions to use a k5_ prefix to indicate that they are not part of the libkrb5 API. Remove the unused code for registering replay cache types at runtime. Remove the krb5_donot_replay structure, as the only concrete replay cache type just needs the authenticator checksum. Identify the checksum part of the authenticator ciphertext at the dispatch layer. Handle container allocation at the dispatch layer so that each replay cache type only needs to work with its data pointer. Remember the full name at the dispatch layer to implement a get_name operation. Consolidate what remains of rcfns.c and rc_conv.c into rc_base.c. Use k5_rc_default() in preference to krb5_get_server_rcache() since they now do the same thing. Remove the sim_client code to create a replay cache, as the per-message functions use a memory reply cache now. --- diff --git a/src/appl/simple/client/sim_client.c b/src/appl/simple/client/sim_client.c index cda7d220c4..08f06abe59 100644 --- a/src/appl/simple/client/sim_client.c +++ b/src/appl/simple/client/sim_client.c @@ -86,8 +86,6 @@ main(int argc, char *argv[]) krb5_data packet, inbuf; krb5_ccache ccdef; krb5_address addr, *portlocal_addr; - krb5_rcache rcache; - krb5_data rcache_name; krb5_context context; krb5_auth_context auth_context = NULL; @@ -267,17 +265,6 @@ main(int argc, char *argv[]) exit(1); } - rcache_name.length = strlen(cp); - rcache_name.data = cp; - - if ((retval = krb5_get_server_rcache(context, &rcache_name, &rcache))) { - com_err(progname, retval, "while getting server rcache"); - exit(1); - } - - /* set auth_context rcache */ - krb5_auth_con_setrcache(context, auth_context, rcache); - /* Make the safe message */ inbuf.data = message; inbuf.length = strlen(message); @@ -310,12 +297,6 @@ main(int argc, char *argv[]) printf("Sent encrypted message: %d bytes\n", i); krb5_free_data_contents(context, &packet); - retval = krb5_rc_destroy(context, rcache); - if (retval) { - com_err(progname, retval, "while deleting replay cache"); - exit(1); - } - krb5_auth_con_setrcache(context, auth_context, NULL); krb5_auth_con_free(context, auth_context); krb5_free_context(context); diff --git a/src/include/k5-int.h b/src/include/k5-int.h index a2faa9d9ad..7833d9987b 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -1960,32 +1960,16 @@ typedef struct _krb5int_access { krb5_error_code KRB5_CALLCONV krb5int_accessor(krb5int_access*, krb5_int32); -typedef struct _krb5_donot_replay { - krb5_magic magic; - krb5_ui_4 hash; - char *server; /* null-terminated */ - char *client; /* null-terminated */ - char *msghash; /* null-terminated */ - krb5_data tag; - krb5_int32 cusec; - krb5_timestamp ctime; -} krb5_donot_replay; - krb5_error_code KRB5_CALLCONV krb5int_cc_user_set_default_name(krb5_context context, const char *name); -krb5_error_code krb5_rc_default(krb5_context, krb5_rcache *); -krb5_error_code krb5_rc_resolve_type(krb5_context, krb5_rcache *, - const char *); -krb5_error_code krb5_rc_resolve_full(krb5_context, krb5_rcache *, - const char *); -char *krb5_rc_get_type(krb5_context, krb5_rcache); -char *krb5_rc_default_type(krb5_context); -char *krb5_rc_default_name(krb5_context); -krb5_error_code krb5_auth_to_rep(krb5_context, krb5_tkt_authent *, - krb5_donot_replay *); -krb5_error_code krb5_rc_hash_message(krb5_context context, - const krb5_data *message, char **out); +krb5_error_code k5_rc_default(krb5_context context, krb5_rcache *rc_out); +krb5_error_code k5_rc_resolve(krb5_context context, const char *name, + krb5_rcache *rc_out); +void k5_rc_close(krb5_context context, krb5_rcache rc); +krb5_error_code k5_rc_store(krb5_context context, krb5_rcache rc, + const krb5_enc_data *authenticator); +const char *k5_rc_get_name(krb5_context context, krb5_rcache rc); /* Set *tag_out to the integrity tag of *enc. (Does not allocate memory; * returned buffer is a subrange of *ctext.) */ @@ -1993,36 +1977,6 @@ krb5_error_code k5_rc_tag_from_ciphertext(krb5_context context, const krb5_enc_data *enc, krb5_data *tag_out); -krb5_error_code KRB5_CALLCONV -krb5_rc_initialize(krb5_context, krb5_rcache, krb5_deltat); - -krb5_error_code KRB5_CALLCONV -krb5_rc_recover_or_initialize(krb5_context, krb5_rcache,krb5_deltat); - -krb5_error_code KRB5_CALLCONV -krb5_rc_recover(krb5_context, krb5_rcache); - -krb5_error_code KRB5_CALLCONV -krb5_rc_destroy(krb5_context, krb5_rcache); - -krb5_error_code KRB5_CALLCONV -krb5_rc_close(krb5_context, krb5_rcache); - -krb5_error_code KRB5_CALLCONV -krb5_rc_store(krb5_context, krb5_rcache, krb5_donot_replay *); - -krb5_error_code KRB5_CALLCONV -krb5_rc_expunge(krb5_context, krb5_rcache); - -krb5_error_code KRB5_CALLCONV -krb5_rc_get_lifespan(krb5_context, krb5_rcache,krb5_deltat *); - -char *KRB5_CALLCONV -krb5_rc_get_name(krb5_context, krb5_rcache); - -krb5_error_code KRB5_CALLCONV -krb5_rc_resolve(krb5_context, krb5_rcache, char *); - /* * This structure was exposed and used in macros in krb5 1.2, so do not * change its ABI. diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 362ba9d86a..acc1868f85 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -191,12 +191,7 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, /* If we have an explicit rcache name, open it. */ if (rcname != NULL) { - code = krb5_rc_resolve_full(context, &rc, rcname); - if (code) { - major = GSS_S_FAILURE; - goto cleanup; - } - code = krb5_rc_recover_or_initialize(context, rc, context->clockskew); + code = k5_rc_resolve(context, rcname, &rc); if (code) { major = GSS_S_FAILURE; goto cleanup; @@ -260,7 +255,7 @@ cleanup: if (kt != NULL) krb5_kt_close(context, kt); if (rc != NULL) - krb5_rc_close(context, rc); + k5_rc_close(context, rc); *minor_status = code; return major; } @@ -880,7 +875,7 @@ error_out: krb5_kt_close(context, cred->keytab); #endif /* LEAN_CLIENT */ if (cred->rcache) - krb5_rc_close(context, cred->rcache); + k5_rc_close(context, cred->rcache); if (cred->name) kg_release_name(context, &cred->name); krb5_free_principal(context, cred->impersonator); @@ -1047,14 +1042,8 @@ gss_krb5int_set_cred_rcache(OM_uint32 *minor_status, *minor_status = code; return GSS_S_FAILURE; } - if (cred->rcache != NULL) { - code = krb5_rc_close(context, cred->rcache); - if (code) { - *minor_status = code; - krb5_free_context(context); - return GSS_S_FAILURE; - } - } + if (cred->rcache != NULL) + k5_rc_close(context, cred->rcache); cred->rcache = rcache; diff --git a/src/lib/gssapi/krb5/export_cred.c b/src/lib/gssapi/krb5/export_cred.c index 8054e4a770..96a408c237 100644 --- a/src/lib/gssapi/krb5/export_cred.c +++ b/src/lib/gssapi/krb5/export_cred.c @@ -130,15 +130,10 @@ json_rcache(krb5_context context, krb5_rcache rcache, k5_json_value *val_out) { krb5_error_code ret; k5_json_string str = NULL; - char *name; if (rcache == NULL) return k5_json_null_create_val(val_out); - if (asprintf(&name, "%s:%s", krb5_rc_get_type(context, rcache), - krb5_rc_get_name(context, rcache)) < 0) - return ENOMEM; - ret = k5_json_string_create(name, &str); - free(name); + ret = k5_json_string_create(k5_rc_get_name(context, rcache), &str); *val_out = str; return ret; } diff --git a/src/lib/gssapi/krb5/import_cred.c b/src/lib/gssapi/krb5/import_cred.c index f0a0373bfb..0bea5e6c6b 100644 --- a/src/lib/gssapi/krb5/import_cred.c +++ b/src/lib/gssapi/krb5/import_cred.c @@ -171,12 +171,8 @@ json_to_rcache(krb5_context context, k5_json_value v, krb5_rcache *rcache_out) return 0; if (k5_json_get_tid(v) != K5_JSON_TID_STRING) return -1; - if (krb5_rc_resolve_full(context, &rcache, (char *)k5_json_string_utf8(v))) + if (k5_rc_resolve(context, (char *)k5_json_string_utf8(v), &rcache)) return -1; - if (krb5_rc_recover_or_initialize(context, rcache, context->clockskew)) { - krb5_rc_close(context, rcache); - return -1; - } *rcache_out = rcache; return 0; } diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c index 8db7450860..a9515daf71 100644 --- a/src/lib/gssapi/krb5/rel_cred.c +++ b/src/lib/gssapi/krb5/rel_cred.c @@ -30,7 +30,7 @@ krb5_gss_release_cred(minor_status, cred_handle) { krb5_context context; krb5_gss_cred_id_t cred; - krb5_error_code code1, code2, code3; + krb5_error_code code1, code2; code1 = krb5_gss_init_context(&context); if (code1) { @@ -68,9 +68,7 @@ krb5_gss_release_cred(minor_status, cred_handle) code2 = 0; if (cred->rcache) - code3 = krb5_rc_close(context, cred->rcache); - else - code3 = 0; + k5_rc_close(context, cred->rcache); if (cred->name) kg_release_name(context, &cred->name); @@ -91,8 +89,6 @@ krb5_gss_release_cred(minor_status, cred_handle) *minor_status = code1; if (code2) *minor_status = code2; - if (code3) - *minor_status = code3; if (*minor_status) save_error_info(*minor_status, context); diff --git a/src/lib/krb5/deps b/src/lib/krb5/deps index 57b5fa1bce..6fb333d920 100644 --- a/src/lib/krb5/deps +++ b/src/lib/krb5/deps @@ -5,7 +5,7 @@ krb5_libinit.so krb5_libinit.po $(OUTPRE)krb5_libinit.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/ccache/cc-int.h $(srcdir)/keytab/kt-int.h \ - $(srcdir)/os/os-proto.h $(srcdir)/rcache/rc-int.h $(top_srcdir)/include/k5-buf.h \ + $(srcdir)/os/os-proto.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c index c8ff9bd005..91d8e26a64 100644 --- a/src/lib/krb5/krb/auth_con.c +++ b/src/lib/krb5/krb/auth_con.c @@ -70,7 +70,7 @@ krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context) krb5_k_free_key(context, auth_context->recv_subkey); zapfree(auth_context->cstate.data, auth_context->cstate.length); if (auth_context->rcache) - krb5_rc_close(context, auth_context->rcache); + k5_rc_close(context, auth_context->rcache); if (auth_context->permitted_etypes) free(auth_context->permitted_etypes); if (auth_context->ad_context) diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c index cb98d967ec..72bc8fe971 100644 --- a/src/lib/krb5/krb/rd_req_dec.c +++ b/src/lib/krb5/krb/rd_req_dec.c @@ -514,10 +514,8 @@ rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, /* Get an rcache if necessary. */ if (((*auth_context)->rcache == NULL) && - ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) && - server != NULL && server->length > 0) { - retval = krb5_get_server_rcache(context, &server->data[0], - &(*auth_context)->rcache); + ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME)) { + retval = k5_rc_default(context, &(*auth_context)->rcache); if (retval) goto cleanup; } @@ -588,28 +586,9 @@ rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, /* only check rcache if sender has provided one---some services may not be able to use replay caches (such as datagram servers) */ - if ((*auth_context)->rcache) { - krb5_donot_replay rep; - krb5_tkt_authent tktauthent; - - tktauthent.ticket = req->ticket; - tktauthent.authenticator = (*auth_context)->authentp; - if (!(retval = krb5_auth_to_rep(context, &tktauthent, &rep))) { - retval = k5_rc_tag_from_ciphertext(context, &req->authenticator, - &rep.tag); - if (!retval) { - retval = krb5_rc_hash_message(context, - &req->authenticator.ciphertext, - &rep.msghash); - } - if (!retval) { - retval = krb5_rc_store(context, (*auth_context)->rcache, &rep); - free(rep.msghash); - } - free(rep.server); - free(rep.client); - } - + if ((*auth_context)->rcache != NULL) { + retval = k5_rc_store(context, (*auth_context)->rcache, + &req->authenticator); if (retval) goto cleanup; } diff --git a/src/lib/krb5/krb/recvauth.c b/src/lib/krb5/krb/recvauth.c index 5adc6dd14a..e3e815151a 100644 --- a/src/lib/krb5/krb/recvauth.c +++ b/src/lib/krb5/krb/recvauth.c @@ -58,7 +58,6 @@ recvauth_common(krb5_context context, krb5_data outbuf; krb5_rcache rcache = 0; krb5_octet response; - krb5_data null_server; krb5_data d; int need_error_free = 0; int local_rcache = 0, local_authcon = 0; @@ -132,17 +131,7 @@ recvauth_common(krb5_context context, } krb5_auth_con_getrcache(context, *auth_context, &rcache); if ((!problem) && rcache == NULL) { - /* - * Setup the replay cache. - */ - if (server != NULL && server->length > 0) { - problem = krb5_get_server_rcache(context, &server->data[0], - &rcache); - } else { - null_server.length = 7; - null_server.data = "default"; - problem = krb5_get_server_rcache(context, &null_server, &rcache); - } + problem = k5_rc_default(context, &rcache); if (!problem) problem = krb5_auth_con_setrcache(context, *auth_context, rcache); local_rcache = 1; @@ -220,7 +209,7 @@ cleanup:; if (local_authcon) { krb5_auth_con_free(context, *auth_context); } else if (local_rcache && rcache != NULL) { - krb5_rc_close(context, rcache); + k5_rc_close(context, rcache); krb5_auth_con_setrcache(context, *auth_context, NULL); } } diff --git a/src/lib/krb5/krb/srv_rcache.c b/src/lib/krb5/krb/srv_rcache.c index 0929145a1d..64a270e6b8 100644 --- a/src/lib/krb5/krb/srv_rcache.c +++ b/src/lib/krb5/krb/srv_rcache.c @@ -37,5 +37,5 @@ krb5_get_server_rcache(krb5_context context, const krb5_data *piece, * server principal, but now ignores the piece argument and resolves the * default replay cache. */ - return krb5_rc_default(context, rcptr); + return k5_rc_default(context, rcptr); } diff --git a/src/lib/krb5/krb/t_ser.c b/src/lib/krb5/krb/t_ser.c index f1a8c25535..cf9cf99454 100644 --- a/src/lib/krb5/krb/t_ser.c +++ b/src/lib/krb5/krb/t_ser.c @@ -141,7 +141,7 @@ ser_data(int verbose, char *msg, krb5_pointer ctx, krb5_magic dtype) krb5_cc_close(ser_ctx, (krb5_ccache) nctx); break; case KV5M_RCACHE: - krb5_rc_close(ser_ctx, (krb5_rcache) nctx); + k5_rc_close(ser_ctx, (krb5_rcache) nctx); break; case KV5M_KEYTAB: krb5_kt_close(ser_ctx, (krb5_keytab) nctx); @@ -428,19 +428,17 @@ ser_rcache_test(krb5_context kcontext, int verbose) { krb5_error_code kret; char rcname[128]; - krb5_rcache rcache; + krb5_rcache rcache = NULL; - snprintf(rcname, sizeof(rcname), "dfl:temp_rc_%d", (int) getpid()); - if (!(kret = krb5_rc_resolve_full(kcontext, &rcache, rcname)) && - !(kret = ser_data(verbose, "> Resolved FILE rcache", - (krb5_pointer) rcache, KV5M_RCACHE)) && - !(kret = krb5_rc_initialize(kcontext, rcache, 3600*24)) && - !(kret = ser_data(verbose, "> Initialized FILE rcache", - (krb5_pointer) rcache, KV5M_RCACHE)) && - !(kret = krb5_rc_destroy(kcontext, rcache))) { + snprintf(rcname, sizeof(rcname), "file2:temp_rc_%d", (int) getpid()); + if (!(kret = k5_rc_resolve(kcontext, rcname, &rcache)) && + !(kret = ser_data(verbose, "> Resolved file2 rcache", + (krb5_pointer) rcache, KV5M_RCACHE))) { if (verbose) printf("* rcache test succeeded\n"); } + if (rcache != NULL) + k5_rc_close(kcontext, rcache); if (kret) printf("* krb5_rcache test failed\n"); return(kret); diff --git a/src/lib/krb5/krb5_libinit.c b/src/lib/krb5/krb5_libinit.c index eb4012496c..bcfe2a2ac7 100644 --- a/src/lib/krb5/krb5_libinit.c +++ b/src/lib/krb5/krb5_libinit.c @@ -10,7 +10,6 @@ #include "k5-platform.h" #include "cc-int.h" #include "kt-int.h" -#include "rc-int.h" #include "os-proto.h" /* @@ -40,9 +39,6 @@ int krb5int_lib_init(void) bindtextdomain(KRB5_TEXTDOMAIN, LOCALEDIR); - err = krb5int_rc_finish_init(); - if (err) - return err; #ifndef LEAN_CLIENT err = krb5int_kt_initialize(); if (err) @@ -87,7 +83,6 @@ void krb5int_lib_fini(void) #ifndef LEAN_CLIENT krb5int_kt_finalize(); #endif /* LEAN_CLIENT */ - krb5int_rc_terminate(); #if defined(_WIN32) || defined(USE_CCAPI) krb5_stdcc_shutdown(); diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports index 1f2249841f..a6d1389038 100644 --- a/src/lib/krb5/libkrb5.exports +++ b/src/lib/krb5/libkrb5.exports @@ -151,6 +151,9 @@ k5_plugin_load k5_plugin_load_all k5_plugin_register k5_plugin_register_dyn +k5_rc_close +k5_rc_get_name +k5_rc_resolve k5_unmarshal_cred k5_unmarshal_princ k5_unwrap_cammac_svc @@ -206,7 +209,6 @@ krb5_auth_con_setrecvsubkey_k krb5_auth_con_setsendsubkey krb5_auth_con_setsendsubkey_k krb5_auth_con_setuseruserkey -krb5_auth_to_rep krb5_authdata_context_copy krb5_authdata_context_free krb5_authdata_context_init @@ -498,24 +500,6 @@ krb5_principal_compare krb5_principal_compare_any_realm krb5_principal_compare_flags krb5_prompter_posix -krb5_rc_close -krb5_rc_default -krb5_rc_default_name -krb5_rc_default_type -krb5_rc_destroy -krb5_rc_expunge -krb5_rc_get_lifespan -krb5_rc_get_name -krb5_rc_get_type -krb5_rc_hash_message -krb5_rc_initialize -krb5_rc_recover -krb5_rc_recover_or_initialize -krb5_rc_register_type -krb5_rc_resolve -krb5_rc_resolve_full -krb5_rc_resolve_type -krb5_rc_store krb5_rd_cred krb5_rd_error krb5_rd_priv diff --git a/src/lib/krb5/rcache/Makefile.in b/src/lib/krb5/rcache/Makefile.in index 441a6cae99..5db08dd895 100644 --- a/src/lib/krb5/rcache/Makefile.in +++ b/src/lib/krb5/rcache/Makefile.in @@ -11,9 +11,7 @@ STLIBOBJS = \ rc_dfl.o \ rc_file2.o \ rc_none.o \ - rc_conv.o \ - ser_rc.o \ - rcfns.o + ser_rc.o OBJS= \ $(OUTPRE)memrcache.$(OBJEXT) \ @@ -21,9 +19,7 @@ OBJS= \ $(OUTPRE)rc_dfl.$(OBJEXT) \ $(OUTPRE)rc_file2.$(OBJEXT) \ $(OUTPRE)rc_none.$(OBJEXT) \ - $(OUTPRE)rc_conv.$(OBJEXT) \ - $(OUTPRE)ser_rc.$(OBJEXT) \ - $(OUTPRE)rcfns.$(OBJEXT) + $(OUTPRE)ser_rc.$(OBJEXT) SRCS= \ $(srcdir)/memrcache.c \ @@ -31,9 +27,7 @@ SRCS= \ $(srcdir)/rc_dfl.c \ $(srcdir)/rc_file2.c \ $(srcdir)/rc_none.c \ - $(srcdir)/rc_conv.c \ $(srcdir)/ser_rc.c \ - $(srcdir)/rcfns.c \ $(srcdir)/t_memrcache.c \ $(srcdir)/t_replay.c diff --git a/src/lib/krb5/rcache/deps b/src/lib/krb5/rcache/deps index a9ac7fdb31..b9a63cf05f 100644 --- a/src/lib/krb5/rcache/deps +++ b/src/lib/krb5/rcache/deps @@ -14,17 +14,6 @@ memrcache.so memrcache.po $(OUTPRE)memrcache.$(OBJEXT): \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ memrcache.c memrcache.h rc_base.so rc_base.po $(OUTPRE)rc_base.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ - $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ - $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ - $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ - $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ - $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ - $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h rc-int.h rc_base.c \ - rc_base.h -rc_dfl.so rc_dfl.po $(OUTPRE)rc_dfl.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../os/os-proto.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ @@ -34,8 +23,17 @@ rc_dfl.so rc_dfl.po $(OUTPRE)rc_dfl.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h memrcache.h rc-int.h \ - rc_dfl.c + $(top_srcdir)/include/socket-utils.h rc-int.h rc_base.c +rc_dfl.so rc_dfl.po $(OUTPRE)rc_dfl.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.h rc-int.h rc_dfl.c rc_file2.so rc_file2.po $(OUTPRE)rc_file2.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ @@ -57,16 +55,6 @@ rc_none.so rc_none.po $(OUTPRE)rc_none.$(OBJEXT): $(BUILDTOP)/include/autoconf.h $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h rc-int.h rc_none.c -rc_conv.so rc_conv.po $(OUTPRE)rc_conv.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ - $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ - $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ - $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ - $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ - $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ - $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h rc_base.h rc_conv.c ser_rc.so ser_rc.po $(OUTPRE)ser_rc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ @@ -77,16 +65,6 @@ ser_rc.so ser_rc.po $(OUTPRE)ser_rc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h rc-int.h ser_rc.c -rcfns.so rcfns.po $(OUTPRE)rcfns.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ - $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ - $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ - $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ - $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ - $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ - $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ - $(top_srcdir)/include/socket-utils.h rc-int.h rcfns.c t_memrcache.so t_memrcache.po $(OUTPRE)t_memrcache.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ diff --git a/src/lib/krb5/rcache/rc-int.h b/src/lib/krb5/rcache/rc-int.h index 599b736180..3cc43c790f 100644 --- a/src/lib/krb5/rcache/rc-int.h +++ b/src/lib/krb5/rcache/rc-int.h @@ -27,71 +27,31 @@ /* This file contains constant and function declarations used in the * file-based replay cache routines. */ -#ifndef __KRB5_RCACHE_INT_H__ -#define __KRB5_RCACHE_INT_H__ +#ifndef RC_INT_H +#define RC_INT_H -int krb5int_rc_finish_init(void); - -void krb5int_rc_terminate(void); +typedef struct { + const char *type; + krb5_error_code (*resolve)(krb5_context context, const char *residual, + void **rcdata_out); + void (*close)(krb5_context context, void *rcdata); + krb5_error_code (*store)(krb5_context, void *rcdata, const krb5_data *tag); +} krb5_rc_ops; struct krb5_rc_st { krb5_magic magic; - const struct _krb5_rc_ops *ops; - krb5_pointer data; - k5_mutex_t lock; -}; - -struct _krb5_rc_ops { - krb5_magic magic; - char *type; - krb5_error_code (KRB5_CALLCONV *init)( - krb5_context, - krb5_rcache, - krb5_deltat); /* create */ - krb5_error_code (KRB5_CALLCONV *recover)( - krb5_context, - krb5_rcache); /* open */ - krb5_error_code (KRB5_CALLCONV *recover_or_init)( - krb5_context, - krb5_rcache, - krb5_deltat); - krb5_error_code (KRB5_CALLCONV *destroy)( - krb5_context, - krb5_rcache); - krb5_error_code (KRB5_CALLCONV *close)( - krb5_context, - krb5_rcache); - krb5_error_code (KRB5_CALLCONV *store)( - krb5_context, - krb5_rcache, - krb5_donot_replay *); - krb5_error_code (KRB5_CALLCONV *expunge)( - krb5_context, - krb5_rcache); - krb5_error_code (KRB5_CALLCONV *get_span)( - krb5_context, - krb5_rcache, - krb5_deltat *); - char *(KRB5_CALLCONV *get_name)( - krb5_context, - krb5_rcache); - krb5_error_code (KRB5_CALLCONV *resolve)( - krb5_context, - krb5_rcache, - char *); + const krb5_rc_ops *ops; + char *name; + void *data; }; -typedef struct _krb5_rc_ops krb5_rc_ops; - -krb5_error_code krb5_rc_register_type(krb5_context, const krb5_rc_ops *); - -extern const krb5_rc_ops krb5_rc_dfl_ops; -extern const krb5_rc_ops krb5_rc_file2_ops; -extern const krb5_rc_ops krb5_rc_none_ops; +extern const krb5_rc_ops k5_rc_dfl_ops; +extern const krb5_rc_ops k5_rc_file2_ops; +extern const krb5_rc_ops k5_rc_none_ops; /* Check and store a replay record in an open (but not locked) file descriptor, * using the file2 format. fd is assumed to be at offset 0. */ krb5_error_code k5_rcfile2_store(krb5_context context, int fd, - krb5_donot_replay *rep); + const krb5_data *tag_data); -#endif /* __KRB5_RCACHE_INT_H__ */ +#endif /* RC_INT_H */ diff --git a/src/lib/krb5/rcache/rc_base.c b/src/lib/krb5/rcache/rc_base.c index 66937594d5..cbde91fcdf 100644 --- a/src/lib/krb5/rcache/rc_base.c +++ b/src/lib/krb5/rcache/rc_base.c @@ -10,165 +10,44 @@ * Base "glue" functions for the replay cache. */ -#include "rc_base.h" +#include "k5-int.h" #include "rc-int.h" #include "k5-thread.h" #include "../os/os-proto.h" -struct krb5_rc_typelist { +struct typelist { const krb5_rc_ops *ops; - struct krb5_rc_typelist *next; + struct typelist *next; }; -static struct krb5_rc_typelist none = { &krb5_rc_none_ops, 0 }; -static struct krb5_rc_typelist file2 = { &krb5_rc_file2_ops, &none }; -static struct krb5_rc_typelist krb5_rc_typelist_dfl = { &krb5_rc_dfl_ops, &file2 }; -static struct krb5_rc_typelist *typehead = &krb5_rc_typelist_dfl; -static k5_mutex_t rc_typelist_lock = K5_MUTEX_PARTIAL_INITIALIZER; - -int -krb5int_rc_finish_init(void) -{ - return k5_mutex_finish_init(&rc_typelist_lock); -} - -void -krb5int_rc_terminate(void) -{ - struct krb5_rc_typelist *t, *t_next; - k5_mutex_destroy(&rc_typelist_lock); - for (t = typehead; t != &krb5_rc_typelist_dfl; t = t_next) { - t_next = t->next; - free(t); - } -} +static struct typelist none = { &k5_rc_none_ops, 0 }; +static struct typelist file2 = { &k5_rc_file2_ops, &none }; +static struct typelist dfl = { &k5_rc_dfl_ops, &file2 }; +static struct typelist *typehead = &dfl; krb5_error_code -krb5_rc_register_type(krb5_context context, const krb5_rc_ops *ops) -{ - struct krb5_rc_typelist *t; - - k5_mutex_lock(&rc_typelist_lock); - for (t = typehead;t && strcmp(t->ops->type,ops->type);t = t->next) - ; - if (t) { - k5_mutex_unlock(&rc_typelist_lock); - return KRB5_RC_TYPE_EXISTS; - } - t = (struct krb5_rc_typelist *) malloc(sizeof(struct krb5_rc_typelist)); - if (t == NULL) { - k5_mutex_unlock(&rc_typelist_lock); - return KRB5_RC_MALLOC; - } - t->next = typehead; - t->ops = ops; - typehead = t; - k5_mutex_unlock(&rc_typelist_lock); - return 0; -} - -krb5_error_code -krb5_rc_resolve_type(krb5_context context, krb5_rcache *idptr, - const char *type) -{ - struct krb5_rc_typelist *t; - krb5_error_code err; - krb5_rcache id; - - *idptr = NULL; - - /* Find the named type in the list. */ - k5_mutex_lock(&rc_typelist_lock); - for (t = typehead; t && strcmp(t->ops->type, type); t = t->next) - ; - k5_mutex_unlock(&rc_typelist_lock); - if (!t) - return KRB5_RC_TYPE_NOTFOUND; - - /* Create and return the rcache structure. */ - id = malloc(sizeof(*id)); - if (!id) - return KRB5_RC_MALLOC; - err = k5_mutex_init(&id->lock); - if (err) { - free(id); - return err; - } - id->data = NULL; /* Gets real data when resolved */ - id->magic = 0; /* Gets real magic after resolved */ - id->ops = t->ops; - *idptr = id; - return 0; -} - -char * krb5_rc_get_type(krb5_context context, krb5_rcache id) -{ - return id->ops->type; -} - -char * -krb5_rc_default_type(krb5_context context) -{ - char *s; - if ((s = secure_getenv("KRB5RCACHETYPE"))) - return s; - else - return "dfl"; -} - -char * -krb5_rc_default_name(krb5_context context) -{ - char *s; - if ((s = secure_getenv("KRB5RCACHENAME"))) - return s; - else - return (char *) 0; -} - -static krb5_error_code -resolve_type_and_residual(krb5_context context, const char *type, - char *residual, krb5_rcache *rc_out) -{ - krb5_error_code ret; - krb5_rcache rc; - - *rc_out = NULL; - - ret = krb5_rc_resolve_type(context, &rc, type); - if (ret) - return ret; - - ret = krb5_rc_resolve(context, rc, residual); - if (ret) { - k5_mutex_destroy(&rc->lock); - free(rc); - return ret; - } - - rc->magic = KV5M_RCACHE; - *rc_out = rc; - return 0; -} - -krb5_error_code -krb5_rc_default(krb5_context context, krb5_rcache *idptr) +k5_rc_default(krb5_context context, krb5_rcache *rc_out) { krb5_error_code ret; const char *val; char *profstr, *rcname; - *idptr = NULL; + *rc_out = NULL; /* If KRB5RCACHENAME is set in the environment, resolve it. */ val = secure_getenv("KRB5RCACHENAME"); if (val != NULL) - return krb5_rc_resolve_full(context, idptr, val); + return k5_rc_resolve(context, val, rc_out); /* If KRB5RCACHETYPE is set in the environment, resolve it with an empty * residual (primarily to support KRB5RCACHETYPE=none). */ val = secure_getenv("KRB5RCACHETYPE"); - if (val != NULL) - return resolve_type_and_residual(context, val, "", idptr); + if (val != NULL) { + if (asprintf(&rcname, "%s:", val) < 0) + return ENOMEM; + ret = k5_rc_resolve(context, rcname, rc_out); + free(rcname); + return ret; + } /* If [libdefaults] default_rcache_name is set, expand path tokens in the * value and resolve it. */ @@ -177,34 +56,107 @@ krb5_rc_default(krb5_context context, krb5_rcache *idptr) &profstr) == 0 && profstr != NULL) { ret = k5_expand_path_tokens(context, profstr, &rcname); profile_release_string(profstr); - ret = krb5_rc_resolve_full(context, idptr, rcname); + ret = k5_rc_resolve(context, rcname, rc_out); free(rcname); return ret; } /* Resolve the default type with no residual. */ - return resolve_type_and_residual(context, "dfl", "", idptr); + return k5_rc_resolve(context, "dfl:", rc_out); } krb5_error_code -krb5_rc_resolve_full(krb5_context context, krb5_rcache *idptr, - const char *string_name) +k5_rc_resolve(krb5_context context, const char *name, krb5_rcache *rc_out) { krb5_error_code ret; - char *type, *sep; + struct typelist *t; + const char *sep; + size_t len; + krb5_rcache rc = NULL; - *idptr = NULL; + *rc_out = NULL; - sep = strchr(string_name, ':'); + sep = strchr(name, ':'); if (sep == NULL) return KRB5_RC_PARSE; + len = sep - name; - type = k5memdup0(string_name, sep - string_name, &ret); - if (type == NULL) - return ret; + for (t = typehead; t != NULL; t = t->next) { + if (strncmp(t->ops->type, name, len) == 0 && t->ops->type[len] == '\0') + break; + } + if (t == NULL) + return KRB5_RC_TYPE_NOTFOUND; - ret = resolve_type_and_residual(context, type, sep + 1, idptr); - free(type); + rc = k5alloc(sizeof(*rc), &ret); + if (rc == NULL) + goto error; + rc->name = strdup(name); + if (rc->name == NULL) { + ret = ENOMEM; + goto error; + } + ret = t->ops->resolve(context, sep + 1, &rc->data); + if (ret) + goto error; + rc->ops = t->ops; + rc->magic = KV5M_RCACHE; + + *rc_out = rc; + return 0; + +error: + if (rc != NULL) { + free(rc->name); + free(rc); + } return ret; } + +void +k5_rc_close(krb5_context context, krb5_rcache rc) +{ + rc->ops->close(context, rc->data); + free(rc->name); + free(rc); +} + +krb5_error_code +k5_rc_store(krb5_context context, krb5_rcache rc, + const krb5_enc_data *authenticator) +{ + krb5_error_code ret; + krb5_data tag; + + ret = k5_rc_tag_from_ciphertext(context, authenticator, &tag); + if (ret) + return ret; + return rc->ops->store(context, rc->data, &tag); +} + +const char * +k5_rc_get_name(krb5_context context, krb5_rcache rc) +{ + return rc->name; +} + +krb5_error_code +k5_rc_tag_from_ciphertext(krb5_context context, const krb5_enc_data *enc, + krb5_data *tag_out) +{ + krb5_error_code ret; + const krb5_data *cdata = &enc->ciphertext; + unsigned int len; + + *tag_out = empty_data(); + + ret = krb5_c_crypto_length(context, enc->enctype, + KRB5_CRYPTO_TYPE_CHECKSUM, &len); + if (ret) + return ret; + if (cdata->length < len) + return EINVAL; + *tag_out = make_data(cdata->data + cdata->length - len, len); + return 0; +} diff --git a/src/lib/krb5/rcache/rc_base.h b/src/lib/krb5/rcache/rc_base.h deleted file mode 100644 index 0530b90f84..0000000000 --- a/src/lib/krb5/rcache/rc_base.h +++ /dev/null @@ -1,15 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* lib/krb5/rcache/rc_base.h */ -/* - * This file of the Kerberos V5 software is derived from public-domain code - * contributed by Daniel J. Bernstein, . - * - */ - -#ifndef KRB5_RC_H -#define KRB5_RC_H -#include "k5-int.h" - -/* all the stuff that was here is now in rcache.h, included by krb5/krb5.h */ - -#endif diff --git a/src/lib/krb5/rcache/rc_conv.c b/src/lib/krb5/rcache/rc_conv.c deleted file mode 100644 index ff33a97ec5..0000000000 --- a/src/lib/krb5/rcache/rc_conv.c +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* lib/krb5/rcache/rc_conv.c */ -/* - * This file of the Kerberos V5 software is derived from public-domain code - * contributed by Daniel J. Bernstein, . - * - */ - -/* - * An implementation for the default replay cache type. - */ - -#include "rc_base.h" - -/* - Local stuff: - krb5_auth_to_replay(context, krb5_tkt_authent *auth,krb5_donot_replay *rep) - given auth, take important information and make rep; return -1 if failed -*/ - -krb5_error_code -krb5_auth_to_rep(krb5_context context, krb5_tkt_authent *auth, krb5_donot_replay *rep) -{ - krb5_error_code retval; - rep->cusec = auth->authenticator->cusec; - rep->ctime = auth->authenticator->ctime; - if ((retval = krb5_unparse_name(context, auth->ticket->server, &rep->server))) - return retval; /* shouldn't happen */ - if ((retval = krb5_unparse_name(context, auth->authenticator->client, - &rep->client))) { - free(rep->server); - return retval; /* shouldn't happen. */ - } - return 0; -} - -/* - * Generate a printable hash value for a message for use in a replay - * record. It is not necessary for this hash function to be - * collision-proof (the only thing you can do with a second preimage - * is produce a false replay error) but for fine granularity replay detection - * it is necessary for the function to be consistent across implementations. - * When two implementations sharing a single replay cache don't agree on hash - * function, the code falls back to legacy replay detection based on - * (client, server, timestamp, usec) tuples. We do an unkeyed - * SHA256 hash of the message and convert it into uppercase hex - * representation. - */ -krb5_error_code -krb5_rc_hash_message(krb5_context context, const krb5_data *message, - char **out) -{ - krb5_error_code retval; - uint8_t cksum[K5_SHA256_HASHLEN]; - char *hash, *ptr; - unsigned int i; - - *out = NULL; - - /* Calculate the binary checksum. */ - retval = k5_sha256(message, 1, cksum); - if (retval) - return retval; - - /* Convert the checksum into printable form. */ - hash = malloc(K5_SHA256_HASHLEN * 2 + 1); - if (!hash) { - return KRB5_RC_MALLOC; - } - - for (i = 0, ptr = hash; i < K5_SHA256_HASHLEN; i++, ptr += 2) - snprintf(ptr, 3, "%02X", cksum[i]); - *ptr = '\0'; - *out = hash; - return 0; -} - -krb5_error_code -k5_rc_tag_from_ciphertext(krb5_context context, const krb5_enc_data *enc, - krb5_data *tag_out) -{ - krb5_error_code ret; - const krb5_data *cdata = &enc->ciphertext; - unsigned int len; - - *tag_out = empty_data(); - - ret = krb5_c_crypto_length(context, enc->enctype, - KRB5_CRYPTO_TYPE_CHECKSUM, &len); - if (ret) - return ret; - if (cdata->length < len) - return EINVAL; - *tag_out = make_data(cdata->data + cdata->length - len, len); - return 0; -} diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c index d7ea476061..1a826763b7 100644 --- a/src/lib/krb5/rcache/rc_dfl.c +++ b/src/lib/krb5/rcache/rc_dfl.c @@ -128,55 +128,20 @@ cleanup: #endif /* not _WIN32 */ -static char * KRB5_CALLCONV -dfl_get_name(krb5_context context, krb5_rcache rc) -{ - return ""; -} - -static krb5_error_code KRB5_CALLCONV -dfl_get_span(krb5_context context, krb5_rcache rc, krb5_deltat *lifespan) -{ - *lifespan = context->clockskew; - return 0; -} - -static krb5_error_code KRB5_CALLCONV -dfl_init(krb5_context context, krb5_rcache rc, krb5_deltat lifespan) -{ - return 0; -} - -static krb5_error_code KRB5_CALLCONV -dfl_close(krb5_context context, krb5_rcache rc) -{ - k5_mutex_destroy(&rc->lock); - free(rc); - return 0; -} - -#define dfl_destroy dfl_close - -static krb5_error_code KRB5_CALLCONV -dfl_resolve(krb5_context context, krb5_rcache rc, char *name) +static krb5_error_code +dfl_resolve(krb5_context context, const char *residual, void **rcdata_out) { + *rcdata_out = NULL; return 0; } -static krb5_error_code KRB5_CALLCONV -dfl_recover(krb5_context context, krb5_rcache rc) +static void +dfl_close(krb5_context context, void *rcdata) { - return 0; } -static krb5_error_code KRB5_CALLCONV -dfl_recover_or_init(krb5_context context, krb5_rcache rc, krb5_deltat lifespan) -{ - return 0; -} - -static krb5_error_code KRB5_CALLCONV -dfl_store(krb5_context context, krb5_rcache rc, krb5_donot_replay *rep) +static krb5_error_code +dfl_store(krb5_context context, void *rcdata, const krb5_data *tag) { krb5_error_code ret; int fd; @@ -185,29 +150,15 @@ dfl_store(krb5_context context, krb5_rcache rc, krb5_donot_replay *rep) if (ret) return ret; - ret = k5_rcfile2_store(context, fd, rep); + ret = k5_rcfile2_store(context, fd, tag); close(fd); return ret; } -static krb5_error_code KRB5_CALLCONV -dfl_expunge(krb5_context context, krb5_rcache rc) -{ - return 0; -} - -const krb5_rc_ops krb5_rc_dfl_ops = +const krb5_rc_ops k5_rc_dfl_ops = { - 0, "dfl", - dfl_init, - dfl_recover, - dfl_recover_or_init, - dfl_destroy, + dfl_resolve, dfl_close, - dfl_store, - dfl_expunge, - dfl_get_span, - dfl_get_name, - dfl_resolve + dfl_store }; diff --git a/src/lib/krb5/rcache/rc_file2.c b/src/lib/krb5/rcache/rc_file2.c index e34c43a3c1..6519cc322f 100644 --- a/src/lib/krb5/rcache/rc_file2.c +++ b/src/lib/krb5/rcache/rc_file2.c @@ -186,24 +186,23 @@ store(krb5_context context, int fd, const uint8_t tag[TAG_LEN], uint32_t now, } krb5_error_code -k5_rcfile2_store(krb5_context context, int fd, krb5_donot_replay *rep) +k5_rcfile2_store(krb5_context context, int fd, const krb5_data *tag_data) { krb5_error_code ret; krb5_timestamp now; - uint8_t tag[TAG_LEN]; - - if (rep->tag.length == 0) - return EINVAL; + uint8_t tagbuf[TAG_LEN], *tag; ret = krb5_timeofday(context, &now); if (ret) return ret; - if (rep->tag.length >= TAG_LEN) { - memcpy(tag, rep->tag.data, TAG_LEN); + /* Extract a tag from the authenticator checksum. */ + if (tag_data->length >= TAG_LEN) { + tag = (uint8_t *)tag_data->data; } else { - memcpy(tag, rep->tag.data, rep->tag.length); - memset(tag + rep->tag.length, 0, TAG_LEN - rep->tag.length); + memcpy(tagbuf, tag_data->data, tag_data->length); + memset(tagbuf + tag_data->length, 0, TAG_LEN - tag_data->length); + tag = tagbuf; } ret = krb5_lock_file(context, fd, KRB5_LOCKMODE_EXCLUSIVE); @@ -214,61 +213,24 @@ k5_rcfile2_store(krb5_context context, int fd, krb5_donot_replay *rep) return ret; } -static char * KRB5_CALLCONV -file2_get_name(krb5_context context, krb5_rcache rc) -{ - return (char *)rc->data; -} - -static krb5_error_code KRB5_CALLCONV -file2_get_span(krb5_context context, krb5_rcache rc, krb5_deltat *lifespan) -{ - *lifespan = context->clockskew; - return 0; -} - -static krb5_error_code KRB5_CALLCONV -file2_init(krb5_context context, krb5_rcache rc, krb5_deltat lifespan) -{ - return 0; -} - -static krb5_error_code KRB5_CALLCONV -file2_close(krb5_context context, krb5_rcache rc) -{ - k5_mutex_destroy(&rc->lock); - free(rc->data); - free(rc); - return 0; -} - -#define file2_destroy file2_close - -static krb5_error_code KRB5_CALLCONV -file2_resolve(krb5_context context, krb5_rcache rc, char *name) -{ - rc->data = strdup(name); - return (rc->data == NULL) ? ENOMEM : 0; -} - -static krb5_error_code KRB5_CALLCONV -file2_recover(krb5_context context, krb5_rcache rc) +static krb5_error_code +file2_resolve(krb5_context context, const char *residual, void **rcdata_out) { - return 0; + *rcdata_out = strdup(residual); + return (*rcdata_out == NULL) ? ENOMEM : 0; } -static krb5_error_code KRB5_CALLCONV -file2_recover_or_init(krb5_context context, krb5_rcache rc, - krb5_deltat lifespan) +static void +file2_close(krb5_context context, void *rcdata) { - return 0; + free(rcdata); } -static krb5_error_code KRB5_CALLCONV -file2_store(krb5_context context, krb5_rcache rc, krb5_donot_replay *rep) +static krb5_error_code +file2_store(krb5_context context, void *rcdata, const krb5_data *tag) { krb5_error_code ret; - const char *filename = rc->data; + const char *filename = rcdata; int fd; fd = open(filename, O_CREAT | O_RDWR | O_BINARY, 0600); @@ -278,29 +240,15 @@ file2_store(krb5_context context, krb5_rcache rc, krb5_donot_replay *rep) filename); return ret; } - ret = k5_rcfile2_store(context, fd, rep); + ret = k5_rcfile2_store(context, fd, tag); close(fd); return ret; } -static krb5_error_code KRB5_CALLCONV -file2_expunge(krb5_context context, krb5_rcache rc) -{ - return 0; -} - -const krb5_rc_ops krb5_rc_file2_ops = +const krb5_rc_ops k5_rc_file2_ops = { - 0, "file2", - file2_init, - file2_recover, - file2_recover_or_init, - file2_destroy, + file2_resolve, file2_close, - file2_store, - file2_expunge, - file2_get_span, - file2_get_name, - file2_resolve + file2_store }; diff --git a/src/lib/krb5/rcache/rc_none.c b/src/lib/krb5/rcache/rc_none.c index 0b2274df7f..0782017840 100644 --- a/src/lib/krb5/rcache/rc_none.c +++ b/src/lib/krb5/rcache/rc_none.c @@ -32,66 +32,27 @@ #include "k5-int.h" #include "rc-int.h" -static krb5_error_code KRB5_CALLCONV -krb5_rc_none_init(krb5_context ctx, krb5_rcache rc, krb5_deltat d) +static krb5_error_code +none_resolve(krb5_context ctx, const char *residual, void **rcdata_out) { + *rcdata_out = NULL; return 0; } -#define krb5_rc_none_recover_or_init krb5_rc_none_init -static krb5_error_code KRB5_CALLCONV -krb5_rc_none_noargs(krb5_context ctx, krb5_rcache rc) +static void +none_close(krb5_context ctx, void *rcdata) { - return 0; -} -#define krb5_rc_none_recover krb5_rc_none_noargs -#define krb5_rc_none_expunge krb5_rc_none_noargs - -static krb5_error_code KRB5_CALLCONV -krb5_rc_none_close(krb5_context ctx, krb5_rcache rc) -{ - k5_mutex_destroy(&rc->lock); - free (rc); - return 0; -} -#define krb5_rc_none_destroy krb5_rc_none_close - -static krb5_error_code KRB5_CALLCONV -krb5_rc_none_store(krb5_context ctx, krb5_rcache rc, krb5_donot_replay *r) -{ - return 0; -} - -static krb5_error_code KRB5_CALLCONV -krb5_rc_none_get_span(krb5_context ctx, krb5_rcache rc, krb5_deltat *d) -{ - return 0; -} - -static char * KRB5_CALLCONV -krb5_rc_none_get_name(krb5_context ctx, krb5_rcache rc) -{ - return ""; } -static krb5_error_code KRB5_CALLCONV -krb5_rc_none_resolve(krb5_context ctx, krb5_rcache rc, char *name) +static krb5_error_code +none_store(krb5_context ctx, void *rcdata, const krb5_data *tag) { - rc->data = "none"; return 0; } -const krb5_rc_ops krb5_rc_none_ops = { - 0, +const krb5_rc_ops k5_rc_none_ops = { "none", - krb5_rc_none_init, - krb5_rc_none_recover, - krb5_rc_none_recover_or_init, - krb5_rc_none_destroy, - krb5_rc_none_close, - krb5_rc_none_store, - krb5_rc_none_expunge, - krb5_rc_none_get_span, - krb5_rc_none_get_name, - krb5_rc_none_resolve + none_resolve, + none_close, + none_store }; diff --git a/src/lib/krb5/rcache/rcfns.c b/src/lib/krb5/rcache/rcfns.c deleted file mode 100644 index b12864ab51..0000000000 --- a/src/lib/krb5/rcache/rcfns.c +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* lib/krb5/rcache/rcfns.c */ -/* - * Copyright 2001 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -/* - * Dispatch methods for replay cache code. - */ - -#include "k5-int.h" -#include "rc-int.h" - -krb5_error_code KRB5_CALLCONV -krb5_rc_initialize (krb5_context context, krb5_rcache id, krb5_deltat span) -{ - return krb5_x(id->ops->init,(context, id, span)); -} - -krb5_error_code KRB5_CALLCONV -krb5_rc_recover_or_initialize (krb5_context context, krb5_rcache id, - krb5_deltat span) -{ - return krb5_x(id->ops->recover_or_init,(context, id, span)); -} - -krb5_error_code KRB5_CALLCONV -krb5_rc_recover (krb5_context context, krb5_rcache id) -{ - return krb5_x((id)->ops->recover,(context, id)); -} - -krb5_error_code KRB5_CALLCONV -krb5_rc_destroy (krb5_context context, krb5_rcache id) -{ - return krb5_x((id)->ops->destroy,(context, id)); -} - -krb5_error_code KRB5_CALLCONV -krb5_rc_close (krb5_context context, krb5_rcache id) -{ - return krb5_x((id)->ops->close,(context, id)); -} - -krb5_error_code KRB5_CALLCONV -krb5_rc_store (krb5_context context, krb5_rcache id, - krb5_donot_replay *dontreplay) -{ - return krb5_x((id)->ops->store,(context, id, dontreplay)); -} - -krb5_error_code KRB5_CALLCONV -krb5_rc_expunge (krb5_context context, krb5_rcache id) -{ - return krb5_x((id)->ops->expunge,(context, id)); -} - -krb5_error_code KRB5_CALLCONV -krb5_rc_get_lifespan (krb5_context context, krb5_rcache id, - krb5_deltat *spanp) -{ - return krb5_x((id)->ops->get_span,(context, id, spanp)); -} - -char *KRB5_CALLCONV -krb5_rc_get_name (krb5_context context, krb5_rcache id) -{ - return krb5_xc((id)->ops->get_name,(context, id)); -} - -krb5_error_code KRB5_CALLCONV -krb5_rc_resolve (krb5_context context, krb5_rcache id, char *name) -{ - return krb5_x((id)->ops->resolve,(context, id, name)); -} diff --git a/src/lib/krb5/rcache/ser_rc.c b/src/lib/krb5/rcache/ser_rc.c index 5c537f08a1..ee6644c6b1 100644 --- a/src/lib/krb5/rcache/ser_rc.c +++ b/src/lib/krb5/rcache/ser_rc.c @@ -61,28 +61,17 @@ krb5_rcache_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) { krb5_error_code kret; krb5_rcache rcache; - size_t required; kret = EINVAL; if ((rcache = (krb5_rcache) arg)) { /* - * Saving FILE: variants of krb5_rcache requires at minimum: + * Saving krb5_rcache requires at minimum: * krb5_int32 for KV5M_RCACHE * krb5_int32 for length of rcache name. * krb5_int32 for KV5M_RCACHE */ - required = sizeof(krb5_int32) * 3; - if (rcache->ops) - required += (strlen(rcache->ops->type)+1); - - /* - * The rcache name is formed as follows: - * : - */ - required += strlen(krb5_rc_get_name(kcontext, rcache)); - + *sizep += sizeof(krb5_int32) * 3 + strlen(rcache->name); kret = 0; - *sizep += required; } return(kret); } @@ -98,8 +87,6 @@ krb5_rcache_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **bu size_t required; krb5_octet *bp; size_t remain; - char *rcname; - char *fnamep; required = 0; bp = *buffer; @@ -109,34 +96,20 @@ krb5_rcache_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **bu kret = ENOMEM; if (!krb5_rcache_size(kcontext, arg, &required) && (required <= remain)) { - /* Our identifier */ - (void) krb5_ser_pack_int32(KV5M_RCACHE, &bp, &remain); - - fnamep = krb5_rc_get_name(kcontext, rcache); - - if (rcache->ops->type) { - if (asprintf(&rcname, "%s:%s", rcache->ops->type, fnamep) < 0) - rcname = NULL; - } else - rcname = strdup(fnamep); - - if (rcname) { - /* Put the length of the file name */ - (void) krb5_ser_pack_int32((krb5_int32) strlen(rcname), - &bp, &remain); - - /* Put the name */ - (void) krb5_ser_pack_bytes((krb5_octet *) rcname, - strlen(rcname), - &bp, &remain); - - /* Put the trailer */ - (void) krb5_ser_pack_int32(KV5M_RCACHE, &bp, &remain); - kret = 0; - *buffer = bp; - *lenremain = remain; - free(rcname); - } + /* Put the header identifier. */ + (void)krb5_ser_pack_int32(KV5M_RCACHE, &bp, &remain); + + /* Put the replay cache name after its length. */ + (void)krb5_ser_pack_int32(strlen(rcache->name), &bp, &remain); + (void)krb5_ser_pack_bytes((uint8_t *)rcache->name, + strlen(rcache->name), &bp, &remain); + + /* Put the trailer. */ + (void)krb5_ser_pack_int32(KV5M_RCACHE, &bp, &remain); + + kret = 0; + *buffer = bp; + *lenremain = remain; } } return(kret); @@ -178,10 +151,9 @@ krb5_rcache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet ** rcname[ibuf] = '\0'; /* Resolve and recover the rcache. */ - kret = krb5_rc_resolve_full(kcontext, &rcache, rcname); + kret = k5_rc_resolve(kcontext, rcname, &rcache); if (kret) goto cleanup; - krb5_rc_recover(kcontext, rcache); /* Read our magic number again. */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); @@ -198,7 +170,7 @@ krb5_rcache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet ** cleanup: free(rcname); if (kret != 0 && rcache) - krb5_rc_close(kcontext, rcache); + k5_rc_close(kcontext, rcache); return kret; } diff --git a/src/lib/krb5/rcache/t_rcfile2.c b/src/lib/krb5/rcache/t_rcfile2.c index cc32719f17..7b8bb55454 100644 --- a/src/lib/krb5/rcache/t_rcfile2.c +++ b/src/lib/krb5/rcache/t_rcfile2.c @@ -55,21 +55,20 @@ krb5_context ctx; static krb5_error_code -test_store(krb5_rcache rc, uint8_t *tag, krb5_timestamp timestamp, +test_store(const char *filename, uint8_t *tag, krb5_timestamp timestamp, const uint32_t clockskew) { - krb5_donot_replay rep = { 0 }; + krb5_data tag_data = make_data(tag, TAG_LEN); ctx->clockskew = clockskew; (void)krb5_set_debugging_time(ctx, timestamp, 0); - rep.tag = make_data(tag, TAG_LEN); - return file2_store(ctx, rc, &rep); + return file2_store(ctx, (void *)filename, &tag_data); } /* Store a sequence of unique tags, with timestamps far enough apart that all * previous records appear expired. Verify that we only use one table. */ static void -expiry_test(krb5_rcache rc, int reps, const char *filename) +expiry_test(const char *filename, int reps) { krb5_error_code ret; struct stat statbuf; @@ -85,7 +84,7 @@ expiry_test(krb5_rcache rc, int reps, const char *filename) hashval = k5_siphash24(data, 4, seed); store_64_be(hashval, tag); - ret = test_store(rc, tag, timestamp, clockskew); + ret = test_store(filename, tag, timestamp, clockskew); assert(ret == 0); /* Since we increment timestamp enough to expire every record between @@ -99,7 +98,7 @@ expiry_test(krb5_rcache rc, int reps, const char *filename) /* Store a sequence of unique tags with the same timestamp. Exit with failure * if any store operation doesn't succeed or fail as given by expect_fail. */ static void -store_records(krb5_rcache rc, int id, int reps, int expect_fail) +store_records(const char *filename, int id, int reps, int expect_fail) { krb5_error_code ret; uint8_t tag[TAG_LEN] = { 0 }; @@ -108,7 +107,7 @@ store_records(krb5_rcache rc, int id, int reps, int expect_fail) store_32_be(id, tag); for (i = 0; i < reps; i++) { store_32_be(i, tag + 4); - ret = test_store(rc, tag, 1000, 100); + ret = test_store(filename, tag, 1000, 100); if (ret != (expect_fail ? KRB5KRB_AP_ERR_REPEAT : 0)) { fprintf(stderr, "store %d %d %sfail\n", id, i, expect_fail ? "didn't " : ""); @@ -120,7 +119,7 @@ store_records(krb5_rcache rc, int id, int reps, int expect_fail) /* Spawn multiple child processes, each storing a sequence of unique tags. * After each process completes, verify that its tags appear as replays. */ static void -concurrency_test(krb5_rcache rc, int nchildren, int reps) +concurrency_test(const char *filename, int nchildren, int reps) { pid_t *pids, pid; int i, nprocs, status; @@ -131,7 +130,7 @@ concurrency_test(krb5_rcache rc, int nchildren, int reps) pids[i] = fork(); assert(pids[i] != -1); if (pids[i] == 0) { - store_records(rc, i, reps, 0); + store_records(filename, i, reps, 0); _exit(0); } } @@ -140,7 +139,7 @@ concurrency_test(krb5_rcache rc, int nchildren, int reps) assert(pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0); for (i = 0; i < nchildren; i++) { if (pids[i] == pid) - store_records(rc, i, reps, 1); + store_records(filename, i, reps, 1); } } free(pids); @@ -149,7 +148,7 @@ concurrency_test(krb5_rcache rc, int nchildren, int reps) /* Spawn multiple child processes, all trying to store the same tag. Verify * that only one of the processes succeeded. Repeat reps times. */ static void -race_test(krb5_rcache rc, int nchildren, int reps) +race_test(const char *filename, int nchildren, int reps) { int i, j, status, nsuccess; uint8_t tag[TAG_LEN] = { 0 }; @@ -161,7 +160,7 @@ race_test(krb5_rcache rc, int nchildren, int reps) pid = fork(); assert(pid != -1); if (pid == 0) - _exit(test_store(rc, tag, 1000, 100) != 0); + _exit(test_store(filename, tag, 1000, 100) != 0); } nsuccess = 0; @@ -179,7 +178,6 @@ int main(int argc, char **argv) { const char *filename, *cmd; - struct krb5_rc_st rc = { 0 }; argv++; assert(*argv != NULL); @@ -190,19 +188,18 @@ main(int argc, char **argv) assert(*argv != NULL); filename = *argv++; unlink(filename); - rc.data = (void *)filename; assert(*argv != NULL); cmd = *argv++; if (strcmp(cmd, "expiry") == 0) { assert(argv[0] != NULL); - expiry_test(&rc, atoi(argv[0]), filename); + expiry_test(filename, atoi(argv[0])); } else if (strcmp(cmd, "concurrent") == 0) { assert(argv[0] != NULL && argv[1] != NULL); - concurrency_test(&rc, atoi(argv[0]), atoi(argv[1])); + concurrency_test(filename, atoi(argv[0]), atoi(argv[1])); } else if (strcmp(cmd, "race") == 0) { assert(argv[0] != NULL && argv[1] != NULL); - race_test(&rc, atoi(argv[0]), atoi(argv[1])); + race_test(filename, atoi(argv[0]), atoi(argv[1])); } else { abort(); } diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def index e6a487593e..67ac1d3653 100644 --- a/src/lib/krb5_32.def +++ b/src/lib/krb5_32.def @@ -277,7 +277,7 @@ EXPORTS krb5_get_tgs_ktypes @177 ; PRIVATE GSSAPI krb5.hin krb5_auth_con_set_req_cksumtype @36 ; PRIVATE GSSAPI krb5.hin krb5_kt_free_entry @192 ; PRIVATE GSSAPI krb5.hin - krb5_rc_close @217 ; PRIVATE GSSAPI krb5.hin + k5_rc_close @217 ; PRIVATE GSSAPI krb5.hin krb5_free_enc_tkt_part @132 ; PRIVATE GSSAPI krb5.hin krb5_decrypt_tkt_part @108 ; PRIVATE GSSAPI krb5.hin @@ -434,10 +434,8 @@ EXPORTS krb5_responder_get_challenge @406 krb5_responder_list_questions @407 krb5_responder_set_answer @408 - krb5_rc_recover_or_initialize @409 ; PRIVATE GSSAPI - krb5_rc_resolve_full @410 ; PRIVATE GSSAPI - krb5_rc_get_name @411 ; PRIVATE GSSAPI - krb5_rc_get_type @412 ; PRIVATE GSSAPI + k5_rc_resolve @410 ; PRIVATE GSSAPI + k5_rc_get_name @411 ; PRIVATE GSSAPI krb5_responder_otp_get_challenge @413 krb5_responder_otp_set_answer @414 krb5_responder_otp_challenge_free @415