* get_in_tkt.c (krb5_get_in_tkt())
authorChris Provenzano <proven@mit.edu>
Wed, 8 Feb 1995 01:36:24 +0000 (01:36 +0000)
committerChris Provenzano <proven@mit.edu>
Wed, 8 Feb 1995 01:36:24 +0000 (01:36 +0000)
* in_tkt_sky.c (krb5_get_in_tkt_with_skey())
* in_tkt_pwd.c (krb5_get_in_tkt_with_password())
Removed krb5_keytype, changed krb5_enctype to krb5_enctype *,
changed krb5_preauthtype to krb5_preauthtype *.

Changed the args to the key_proc arg of krb5_get_in_tkt()
to be the following (krb5_context, const krb5_keytype,
krb5_data *, krb5_const_pointer, krb5_keyblock **)

* in_tkt_ktb.c (krb5_get_in_tkt_with_keytab()) Added this routine
to replace krb5_get_in_tkt_with_skey() in kinit.

* Makefile.in Added new source file in_tkt_ktb.c.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4922 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/get_in_tkt.c
src/lib/krb5/krb/in_tkt_ktb.c [new file with mode: 0644]
src/lib/krb5/krb/in_tkt_pwd.c
src/lib/krb5/krb/in_tkt_sky.c

index 4cf6e21841e8f735a83f1773b02adba213bc3d67..31131cc1fcd4191fed175f5913dfafc4eeb31e9d 100644 (file)
@@ -1,3 +1,20 @@
+Mon Feb 06 17:19:04 1995 Chris Provenzano  (proven@mit.edu)
+
+       * get_in_tkt.c (krb5_get_in_tkt())
+       * in_tkt_sky.c (krb5_get_in_tkt_with_skey())
+       * in_tkt_pwd.c (krb5_get_in_tkt_with_password())
+               Removed krb5_keytype, changed krb5_enctype to krb5_enctype *,
+               changed krb5_preauthtype to krb5_preauthtype *.
+
+               Changed the args to the key_proc arg of krb5_get_in_tkt()
+               to be the following (krb5_context, const krb5_keytype, 
+               krb5_data *, krb5_const_pointer, krb5_keyblock **)
+
+       * in_tkt_ktb.c (krb5_get_in_tkt_with_keytab()) Added this routine
+               to replace krb5_get_in_tkt_with_skey() in kinit.
+
+       * Makefile.in Added new source file in_tkt_ktb.c.
+               
 Fri Feb  3 16:41:19 1995  Mark Eichin  (eichin@cygnus.com)
 
        * get_in_tkt.c (krb5_get_in_tkt): also check for the version
index db9c586efddc2902860cd80a6dce76a0cb4455e2..64aab2a812d4289416e6a6eb27fe9bb10f81f3c4 100644 (file)
@@ -37,6 +37,7 @@ OBJS= addr_comp.o     \
        get_creds.o     \
        get_fcreds.o    \
        get_in_tkt.o    \
+       in_tkt_ktb.o    \
        in_tkt_pwd.o    \
        in_tkt_sky.o    \
        init_ctx.o      \
@@ -101,6 +102,7 @@ SRCS=       $(srcdir)/addr_comp.c   \
        $(srcdir)/get_creds.c   \
        $(srcdir)/get_fcreds.c \
        $(srcdir)/get_in_tkt.c  \
+       $(srcdir)/in_tkt_ktb.c  \
        $(srcdir)/in_tkt_pwd.c  \
        $(srcdir)/in_tkt_sky.c  \
        $(srcdir)/init_ctx.c    \
index 8cc5ae99e06907a3e4945b7ef33c4b0850d792e1..8275fa27f1e3f59fd86a8e077111bb6a20332b83 100644 (file)
 
  Attempts to get an initial ticket for creds->client to use server
  creds->server, (realm is taken from creds->client), with options
- options, requesting encryption type etype, and using
- creds->times.starttime,  creds->times.endtime,  creds->times.renew_till
- as from, till, and rtime.  creds->times.renew_till is ignored unless
- the RENEWABLE option is requested.
+ options, and using creds->times.starttime, creds->times.endtime,
+ creds->times.renew_till as from, till, and rtime.  
+ creds->times.renew_till is ignored unless the RENEWABLE option is requested.
 
  key_proc is called to fill in the key to be used for decryption.
  keyseed is passed on to key_proc.
