fwd_tgt.c (krb5_fwd_tgt_creds): New function which handles all of the
authorTheodore Tso <tytso@mit.edu>
Wed, 10 Jan 1996 03:08:30 +0000 (03:08 +0000)
committerTheodore Tso <tytso@mit.edu>
Wed, 10 Jan 1996 03:08:30 +0000 (03:08 +0000)
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
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/fwd_tgt.c [new file with mode: 0644]
src/lib/krb5/krb/init_ctx.c
src/lib/krb5/krb/mk_cred.c
src/lib/krb5/krb/rd_cred.c

index 3e60282f1b723383547f3d29ac5a62f7aa4f1ee8..6d5335863fd92d2d8483cd1d2c96cdba3194f55d 100644 (file)
@@ -1,3 +1,18 @@
+Tue Jan  9 22:04:09 1996  Theodore Y. Ts'o  <tytso@dcl>
+
+       * 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  <tytso@dcl>
 
        * rd_cred.c (krb5_rd_cred_basic): When the keyblock is NULL,
index 396cf9e11cb10197bb50c56cbe175b39c842a56f..e511bbca4beb5be6f1bf06166a35c18130c10008 100644 (file)
@@ -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 (file)
index 0000000..762a41e
--- /dev/null
@@ -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 <memory.h>
+#include <netdb.h>
+
+/* 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;
+}
+
+
+
index a641d7d088767377aa299cebbe4fdbe3a7624088..1850cd8bb5a6dee4449eab51bc26646efb711553 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include "k5-int.h"
+#include <ctype.h>
 
 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++;
index 6c0162dda495f4031bc72b523cea58ec627d2965..ceb8678ad51897e6f9b3ce7fdd17592477a46de7 100644 (file)
@@ -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;
 }
 
index d515b7b60aa304353d98f5e4fa469642f55e3243..874960bf510168897648baf9827ec86691239016 100644 (file)
@@ -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;
 }