From b1cfe96d92ee4b16f129855b649d84f690bdb7a5 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Wed, 10 Jan 1996 03:08:30 +0000 Subject: [PATCH] fwd_tgt.c (krb5_fwd_tgt_creds): New function which handles all of the dirty work of forwarding TGT's. rd_cred.c (krb5_rd_cred_basic): Clean up memory allocation discpline to remove memory leaks. mk_cred.c (krb5_mk_ncred_basic, krb5_mk_ncred, krb5_mk_1cred): Clean up memory allocation discpline to remove memory leaks. init_ctx.c (krb5_get_tgs_ktypes): Clean up parsing of the etype list. Don't overrun the string containing the etype list. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7280 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/krb/ChangeLog | 15 ++++ src/lib/krb5/krb/Makefile.in | 2 + src/lib/krb5/krb/fwd_tgt.c | 147 +++++++++++++++++++++++++++++++++++ src/lib/krb5/krb/init_ctx.c | 7 +- src/lib/krb5/krb/mk_cred.c | 116 ++++++++++++--------------- src/lib/krb5/krb/rd_cred.c | 8 +- 6 files changed, 227 insertions(+), 68 deletions(-) create mode 100644 src/lib/krb5/krb/fwd_tgt.c diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index 3e60282f1..6d5335863 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,18 @@ +Tue Jan 9 22:04:09 1996 Theodore Y. Ts'o + + * fwd_tgt.c (krb5_fwd_tgt_creds): New function which handles all + of the dirty work of forwarding TGT's. + + * rd_cred.c (krb5_rd_cred_basic): Clean up memory allocation + discpline to remove memory leaks. + + * mk_cred.c (krb5_mk_ncred_basic, krb5_mk_ncred, krb5_mk_1cred): + Clean up memory allocation discpline to remove memory + leaks. + + * init_ctx.c (krb5_get_tgs_ktypes): Clean up parsing of the etype + list. Don't overrun the string containing the etype list. + Wed Jan 3 21:32:59 1996 Theodore Y. Ts'o * rd_cred.c (krb5_rd_cred_basic): When the keyblock is NULL, diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index 396cf9e11..e511bbca4 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -30,6 +30,7 @@ OBJS= addr_comp.$(OBJEXT) \ encode_kdc.$(OBJEXT) \ encrypt_tk.$(OBJEXT) \ free_rtree.$(OBJEXT) \ + fwd_tgt.$(OBJEXT) \ gc_frm_kdc.$(OBJEXT) \ gc_via_tkt.$(OBJEXT) \ gen_seqnum.$(OBJEXT) \ @@ -102,6 +103,7 @@ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/encode_kdc.c \ $(srcdir)/encrypt_tk.c \ $(srcdir)/free_rtree.c \ + $(srcdir)/fwd_tgt.c \ $(srcdir)/gc_frm_kdc.c \ $(srcdir)/gc_via_tkt.c \ $(srcdir)/gen_seqnum.c \ diff --git a/src/lib/krb5/krb/fwd_tgt.c b/src/lib/krb5/krb/fwd_tgt.c new file mode 100644 index 000000000..762a41e33 --- /dev/null +++ b/src/lib/krb5/krb/fwd_tgt.c @@ -0,0 +1,147 @@ +/* + * lib/krb5/krb/get_in_tkt.c + * + * Copyright 1995 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. 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. + */ + +#include "k5-int.h" +#include +#include + +/* 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 +krb5_fwd_tgt_creds(context, auth_context, rhost, client, server, cc, + forwardable, outbuf) + krb5_context context; + krb5_auth_context auth_context; + char *rhost; + krb5_principal client; + krb5_principal server; + krb5_ccache cc; + int forwardable; /* Should forwarded TGT also be forwardable? */ + krb5_data *outbuf; +{ + krb5_replay_data replaydata; + krb5_data * scratch; + krb5_address **addrs; + krb5_error_code retval; + krb5_creds creds, tgt; + krb5_creds *pcreds; + krb5_flags kdcoptions; + int close_cc = 0; + int free_rhost = 0; + + memset((char *)&creds, 0, sizeof(creds)); + memset((char *)&tgt, 0, sizeof(creds)); + + if (rhost == NULL) { + if (krb5_princ_type(context, server) != KRB5_NT_SRV_HST) + return(KRB5_FWD_BAD_PRINCIPAL); + + if (krb5_princ_size(context, server) < 2) + return (KRB5_CC_BADNAME); + + rhost = malloc(server->data[1].length+1); + if (!rhost) + return ENOMEM; + free_rhost = 1; + memcpy(rhost, server->data[1].data, server->data[1].length); + rhost[server->data[1].length] = '\0'; + } + + retval = krb5_os_hostaddr(context, rhost, &addrs); + if (retval) + goto errout; + + if ((retval = krb5_copy_principal(context, client, &creds.client))) + goto errout; + + if ((retval = krb5_build_principal_ext(context, &creds.server, + server->realm.length, + server->realm.data, + KRB5_TGS_NAME_SIZE, + KRB5_TGS_NAME, + client->realm.length, + client->realm.data, + 0))) + goto errout; + + if (cc == 0) { + if ((retval = krb5_cc_default(context, &cc))) + goto errout; + close_cc = 1; + } + + /* fetch tgt directly from cache */ + retval = krb5_cc_retrieve_cred (context, cc, KRB5_TC_MATCH_SRV_NAMEONLY, + &creds, &tgt); + 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 (!tgt.ticket.length) { + retval = KRB5_NO_TKT_SUPPLIED; + goto errout; + } + + creds.times = tgt.times; + creds.times.starttime = 0; + 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); + + if (retval) { + krb5_free_data(context, scratch); + } else { + *outbuf = *scratch; + krb5_xfree(scratch); + } + +errout: + if (addrs) + krb5_free_addresses(context, addrs); + if (close_cc) + krb5_cc_close(context, cc); + if (free_rhost) + free(rhost); + krb5_free_cred_contents(context, &creds); + krb5_free_cred_contents(context, &tgt); + return retval; +} + + + diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c index a641d7d08..1850cd8bb 100644 --- a/src/lib/krb5/krb/init_ctx.c +++ b/src/lib/krb5/krb/init_ctx.c @@ -24,6 +24,7 @@ */ #include "k5-int.h" +#include krb5_error_code INTERFACE krb5_init_context(context) @@ -251,10 +252,14 @@ krb5_get_tgs_ktypes(context, princ, ktypes) sp = retval; j = 0; - for (i = 0; i < count; i++) { + i = 1; + while (1) { if (! krb5_string_to_enctype(sp, &old_ktypes[j])) j++; + if (i++ >= count) + break; + /* skip to next token */ while (*sp) sp++; while (! *sp) sp++; diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c index 6c0162dda..ceb8678ad 100644 --- a/src/lib/krb5/krb/mk_cred.c +++ b/src/lib/krb5/krb/mk_cred.c @@ -120,7 +120,6 @@ krb5_mk_ncred_basic(context, ppcreds, nppcreds, keyblock, { krb5_cred_enc_part credenc; krb5_error_code retval; - char * tmp; int i; credenc.magic = KV5M_CRED_ENC_PART; @@ -136,59 +135,56 @@ krb5_mk_ncred_basic(context, ppcreds, nppcreds, keyblock, malloc((size_t) (sizeof(krb5_cred_info *) * (nppcreds + 1)))) == NULL) { return ENOMEM; } - if ((tmp = (char *)malloc((size_t) (sizeof(krb5_cred_info) * nppcreds))) == NULL) { - retval = ENOMEM; - goto cleanup_info; - } - memset(tmp, 0, (size_t) (sizeof(krb5_cred_info) * nppcreds)); - + memset(credenc.ticket_info, 0, sizeof(krb5_cred_info *) * (nppcreds + 1)); + /* * For each credential in the list, initialize a cred info * structure and copy the ticket into the ticket list. */ for (i = 0; i < nppcreds; i++) { - credenc.ticket_info[i] = (krb5_cred_info *)tmp + i; - + credenc.ticket_info[i] = malloc(sizeof(krb5_cred_info)); + if (credenc.ticket_info[i] == NULL) { + retval = ENOMEM; + goto cleanup; + } + credenc.ticket_info[i+1] = NULL; + credenc.ticket_info[i]->magic = KV5M_CRED_INFO; credenc.ticket_info[i]->times = ppcreds[i]->times; credenc.ticket_info[i]->flags = ppcreds[i]->ticket_flags; if ((retval = decode_krb5_ticket(&ppcreds[i]->ticket, &pcred->tickets[i]))) - goto cleanup_info_ptrs; + goto cleanup; if ((retval = krb5_copy_keyblock(context, &ppcreds[i]->keyblock, &credenc.ticket_info[i]->session))) - goto cleanup_info_ptrs; + goto cleanup; if ((retval = krb5_copy_principal(context, ppcreds[i]->client, &credenc.ticket_info[i]->client))) - goto cleanup_info_ptrs; + goto cleanup; if ((retval = krb5_copy_principal(context, ppcreds[i]->server, &credenc.ticket_info[i]->server))) - goto cleanup_info_ptrs; + goto cleanup; if ((retval = krb5_copy_addresses(context, ppcreds[i]->addresses, &credenc.ticket_info[i]->caddrs))) - goto cleanup_info_ptrs; + goto cleanup; } /* * NULL terminate the lists. */ - credenc.ticket_info[i] = NULL; pcred->tickets[i] = NULL; /* encrypt the credential encrypted part */ retval = encrypt_credencpart(context, &credenc, keyblock, &pcred->enc_part); -cleanup_info_ptrs: - free(tmp); - -cleanup_info: - free(credenc.ticket_info); +cleanup: + krb5_free_cred_enc_part(context, &credenc); return retval; } @@ -207,12 +203,20 @@ krb5_mk_ncred(context, auth_context, ppcreds, ppdata, outdata) krb5_data ** ppdata; krb5_replay_data * outdata; { + krb5_address * premote_fulladdr = NULL; + krb5_address * plocal_fulladdr = NULL; + krb5_address remote_fulladdr; + krb5_address local_fulladdr; krb5_error_code retval; krb5_keyblock * keyblock; krb5_replay_data replaydata; krb5_cred * pcred; int ncred; + local_fulladdr.contents = 0; + remote_fulladdr.contents = 0; + memset(&replaydata, 0, sizeof(krb5_replay_data)); + if (ppcreds == NULL) { return KRB5KRB_AP_ERR_BADADDR; } @@ -224,12 +228,14 @@ krb5_mk_ncred(context, auth_context, ppcreds, ppdata, outdata) if ((pcred = (krb5_cred *)malloc(sizeof(krb5_cred))) == NULL) return ENOMEM; + memset(pcred, 0, sizeof(krb5_cred)); if ((pcred->tickets = (krb5_ticket **)malloc(sizeof(krb5_ticket *) * (ncred + 1))) == NULL) { retval = ENOMEM; free(pcred); } + memset(pcred->tickets, 0, sizeof(krb5_ticket *) * (ncred +1)); /* Get keyblock */ if ((keyblock = auth_context->local_subkey) == NULL) @@ -247,19 +253,12 @@ krb5_mk_ncred(context, auth_context, ppcreds, ppdata, outdata) /* Need a better error */ return KRB5_RC_REQUIRED; - if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) || - (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME)) { - if ((retval = krb5_us_timeofday(context, &replaydata.timestamp, - &replaydata.usec))) - return retval; - if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) { - outdata->timestamp = replaydata.timestamp; - outdata->usec = replaydata.usec; - } - if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) { - outdata->timestamp = replaydata.timestamp; - outdata->usec = replaydata.usec; - } + if ((retval = krb5_us_timeofday(context, &replaydata.timestamp, + &replaydata.usec))) + return retval; + if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) { + outdata->timestamp = replaydata.timestamp; + outdata->usec = replaydata.usec; } if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) || (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) { @@ -271,23 +270,13 @@ krb5_mk_ncred(context, auth_context, ppcreds, ppdata, outdata) } } -{ - krb5_address * premote_fulladdr = NULL; - krb5_address * plocal_fulladdr = NULL; - krb5_address remote_fulladdr; - krb5_address local_fulladdr; - CLEANUP_INIT(2); - if (auth_context->local_addr) { if (auth_context->local_port) { - if (!(retval = krb5_make_fulladdr(context, auth_context->local_addr, - auth_context->local_port, - &local_fulladdr))) { - CLEANUP_PUSH(local_fulladdr.contents, free); - plocal_fulladdr = &local_fulladdr; - } else { - goto error; - } + if ((retval = krb5_make_fulladdr(context, auth_context->local_addr, + auth_context->local_port, + &local_fulladdr))) + goto error; + plocal_fulladdr = &local_fulladdr; } else { plocal_fulladdr = auth_context->local_addr; } @@ -295,15 +284,11 @@ krb5_mk_ncred(context, auth_context, ppcreds, ppdata, outdata) if (auth_context->remote_addr) { if (auth_context->remote_port) { - if (!(retval = krb5_make_fulladdr(context,auth_context->remote_addr, + if ((retval = krb5_make_fulladdr(context,auth_context->remote_addr, auth_context->remote_port, - &remote_fulladdr))){ - CLEANUP_PUSH(remote_fulladdr.contents, free); - premote_fulladdr = &remote_fulladdr; - } else { - CLEANUP_DONE(); - goto error; - } + &remote_fulladdr))) + goto error; + premote_fulladdr = &remote_fulladdr; } else { premote_fulladdr = auth_context->remote_addr; } @@ -313,13 +298,9 @@ krb5_mk_ncred(context, auth_context, ppcreds, ppdata, outdata) if ((retval = krb5_mk_ncred_basic(context, ppcreds, ncred, keyblock, &replaydata, plocal_fulladdr, premote_fulladdr, pcred))) { - CLEANUP_DONE(); goto error; } - CLEANUP_DONE(); -} - if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) { krb5_donot_replay replay; @@ -342,12 +323,16 @@ krb5_mk_ncred(context, auth_context, ppcreds, ppdata, outdata) retval = encode_krb5_cred(pcred, ppdata); error: + if (local_fulladdr.contents) + free(local_fulladdr.contents); + if (remote_fulladdr.contents) + free(remote_fulladdr.contents); + krb5_free_cred(context, pcred); + if (retval) { if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) || (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) auth_context->local_seq_number--; - free(pcred->tickets); - free(pcred); } return retval; } @@ -375,9 +360,10 @@ krb5_mk_1cred(context, auth_context, pcreds, ppdata, outdata) ppcreds[0] = pcreds; ppcreds[1] = NULL; - if ((retval = krb5_mk_ncred(context, auth_context, ppcreds, - ppdata, outdata))) - free(ppcreds); + retval = krb5_mk_ncred(context, auth_context, ppcreds, + ppdata, outdata); + + free(ppcreds); return retval; } diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c index d515b7b60..874960bf5 100644 --- a/src/lib/krb5/krb/rd_cred.c +++ b/src/lib/krb5/krb/rd_cred.c @@ -95,6 +95,8 @@ krb5_rd_cred_basic(context, pcreddata, pkeyblock, local_addr, remote_addr, if ((retval = decode_krb5_cred(pcreddata, &pcred))) return retval; + memset(&encpart, sizeof(encpart), 0); + if ((retval = decrypt_credencdata(context, pcred, pkeyblock, &encpart))) goto cleanup_cred; @@ -147,6 +149,7 @@ krb5_rd_cred_basic(context, pcreddata, pkeyblock, local_addr, remote_addr, retval = ENOMEM; goto cleanup_cred; } + (*pppcreds)[0] = NULL; /* * For each credential, create a strcture in the list of @@ -163,6 +166,7 @@ krb5_rd_cred_basic(context, pcreddata, pkeyblock, local_addr, remote_addr, } (*pppcreds)[i] = pcur; + (*pppcreds)[i+1] = 0; pinfo = encpart.ticket_info[i++]; memset(pcur, 0, sizeof(krb5_creds)); @@ -204,11 +208,11 @@ krb5_rd_cred_basic(context, pcreddata, pkeyblock, local_addr, remote_addr, cleanup: if (retval) - while (i >= 0) - free((*pppcreds)[i--]); + krb5_free_tgt_creds(context, *pppcreds); cleanup_cred: krb5_free_cred(context, pcred); + krb5_free_cred_enc_part(context, &encpart); return retval; } -- 2.26.2