@@ -67,24 +66,22 @@ extern krb5_deltat krb5_clockskew;
 
 typedef krb5_error_code (*git_key_proc) PROTOTYPE((krb5_context,
                                                   const krb5_keytype,
-                                                  krb5_keyblock **,
+                                                  krb5_data *,
                                                   krb5_const_pointer,
-                                                  krb5_pa_data **));
+                                                  krb5_keyblock **));
 
 typedef krb5_error_code (*git_decrypt_proc) PROTOTYPE((krb5_context,
                                                       const krb5_keyblock *,
                                                       krb5_const_pointer,
                                                       krb5_kdc_rep * ));
 krb5_error_code
-krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
-               key_proc, keyseed, decrypt_proc, decryptarg, creds,
-               ccache, ret_as_reply)
+krb5_get_in_tkt(context, options, addrs, etypes, ptypes, key_proc, keyseed,
+               decrypt_proc, decryptarg, creds, ccache, ret_as_reply)
     krb5_context context;
     const krb5_flags options;
     krb5_address * const * addrs;
-    const krb5_preauthtype pre_auth_type;
-    const krb5_enctype etype;
-    const krb5_keytype keytype;
+    krb5_enctype * etypes;
+    krb5_preauthtype * ptypes;
     git_key_proc key_proc;
     krb5_const_pointer keyseed;
     git_decrypt_proc decrypt_proc;
