summaryrefslogtreecommitdiff
path: root/lib/ZMkAuth.c
diff options
context:
space:
mode:
authorGravatar Karl Ramm <kcr@1ts.org>2010-08-22 00:56:20 +0000
committerGravatar Karl Ramm <kcr@1ts.org>2010-08-22 00:56:20 +0000
commitb76f80d4acb7b3d63ae119f91c15cded1f606f47 (patch)
treea5dfff3c7760b69b62a97fbf2a7853e2847c251f /lib/ZMkAuth.c
parent8035bb6746b5cf9f8ee23bc98bee8dfd74c25c3f (diff)
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.
Diffstat (limited to 'lib/ZMkAuth.c')
-rw-r--r--lib/ZMkAuth.c47
1 files changed, 34 insertions, 13 deletions
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);