From b76f80d4acb7b3d63ae119f91c15cded1f606f47 Mon Sep 17 00:00:00 2001 From: Karl Ramm Date: Sun, 22 Aug 2010 00:56:20 +0000 Subject: fixes for krb5 being more careful about ticket expiration krb5 actually checks in mk_req and fails if the ticks are expired, rather than giving you an authenticator that would fail and, handing you the session key that you'd already negotiated. This causes (meh) sending auth to fail as opposed to just ending up unauthentic and (poor) verifiable messages to look unauthentic or forged. So get the session key from the ccache without checking the expiration time, and have the cert routine skip making an authenticator if krb5_mk_req_extended says the ticket is expired. --- lib/ZMkAuth.c | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) (limited to 'lib/ZMkAuth.c') diff --git a/lib/ZMkAuth.c b/lib/ZMkAuth.c index 0a39487..e5ad2df 100644 --- a/lib/ZMkAuth.c +++ b/lib/ZMkAuth.c @@ -147,21 +147,30 @@ ZMakeZcodeRealmAuthentication(register ZNotice_t *notice, result = krb5_mk_req_extended(Z_krb5_ctx, &authctx, 0 /* options */, 0 /* in_data */, creds, authent); krb5_auth_con_free(Z_krb5_ctx, authctx); + /* HOLDING: creds, authent */ if (result) { - krb5_free_creds(Z_krb5_ctx, creds); - return (result); + free(authent); + authent = NULL; } - /* HOLDING: creds, authent */ - - /* Encode the authenticator */ - notice->z_auth = 1; - notice->z_authent_len = authent->length; - zcode_len = authent->length * 2 + 2; /* 2x growth plus Z and null */ - notice->z_ascii_authent = (char *)malloc(zcode_len); - if (!notice->z_ascii_authent) { - krb5_free_data(Z_krb5_ctx, authent); + /* HOLDING: creds */ + if (result == 0 || result == KRB5KRB_AP_ERR_TKT_EXPIRED) { + /* Encode the authenticator */ + notice->z_auth = 1; + if (result == 0) + notice->z_authent_len = authent->length; + else + notice->z_authent_len = 0; + zcode_len = authent->length * 2 + 2; /* 2x growth plus Z and null */ + notice->z_ascii_authent = (char *)malloc(zcode_len); + if (!notice->z_ascii_authent) { + if (authent) + krb5_free_data(Z_krb5_ctx, authent); + krb5_free_creds(Z_krb5_ctx, creds); + return (ENOMEM); + } + } else { krb5_free_creds(Z_krb5_ctx, creds); - return (ENOMEM); + return result; } /* HOLDING: creds, authent, notice->z_ascii_authent */ result = ZMakeZcode(notice->z_ascii_authent, zcode_len, @@ -210,6 +219,7 @@ ZGetCredsRealm(krb5_creds **creds_out, char *realm) { krb5_creds creds_in; + krb5_creds creds_tmp; krb5_ccache ccache; /* XXX make this a global or static?*/ int result; @@ -229,7 +239,18 @@ ZGetCredsRealm(krb5_creds **creds_out, } result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client); - if (!result) + if (!result) { + result = krb5_cc_retrieve_cred(Z_krb5_ctx, ccache, + KRB5_TC_SUPPORTED_KTYPES, &creds_in, &creds_tmp); + if (!result) { + *creds_out = malloc(sizeof(creds_tmp)); + if (*creds_out == NULL) + result = errno; + else + memcpy(*creds_out, &creds_tmp, sizeof(creds_tmp)); + } + } + if (result == KRB5_CC_NOTFOUND) result = krb5_get_credentials(Z_krb5_ctx, 0, ccache, &creds_in, creds_out); krb5_cc_close(Z_krb5_ctx, ccache); -- cgit v1.2.3