From c357237a23785092f1d5b46824612a3ba3720b3a Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 1 Apr 2004 20:43:06 +0000 Subject: [PATCH] kfw-ak5log-20040401 Remove internally defined life_to_time. Instead rely on version in rxkad Use kvno = RXKAD_TKT_TYPE_KERBEROS_V5 when setting tokens. No longer use krb524d. Fix the assignment of the username and instance to place the instance within the aclient.instance field instead of appended to the aclient.name field. --- src/WINNT/client_creds/afskfw.c | 154 +++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 73 deletions(-) diff --git a/src/WINNT/client_creds/afskfw.c b/src/WINNT/client_creds/afskfw.c index 376ce09..c2cf18f 100644 --- a/src/WINNT/client_creds/afskfw.c +++ b/src/WINNT/client_creds/afskfw.c @@ -62,6 +62,7 @@ #include "creds.h" #include +#include /* for life_to_time */ /* * TIMING _____________________________________________________________________ @@ -2471,64 +2472,6 @@ static const int tkt_lifetimes[TKTLIFENUMFIXED] = { 2592000}; /* 720.00 hours, 30.00 days */ -/* - * KFW_KRB4_life_to_time - takes a start time and a Kerberos standard - * lifetime char and returns the corresponding end time. There are - * four simple cases to be handled. The first is a life of 0xff, - * meaning no expiration, and results in an end time of 0xffffffff. - * The second is when life is less than the values covered by the - * table. In this case, the end time is the start time plus the - * number of 5 minute intervals specified by life. The third case - * returns start plus the MAXTKTLIFETIME if life is greater than - * TKTLIFEMAXFIXED. The last case, uses the life value (minus - * TKTLIFEMINFIXED) as an index into the table to extract the lifetime - * in seconds, which is added to start to produce the end time. - */ -static u_int32_t -KFW_KRB4_life_to_time(u_int32_t start, int life_) -{ - unsigned char life = (unsigned char) life_; - - if (no_long_lifetimes) return start + life*5*60; - - if (life == TKTLIFENOEXPIRE) return NEVERDATE; - if (life < TKTLIFEMINFIXED) return start + life*5*60; - if (life > TKTLIFEMAXFIXED) return start + MAXTKTLIFETIME; - return start + tkt_lifetimes[life - TKTLIFEMINFIXED]; -} - -/* - * KFW_KRB4_time_to_life - takes start and end times for the ticket and - * returns a Kerberos standard lifetime char, possibily using the - * tkt_lifetimes table for lifetimes above 127*5 minutes. First, the - * special case of (end == NEVERDATE) is handled to mean no - * expiration. Then negative lifetimes and those greater than the - * maximum ticket lifetime are rejected. Then lifetimes less than the - * first table entry are handled by rounding the requested lifetime - * *up* to the next 5 minute interval. The final step is to search - * the table for the smallest entry *greater than or equal* to the - * requested entry. - */ -static int -KFW_KRB4_time_to_life(u_int32_t start, u_int32_t end) -{ - int i; - long lifetime = end - start; - - if (no_long_lifetimes) return (lifetime + 5*60 - 1)/(5*60); - - if (end >= NEVERDATE) return TKTLIFENOEXPIRE; - if (lifetime > MAXTKTLIFETIME || lifetime <= 0) return 0; - if (lifetime < tkt_lifetimes[0]) return (lifetime + 5*60 - 1)/(5*60); - for (i=0; iticket.length > MAXKTCTICKETLEN) + goto try_krb524d; + + memset(&aserver, '\0', sizeof(aserver)); + strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1); + strncpy(aserver.cell, CellName, MAXKTCREALMLEN - 1); + + memset(&atoken, '\0', sizeof(atoken)); + atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5; + atoken.startTime = k5creds->times.starttime; + atoken.endTime = k5creds->times.endtime; + memcpy(&atoken.sessionKey, k5creds->keyblock.contents, k5creds->keyblock.length); + atoken.ticketLen = k5creds->ticket.length; + memcpy(atoken.ticket, k5creds->ticket.data, atoken.ticketLen); + + retry_gettoken5: + rc = pktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient); + if (rc != 0 && rc != KTC_NOENT && rc != KTC_NOCELL) { + if ( rc == KTC_NOCM && retry < 20 ) { + Sleep(500); + retry++; + goto retry_gettoken5; + } + goto try_krb524d; + } + + if (atoken.kvno == btoken.kvno && + atoken.ticketLen == btoken.ticketLen && + !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) && + !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) + { + /* Success - Nothing to do */ + goto cleanup; + } + + // * Reset the "aclient" structure before we call ktc_SetToken. + // * This structure was first set by the ktc_GetToken call when + // * we were comparing whether identical tokens already existed. + + len = min(k5creds->client->data[0].length,MAXKTCNAMELEN - 1); + strncpy(aclient.name, k5creds->client->data[0].data, len); + aclient.name[len] = '\0'; + + if ( k5creds->client->length > 1 ) { + len = min(k5creds->client->data[1].length,MAXKTCNAMELEN - 1); + strncpy(aclient.instance, k5creds->client->data[1].data, len); + aclient.instance[len] = '\0'; + } else + aclient.instance[0] = '\0'; + len = min(k5creds->client->realm.length,MAXKTCNAMELEN - 1); + strncpy(aclient.cell, k5creds->client->realm.data, len); + aclient.cell[len] = '\0'; + + rc = pktc_SetToken(&aserver, &atoken, &aclient, 0); + if (!rc) + goto cleanup; /* We have successfully inserted the token */ + + try_krb524d: + /* Otherwise, the ticket could have been too large so try to + * convert using the krb524d running with the KDC + */ code = pkrb524_convert_creds_kdc(ctx, k5creds, &creds); pkrb5_free_creds(ctx, k5creds); if (code) { @@ -2784,17 +2795,10 @@ KFW_AFS_klog( strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1); strncpy(aserver.cell, CellName, MAXKTCREALMLEN - 1); - strcpy(username, creds.pname); - if (creds.pinst[0]) - { - strcat(username, "."); - strcat(username, creds.pinst); - } - memset(&atoken, '\0', sizeof(atoken)); atoken.kvno = creds.kvno; atoken.startTime = creds.issue_date; - atoken.endTime = creds.issue_date + KFW_KRB4_life_to_time(0,creds.lifetime); + atoken.endTime = creds.issue_date + life_to_time(0,creds.lifetime); memcpy(&atoken.sessionKey, creds.session, 8); atoken.ticketLen = creds.ticket_st.length; memcpy(atoken.ticket, creds.ticket_st.dat, atoken.ticketLen); @@ -2824,8 +2828,8 @@ KFW_AFS_klog( // * This structure was first set by the ktc_GetToken call when // * we were comparing whether identical tokens already existed. - strncpy(aclient.name, username, MAXKTCNAMELEN - 1); - strcpy(aclient.instance, ""); + strncpy(aclient.name, creds.pname, MAXKTCNAMELEN - 1); + strcpy(aclient.instance, creds.pinst); strncpy(aclient.cell, creds.realm, MAXKTCREALMLEN - 1); if (rc = pktc_SetToken(&aserver, &atoken, &aclient, 0)) @@ -2836,6 +2840,10 @@ KFW_AFS_klog( } cleanup: + if (cname) + pkrb5_free_unparsed_name(ctx,cname); + if (sname) + pkrb5_free_unparsed_name(ctx,sname); if (client_principal) pkrb5_free_principal(ctx,client_principal); /* increds.client == client_principal */ -- 1.9.4