@@ -93,6 +90,8 @@ krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
     krb5_ccache ccache;
     krb5_kdc_rep ** ret_as_reply;
 {
+    krb5_keytype keytype;
+    krb5_enctype etype;
     krb5_kdc_req request;
     krb5_kdc_rep *as_reply = 0;
     krb5_error *err_reply;
@@ -100,9 +99,10 @@ krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
     krb5_data *packet;
     krb5_data reply;
     krb5_keyblock *decrypt_key = 0;
-    krb5_enctype etypes[1];
     krb5_timestamp time_now;
     krb5_pa_data       *padata;
+    int f_salt = 0, use_salt = 0;
+    krb5_data salt;
     char k4_version;           /* same type as *(krb5_data::data) */
 
     if (! krb5_realm_compare(context, creds->client, creds->server))
@@ -119,10 +119,12 @@ krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
 
     reply.data = 0;
 
-    if (pre_auth_type == KRB5_PADATA_NONE) {
+    if (1) {
            decrypt_key = 0;
            request.padata = 0;
     } else {
+           /* Pre authentication is not yet supported */
+
            /*
             * First, we get the user's key.  We assume we will need
             * it for the pre-authentication.  Actually, this could
@@ -134,7 +136,7 @@ krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
             * default.  But if we're changing salts, because of a
             * realm renaming, or some such, this won't work.
             */
-           retval = (*key_proc)(context, keytype, &decrypt_key, keyseed, 0);
+/*    retval = (*key_proc)(context, keytype, &decrypt_key, keyseed, 0); */
            if (retval)
                    return retval;
            request.padata = (krb5_pa_data **) malloc(sizeof(krb5_pa_data *)
@@ -144,12 +146,12 @@ krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
                goto cleanup;
            }
            
-           retval = krb5_obtain_padata(context, pre_auth_type, creds->client,
+         /*  retval = krb5_obtain_padata(context, ptypes[0], creds->client,
                                        request.addresses, decrypt_key,
-                                       &padata);
+                                       &padata); */
            if (retval)
                goto cleanup;
-           request.padata[0] = padata;
+/*         request.padata[0] = padata; */
            request.padata[1] = 0;
     }
     
@@ -166,13 +168,15 @@ krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
     /* XXX we know they are the same size... */
     request.nonce = (krb5_int32) time_now;
 
-    etypes[0] = etype;
-    request.etype = etypes;
-    request.netypes = 1;
-    request.second_ticket = 0;
+    if (etypes) 
+       request.etype = etypes;
+    else 
+       krb5_get_default_in_tkt_etypes(context, &request.etype);
+    for (request.netypes = 0;request.etype[request.netypes];request.netypes++);
     request.authorization_data.ciphertext.length = 0;
     request.authorization_data.ciphertext.data = 0;
     request.unenc_authdata = 0;
+    request.second_ticket = 0;
 
     /* encode & send to KDC */
     if (retval = encode_krb5_as_req(&request, &packet))
@@ -238,12 +242,36 @@ krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
        goto cleanup;
     }
 
-    /* it was a kdc_rep--decrypt & check */
+    /* Encryption type, keytype, */
+    etype = as_reply->ticket->enc_part.etype;
+    keytype = krb5_csarray[etype]->system->proto_keytype;
+
+    /* and salt */
+    if (as_reply->padata) {
+       krb5_pa_data **ptr;
+
+        for (ptr = as_reply->padata; *ptr; ptr++) {
+            if ((*ptr)->pa_type == KRB5_PADATA_PW_SALT) {
+                /* use KDC-supplied salt, instead of default */
+                salt.data = (char *)(*ptr)->contents;
+                salt.length = (*ptr)->length;
+                use_salt = 1;
+                break;
+            }
+        }
+    } 
+    if (!use_salt) {
+        /* need to use flattened principal */
+        if (retval = krb5_principal2salt(context, creds->client, &salt))
+            return(retval);
+        f_salt = 1;
+    }
 
-     /* Generate the key, if we haven't done so already. */
+    /* it was a kdc_rep--decrypt & check */
+    /* Generate the key, if we haven't done so already. */
     if (!decrypt_key) {
-           if (retval = (*key_proc)(context, keytype, &decrypt_key, keyseed,
-                                    as_reply->padata))
+           if (retval = (*key_proc)(context, keytype, & salt, keyseed,
+                                    &decrypt_key))
                goto cleanup;
     }
     
@@ -323,6 +351,8 @@ krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, keytype,
     retval = 0;
     
 cleanup:
+    if (f_salt)
+       krb5_xfree(salt.data);
     if (as_reply)
        krb5_free_kdc_rep(context, as_reply);
     if (reply.data)
diff --git a/src/lib/krb5/krb/in_tkt_ktb.c b/src/lib/krb5/krb/in_tkt_ktb.c
new file mode 100644 (file)
index 0000000..47fd8a9
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * lib/krb5/krb/in_tkt_ktb.c
+ *
+ * Copyright 1990,1991 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.
+ * 
+ *
+ * krb5_get_in_tkt_with_keytab()
+ *     
+ */
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+
+struct keytab_keyproc_arg {
+    krb5_keytab        keytab;
+    krb5_principal client;
+};
+
+/*
+ * Key-generator for in_tkt_keytab, below.
+ * "keyseed" is actually a krb5_keytab, or NULL if we should fetch
+ * from system area.
+ */
+static keytab_keyproc(context, type, salt, keyseed, key)
+    krb5_context context;
+    const krb5_keytype type;
+    krb5_data * salt;
+    krb5_const_pointer keyseed;
+    krb5_keyblock ** key;
+{
+    struct keytab_keyproc_arg * arg = (struct keytab_keyproc_arg *)keyseed;
+    krb5_keyblock *realkey;
+    krb5_error_code retval;
+    krb5_keytab kt_id;
+    krb5_keytab_entry kt_ent;
+
+    kt_id = arg->keytab;
+
+    if (!valid_keytype(type))
+       return KRB5_PROG_ETYPE_NOSUPP;
+
+    if (kt_id == NULL)
+       /* Fetch from default keytab location */
+       if (retval = krb5_kt_default(context, &kt_id))
+           return retval;
+
+
+    if (retval = krb5_kt_get_entry(context, kt_id, arg->client,
+                                  0, /* don't have vno available */
+                                  type, &kt_ent))
+           return retval;
+
+    if (retval = krb5_copy_keyblock(context, &kt_ent.key, &realkey)) {
+       (void) krb5_kt_free_entry(context, &kt_ent);
+       return retval;
+    }
+       
+    if (realkey->keytype != type) {
+       (void) krb5_kt_free_entry(context, &kt_ent);
+       krb5_free_keyblock(context, realkey);
+       return KRB5_PROG_ETYPE_NOSUPP;
+    }  
+
+    (void) krb5_kt_free_entry(context, &kt_ent);
+    *key = realkey;
+    return 0;
+}
+
+/*
+ Similar to krb5_get_in_tkt_with_skey.
+
+ Attempts to get an initial ticket for creds->client to use server
+ creds->server, (realm is taken from creds->client), with options
+ options, and using creds->times.starttime, creds->times.endtime, 
+ creds->times.renew_till as from, till, and rtime. 
+ creds->times.renew_till is ignored unless the RENEWABLE option is requested.
+
+ If addrs is non-NULL, it is used for the addresses requested.  If it is
+ null, the system standard addresses are used.
+
+ A succesful call will place the ticket in the credentials cache ccache.
+
+ returns system errors, encryption errors
+
+ */
+krb5_error_code
+krb5_get_in_tkt_with_keytab(context, options, addrs, etypes, pre_auth_types, 
+                           keytab, ccache, creds, ret_as_reply)
+    krb5_context context;
+    const krb5_flags options;
+    krb5_address * const * addrs;
+    krb5_enctype * etypes;
+    krb5_preauthtype * pre_auth_types;
+    const krb5_keytab keytab;
+    krb5_ccache ccache;
+    krb5_creds * creds;
+    krb5_kdc_rep ** ret_as_reply;
+{
+    struct keytab_keyproc_arg arg;
+
+    arg.keytab = keytab;
+    arg.client = creds->client;
+
+    return (krb5_get_in_tkt(context, options, addrs, etypes, pre_auth_types, 
+                           keytab_keyproc, (krb5_pointer)&arg,
+                           krb5_kdc_rep_decrypt_proc, 0, creds,
+                           ccache, ret_as_reply));
+}
index 9bbb033e7b1aeda443fee160fa30327a44b78fa0..1fb3b41ff6ac99882bfe40f2141bf2ab8bb0c7e3 100644 (file)
 #include <krb5/ext-proto.h>
 #include <krb5/los-proto.h>
 
-struct pwd_keyproc_arg {
-    krb5_principal who;
-    krb5_data password;
-};
-
 extern char *krb5_default_pwd_prompt1;
 
 /* 
@@ -41,84 +36,50 @@ extern char *krb5_default_pwd_prompt1;
  */
 
 static krb5_error_code
-pwd_keyproc(context, type, key, keyseed, padata)
+pwd_keyproc(context, type, salt, keyseed, key)
     krb5_context context;
     const krb5_keytype type;
-    krb5_keyblock ** key;
+    krb5_data * salt;
     krb5_const_pointer keyseed;
-    krb5_pa_data ** padata;
+    krb5_keyblock ** key;
 {
-    krb5_data salt;
     krb5_error_code retval;
     krb5_encrypt_block eblock;
     const struct pwd_keyproc_arg *arg;
-    struct pwd_keyproc_arg arg2;
     char pwdbuf[BUFSIZ];
+    krb5_data * password;
     int pwsize = sizeof(pwdbuf);
-    char f_salt = 0, use_salt = 0;
 
     if (!valid_keytype(type))
        return KRB5_PROG_KEYTYPE_NOSUPP;
 
     krb5_use_keytype(context, &eblock, type);
     
-    if (padata) {
-        krb5_pa_data **ptr;
-
-        for (ptr = padata; *ptr; ptr++)
-        {
-            if ((*ptr)->pa_type == KRB5_PADATA_PW_SALT)
-            {
-                /* use KDC-supplied salt, instead of default */
-                salt.length = (*ptr)->length;
-                salt.data = (char *)(*ptr)->contents;
-               use_salt = 1;
-                break;
-            }
-        }
-    }
-    arg = (const struct pwd_keyproc_arg *)keyseed;
-    if (!use_salt) {
-       /* need to use flattened principal */
-       if (retval = krb5_principal2salt(context, arg->who, &salt))
-           return(retval);
-       f_salt = 1;
-    }
+    password = (krb5_data *)keyseed;
 
-    if (!arg->password.length) {
-       if (retval = krb5_read_password(context, krb5_default_pwd_prompt1,
-                                       0,
+    if (!password->length) {
+       if (retval = krb5_read_password(context, krb5_default_pwd_prompt1, 0,
                                        pwdbuf, &pwsize)) {
-           if (f_salt) krb5_xfree(salt.data);
            return retval;
        }
-       arg2 = *arg;
-        arg2.password.length = pwsize;
-        arg2.password.data = pwdbuf;
-       arg = &arg2;
+        password->length = pwsize;
+        password->data = pwdbuf;
     }
-    *key = (krb5_keyblock *)malloc(sizeof(**key));
-    if (!*key) {
-       if (f_salt) krb5_xfree(salt.data);
+
+    if (!(*key = (krb5_keyblock *)malloc(sizeof(**key))))
        return ENOMEM;
-    }
-    retval = krb5_string_to_key(context, &eblock, type, *key, &arg->password, &salt);
-    if (retval) {
+
+    if (retval = krb5_string_to_key(context,&eblock,type,*key,password,salt))
        krb5_xfree(*key);
-       if (f_salt) krb5_xfree(salt.data);
-       return(retval);
-    }
-    if (f_salt) krb5_xfree(salt.data);
-    return 0;
+    return(retval);
 }
 
 /*
  Attempts to get an initial ticket for creds->client to use server
  creds->server, (realm is taken from creds->client), with options
- options, requesting encryption type etype, and using
- creds->times.starttime,  creds->times.endtime,  creds->times.renew_till
- as from, till, and rtime.  creds->times.renew_till is ignored unless
- the RENEWABLE option is requested.
+ options, and using creds->times.starttime, creds->times.endtime,
+ creds->times.renew_till as from, till, and rtime.  
+ creds->times.renew_till is ignored unless the RENEWABLE option is requested.
 
  If addrs is non-NULL, it is used for the addresses requested.  If it is
  null, the system standard addresses are used.
@@ -133,32 +94,30 @@ pwd_keyproc(context, type, key, keyseed, padata)
  returns system errors, encryption errors
  */
 krb5_error_code
-krb5_get_in_tkt_with_password(context, options, addrs, pre_auth_type, etype,
-                             keytype, password, ccache, creds, ret_as_reply)
+krb5_get_in_tkt_with_password(context, options, addrs, etypes, pre_auth_types, 
+                             password, ccache, creds, ret_as_reply)
     krb5_context context;
     const krb5_flags options;
     krb5_address * const * addrs;
-    const krb5_preauthtype pre_auth_type;
-    const krb5_enctype etype;
-    const krb5_keytype keytype;
+    krb5_enctype * etypes;
+    krb5_preauthtype * pre_auth_types;
     const char * password;
     krb5_ccache ccache;
     krb5_creds * creds;
     krb5_kdc_rep ** ret_as_reply;
 {
     krb5_error_code retval;
-    struct pwd_keyproc_arg keyseed;
+    krb5_data data;
 
 
-    keyseed.password.data = (char *)password;
-    if (password)
-       keyseed.password.length = strlen(password);
-    else
-       keyseed.password.length = 0;
-    keyseed.who = creds->client;
+    if (data.data = (char *)password) {
+       data.length = strlen(password);
+    } else {
+       data.length = 0;
+    }
 
-    retval = krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype,
-                            keytype, pwd_keyproc, (krb5_pointer) &keyseed,
+    retval = krb5_get_in_tkt(context, options, addrs, etypes, pre_auth_types, 
+                            pwd_keyproc, (krb5_pointer) &data,
                             krb5_kdc_rep_decrypt_proc, 0,
                             creds, ccache, ret_as_reply);
     return retval;
index f6184585774d980d83e5819567c52b0ff9ff174c..a0ccb151d0e055b2dc3bdb587f608812dea3e770 100644 (file)
@@ -40,54 +40,34 @@ struct skey_keyproc_arg {
  * "keyseed" is actually a krb5_keyblock *, or NULL if we should fetch
  * from system area.
  */
-skey_keyproc(context, type, key, keyseed, padata)
+skey_keyproc(context, type, salt, keyseed, key)
     krb5_context context;
     const krb5_keytype type;
-    krb5_keyblock ** key;
+    krb5_data * salt;
     krb5_const_pointer keyseed;
-    krb5_pa_data ** padata;
+    krb5_keyblock ** key;
 {
     krb5_keyblock *realkey;
     const struct skey_keyproc_arg *arg;
     krb5_error_code retval;
     krb5_keytab kt_id;
     krb5_keytab_entry kt_ent;
+    const krb5_keyblock * keyblock;
 
-    arg = (const struct skey_keyproc_arg *)keyseed;
+    keyblock = (const krb5_keyblock *)keyseed;
 
     if (!valid_keytype(type))
        return KRB5_PROG_ETYPE_NOSUPP;
 
-    if (arg->client) {
-       /* do keytab stuff */
-       /* else we need to fetch from system key place */
-       if (retval = krb5_kt_default(context, &kt_id))
-           return retval;
-       if (retval = krb5_kt_get_entry(context, kt_id, arg->client,
-                                      0, /* don't have vno available */
-                                      type,
-                                      &kt_ent))
-           return retval;
-    }
-#define cleanup() {if (arg->client) (void) krb5_kt_free_entry(context, &kt_ent);}
-
-    if (arg->key)
-       retval = krb5_copy_keyblock(context, arg->key, &realkey);
-    else
-       retval = krb5_copy_keyblock(context, &kt_ent.key, &realkey);
-    if (retval) {
-       cleanup();
+    if (retval = krb5_copy_keyblock(context, keyblock, &realkey))
        return retval;
-    }
        
     if (realkey->keytype != type) {
        krb5_free_keyblock(context, realkey);
-       cleanup();
        return KRB5_PROG_ETYPE_NOSUPP;
     }  
 
     *key = realkey;
-    cleanup();
     return 0;
 }
 
@@ -96,10 +76,9 @@ skey_keyproc(context, type, key, keyseed, padata)
 
  Attempts to get an initial ticket for creds->client to use server
  creds->server, (realm is taken from creds->client), with options
- options, requesting encryption type etype, and using
- creds->times.starttime,  creds->times.endtime,  creds->times.renew_till
- as from, till, and rtime.  creds->times.renew_till is ignored unless
- the RENEWABLE option is requested.
+ options, and using creds->times.starttime, creds->times.endtime,
+ creds->times.renew_till as from, till, and rtime.  
+ creds->times.renew_till is ignored unless the RENEWABLE option is requested.
 
  If addrs is non-NULL, it is used for the addresses requested.  If it is
  null, the system standard addresses are used.
@@ -114,36 +93,26 @@ skey_keyproc(context, type, key, keyseed, padata)
 
  */
 krb5_error_code
-krb5_get_in_tkt_with_skey(context, options, addrs, pre_auth_type, etype,
+krb5_get_in_tkt_with_skey(context, options, addrs, etypes, pre_auth_types, 
                          key, ccache, creds, ret_as_reply)
     krb5_context context;
     const krb5_flags options;
     krb5_address * const * addrs;
-    const krb5_preauthtype pre_auth_type;
-    const krb5_enctype  etype;
+    krb5_enctype * etypes;
+    krb5_preauthtype * pre_auth_types;
     const krb5_keyblock * key;
     krb5_ccache ccache;
     krb5_creds * creds;
     krb5_kdc_rep ** ret_as_reply;
 
 {
-    struct skey_keyproc_arg arg;
-    krb5_keytype keytype;
-
-    if (key) {
-       arg.key = key;
-       arg.client = 0;
-       keytype = key->keytype;
-    } else {
-       arg.key = 0;
-       arg.client = creds->client;
-       if (!valid_etype(etype))
-           return(KRB5_PROG_ETYPE_NOSUPP);
-
-       keytype = krb5_csarray[etype]->system->proto_keytype;
-    }
-    return (krb5_get_in_tkt(context, options, addrs, pre_auth_type, etype, 
-                           keytype, skey_keyproc, (krb5_pointer) &arg,
-                           krb5_kdc_rep_decrypt_proc, 0, creds,
-                           ccache, ret_as_reply));
+    if (key) 
+       return krb5_get_in_tkt(context, options, addrs, etypes, pre_auth_types, 
+                              skey_keyproc, (krb5_pointer)key,
+                              krb5_kdc_rep_decrypt_proc, 0, creds,
+                              ccache, ret_as_reply);
+    else 
+       return krb5_get_in_tkt_with_keytab(context, options, addrs, etypes,
+                                          pre_auth_types, NULL, ccache,
+                                          creds, ret_as_reply);
 }