From e4c08a665fdf617958c2cbea947c2e57332d268d Mon Sep 17 00:00:00 2001 From: Chris Provenzano Date: Wed, 26 Apr 1995 02:58:00 +0000 Subject: [PATCH] * forward.c (rd_and_store_for_creds()) : Rewritten to use auth_context and the new krb5_rd_creds(). * forward.c (get_for_creds()) : New function replacing krb5_get_for_creds() and uses auth_context and new krb5_mk_creds() routine. * kerberos5.c (kerberos5_send()): Set initial flags on auth_context to KRB5_AUTH_CONTEXT_RET_TIME, and use new rd_and_store_for_creds() routine. * kerberos5.c (kerberos5_forward()): Use the new get_for_creds(). git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5485 dc483132-0cff-0310-8789-dd5450dbe970 --- src/appl/telnet/libtelnet/ChangeLog | 12 ++ src/appl/telnet/libtelnet/forward.c | 191 ++++++++++++++++++++++---- src/appl/telnet/libtelnet/kerberos5.c | 113 ++++++--------- 3 files changed, 218 insertions(+), 98 deletions(-) diff --git a/src/appl/telnet/libtelnet/ChangeLog b/src/appl/telnet/libtelnet/ChangeLog index a9a555b61..31aeb4c10 100644 --- a/src/appl/telnet/libtelnet/ChangeLog +++ b/src/appl/telnet/libtelnet/ChangeLog @@ -1,3 +1,15 @@ +Tue Apr 25 21:23:28 1995 Chris Provenzano (proven@mit.edu) + + * forward.c (rd_and_store_for_creds()) : Rewritten to use + auth_context and the new krb5_rd_creds(). + * forward.c (get_for_creds()) : New function replacing + krb5_get_for_creds() and uses auth_context and new + krb5_mk_creds() routine. + * kerberos5.c (kerberos5_send()): Set initial flags on auth_context + to KRB5_AUTH_CONTEXT_RET_TIME, and use new + rd_and_store_for_creds() routine. + * kerberos5.c (kerberos5_forward()): Use the new get_for_creds(). + Sat Apr 22 00:50:14 1995 Theodore Y. Ts'o (tytso@dcl) * kerberos5.c (kerberos5_init): Only call krb5_init_context if diff --git a/src/appl/telnet/libtelnet/forward.c b/src/appl/telnet/libtelnet/forward.c index f80f6b155..ac42885ca 100644 --- a/src/appl/telnet/libtelnet/forward.c +++ b/src/appl/telnet/libtelnet/forward.c @@ -23,55 +23,194 @@ /* General-purpose forwarding routines. These routines may be put into */ /* libkrb5.a to allow widespread use */ -#if defined(KRB5) && defined(FORWARD) +#if defined(KERBEROS) || defined(KRB5) #include #include #include - -#include "krb5.h" - + +#include "k5-int.h" + /* Decode, decrypt and store the forwarded creds in the local ccache. */ krb5_error_code -rd_and_store_for_creds(context, inbuf, ticket, lusername) - krb5_context context; - krb5_data *inbuf; - krb5_ticket *ticket; - char *lusername; +rd_and_store_for_creds(context, auth_context, inbuf, ticket, lusername) + krb5_context context; + krb5_auth_context * auth_context; + krb5_data *inbuf; + krb5_ticket *ticket; + char *lusername; { - krb5_creds creds; + krb5_creds **creds; krb5_error_code retval; char ccname[35]; krb5_ccache ccache = NULL; struct passwd *pwd; - if (retval = krb5_rd_cred(context, inbuf, ticket->enc_part2->session, - &creds, 0, 0)) { - return(retval); - } - - if (!(pwd = (struct passwd *) getpwnam(lusername))) { + if (!(pwd = (struct passwd *) getpwnam(lusername))) return -1; - } + + if (retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)) + return(retval); sprintf(ccname, "FILE:/tmp/krb5cc_%d", pwd->pw_uid); - if (retval = krb5_cc_resolve(context, ccname, &ccache)) { - return(retval); + if (retval = krb5_cc_resolve(context, ccname, &ccache)) + goto cleanup; + + if (retval = krb5_cc_initialize(context, ccache, ticket->enc_part2->client)) + goto cleanup; + + if (retval = krb5_cc_store_cred(context, ccache, *creds)) + goto cleanup; + + if (retval = chown(ccname+5, pwd->pw_uid, -1)) + goto cleanup; + +cleanup: + krb5_free_creds(context, *creds); + return retval; +} + + +#define KRB5_DEFAULT_LIFE 60*60*8 /* 8 hours */ +/* helper function: convert flags to necessary KDC options */ +#define flags2options(flags) (flags & KDC_TKT_COMMON_MASK) + +/* Get a TGT for use at the remote host */ +krb5_error_code INTERFACE +get_for_creds(context, auth_context, rhost, client, forwardable, outbuf) + krb5_context context; + krb5_auth_context * auth_context; + char *rhost; + krb5_principal client; + int forwardable; /* Should forwarded TGT also be forwardable? */ + krb5_data *outbuf; +{ + krb5_replay_data replaydata; + krb5_data * scratch; + struct hostent *hp; + krb5_address **addrs; + krb5_error_code retval; + krb5_error *err_reply; + krb5_creds creds, tgt; + krb5_creds *pcreds; + krb5_ccache cc; + krb5_flags kdcoptions; + krb5_timestamp now; + char *remote_host = 0; + char **hrealms = 0; + int i; + + memset((char *)&creds, 0, sizeof(creds)); + + if (!rhost || !(hp = gethostbyname(rhost))) + return KRB5_ERR_BAD_HOSTNAME; + + remote_host = (char *) malloc(strlen(hp->h_name)+1); + if (!remote_host) { + retval = ENOMEM; + goto errout; + } + strcpy(remote_host, hp->h_name); + + if (retval = krb5_get_host_realm(context, remote_host, &hrealms)) + goto errout; + if (!hrealms[0]) { + retval = KRB5_ERR_HOST_REALM_UNKNOWN; + goto errout; } - if (retval = krb5_cc_initialize(context, ccache, - ticket->enc_part2->client)) { - return(retval); + /* Count elements */ + for(i=0; hp->h_addr_list[i]; i++); + + addrs = (krb5_address **) malloc ((i+1)*sizeof(*addrs)); + if (!addrs) { + retval = ENOMEM; + goto errout; } + memset(addrs, 0, (i+1)*sizeof(*addrs)); + + for(i=0; hp->h_addr_list[i]; i++) { + addrs[i] = (krb5_address *) malloc(sizeof(krb5_address)); + if (!addrs[i]) { + retval = ENOMEM; + goto errout; + } + addrs[i]->addrtype = hp->h_addrtype; + addrs[i]->length = hp->h_length; + addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); + if (!addrs[i]->contents) { + retval = ENOMEM; + goto errout; + } + memcpy ((char *)addrs[i]->contents, hp->h_addr_list[i], + addrs[i]->length); + } + addrs[i] = 0; - if (retval = krb5_cc_store_cred(context, ccache, &creds)) { - return(retval); + if (retval = krb5_copy_principal(context, client, &creds.client)) + goto errout; + + if (retval = krb5_build_principal_ext(context, &creds.server, + strlen(hrealms[0]), + hrealms[0], + KRB5_TGS_NAME_SIZE, + KRB5_TGS_NAME, + client->realm.length, + client->realm.data, + 0)) + goto errout; + + creds.times.starttime = 0; + if (retval = krb5_timeofday(context, &now)) + goto errout; + + creds.times.endtime = now + KRB5_DEFAULT_LIFE; + creds.times.renew_till = 0; + + if (retval = krb5_cc_default(context, &cc)) + goto errout; + + /* fetch tgt directly from cache */ + retval = krb5_cc_retrieve_cred (context, cc, KRB5_TC_MATCH_SRV_NAMEONLY, + &creds, &tgt); + krb5_cc_close(context, cc); + if (retval) + goto errout; + + /* tgt->client must be equal to creds.client */ + if (!krb5_principal_compare(context, tgt.client, creds.client)) { + retval = KRB5_PRINC_NOMATCH; + goto errout; } - if (retval = chown(ccname+5, pwd->pw_uid, -1)) { - return(retval); + if (!tgt.ticket.length) { + retval = KRB5_NO_TKT_SUPPLIED; + goto errout; } + kdcoptions = flags2options(tgt.ticket_flags)|KDC_OPT_FORWARDED; + + if (!forwardable) /* Reset KDC_OPT_FORWARDABLE */ + kdcoptions &= ~(KDC_OPT_FORWARDABLE); + + if (retval = krb5_get_cred_via_tkt(context, &tgt, kdcoptions, + addrs, &creds, &pcreds)) + goto errout; + + retval = krb5_mk_1cred(context, auth_context, pcreds, + &scratch, &replaydata); + krb5_free_creds(context, pcreds); + *outbuf = *scratch; + krb5_xfree(scratch); + +errout: + if (remote_host) + free(remote_host); + if (hrealms) + krb5_xfree(hrealms); + if (addrs) + krb5_free_addresses(context, addrs); + krb5_free_cred_contents(context, &creds); return retval; } diff --git a/src/appl/telnet/libtelnet/kerberos5.c b/src/appl/telnet/libtelnet/kerberos5.c index 5f1685e65..af7a3cb4a 100644 --- a/src/appl/telnet/libtelnet/kerberos5.c +++ b/src/appl/telnet/libtelnet/kerberos5.c @@ -74,6 +74,7 @@ #include "misc.h" extern auth_debug_mode; +extern int net; #ifdef FORWARD int forward_flags = 0; /* Flags get set in telnet/main.c on -f and -F */ @@ -251,9 +252,19 @@ kerberos5_send(ap) ap_opts |= AP_OPTS_USE_SUBKEY; #endif /* ENCRYPTION */ - auth_context = 0; - r = krb5_mk_req_extended(telnet_context, &auth_context, ap_opts, - NULL, new_creds, &auth); + if (r = krb5_auth_con_init(telnet_context, &auth_context)) { + if (auth_debug_mode) { + printf("Kerberos V5: failed to init auth_context (%s)\r\n", + error_message(r)); + } + return(0); + } + + krb5_auth_con_setflags(telnet_context, auth_context, + KRB5_AUTH_CONTEXT_RET_TIME); + + r = krb5_mk_req_extended(telnet_context, &auth_context, ap_opts, + NULL, new_creds, &auth); #ifdef ENCRYPTION krb5_auth_con_getlocalsubkey(telnet_context, auth_context, &newkey); @@ -405,10 +416,13 @@ kerberos5_is(ap, data, cnt) break; #ifdef FORWARD case KRB_FORWARD: - inbuf.data = (char *)data; inbuf.length = cnt; - if (r = rd_and_store_for_creds(telnet_context, &inbuf, ticket, - UserNameRequested)) { + inbuf.data = (char *)data; + if ((r = krb5_auth_con_genaddrs(telnet_context, auth_context, + net, KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) || + (r = rd_and_store_for_creds(telnet_context, auth_context, + &inbuf, ticket, UserNameRequested))) { + char errbuf[128]; (void) strcpy(errbuf, "Read forwarded creds failed: "); @@ -605,99 +619,54 @@ kerberos5_printsub(data, cnt, buf, buflen) } #ifdef FORWARD - void + +void kerberos5_forward(ap) Authenticator *ap; { - krb5_creds *local_creds, * new_creds; krb5_error_code r; - krb5_data forw_creds; - extern krb5_cksumtype krb5_kdc_req_sumtype; krb5_ccache ccache; - - if (!(local_creds = (krb5_creds *) - calloc(1, sizeof(*local_creds)))) { - if (auth_debug_mode) - printf("Kerberos V5: could not allocate memory for credentials\r\n"); - return; - } - - if (r = krb5_sname_to_principal(telnet_context, RemoteHostName, "host", - KRB5_NT_SRV_HST, &local_creds->server)) { - if (auth_debug_mode) - printf("Kerberos V5: could not build server name - %s\r\n", - error_message(r)); - krb5_free_creds(telnet_context, local_creds); - return; - } - - if (telnet_krb5_realm != NULL) { - krb5_data rdata; - - rdata.length = strlen(telnet_krb5_realm); - rdata.data = (char *) malloc(rdata.length + 1); - if (rdata.data == NULL) { - fprintf(stderr, "malloc failed\n"); - return; - } - strcpy(rdata.data, telnet_krb5_realm); - krb5_princ_set_realm(telnet_context, local_creds->server, &rdata); - } + krb5_principal client; + krb5_data forw_creds; if (r = krb5_cc_default(telnet_context, &ccache)) { if (auth_debug_mode) - printf("Kerberos V5: could not get default ccache - %s\r\n", - error_message(r)); - krb5_free_creds(telnet_context, local_creds); + printf("Kerberos V5: could not get default ccache - %s\r\n", + error_message(r)); return; } - if (r = krb5_cc_get_principal(telnet_context,ccache,&local_creds->client)) { + if (r = krb5_cc_get_principal(telnet_context, ccache, &client)) { if (auth_debug_mode) - printf("Kerberos V5: could not get default principal - %s\r\n", - error_message(r)); - krb5_free_creds(telnet_context, local_creds); + printf("Kerberos V5: could not get default principal - %s\r\n", + error_message(r)); return; } - /* Get ticket from credentials cache */ - if (r = krb5_get_credentials(telnet_context, KRB5_GC_CACHED, - ccache, local_creds, &new_creds)) { - if (auth_debug_mode) - printf("Kerberos V5: could not obtain credentials - %s\r\n", - error_message(r)); - krb5_free_creds(telnet_context, local_creds); - krb5_free_creds(telnet_context, new_creds); + if (r = krb5_auth_con_genaddrs(telnet_context, auth_context, net, + KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR)) { + if (auth_debug_mode) + printf("Kerberos V5: could not gen local full address - %s\r\n", + error_message(r)); return; } - if (r = krb5_get_for_creds(telnet_context, - krb5_kdc_req_sumtype, - RemoteHostName, - new_creds->client, - &new_creds->keyblock, - forward_flags & OPTS_FORWARDABLE_CREDS, - &forw_creds)) { + if (r = get_for_creds(telnet_context, auth_context, RemoteHostName, client, + forward_flags & OPTS_FORWARDABLE_CREDS, &forw_creds)){ if (auth_debug_mode) - printf("Kerberos V5: error getting forwarded creds - %s\r\n", - error_message(r)); - krb5_free_creds(telnet_context, local_creds); - krb5_free_creds(telnet_context, new_creds); + printf("Kerberos V5: error getting forwarded creds - %s\r\n", + error_message(r)); return; } /* Send forwarded credentials */ if (!Data(ap, KRB_FORWARD, forw_creds.data, forw_creds.length)) { if (auth_debug_mode) - printf("Not enough room for authentication data\r\n"); - } - else { + printf("Not enough room for authentication data\r\n"); + } else { if (auth_debug_mode) - printf("Forwarded local Kerberos V5 credentials to server\r\n"); + printf("Forwarded local Kerberos V5 credentials to server\r\n"); } - - krb5_free_creds(telnet_context, local_creds); - krb5_free_creds(telnet_context, new_creds); } #endif /* FORWARD */ -- 2.26.2