rd_svc_key.c (krb54_get_service_keyblock): New function which searches
authorTheodore Tso <tytso@mit.edu>
Sat, 5 Dec 1998 05:38:29 +0000 (05:38 +0000)
committerTheodore Tso <tytso@mit.edu>
Sat, 5 Dec 1998 05:38:29 +0000 (05:38 +0000)
the appropaite krb5 keytab file for the key to be used by the krb4
library.

rd_req.c (krb_rd_req): If the appropriate key cannot be found in the
krb4 srvtab file, try calling krb54_get_service_keyblock.

decomp_tkt.c (dcmp_tkt_int):
g_in_tkt.c (krb_mk_in_tkt_preauth):
g_ad_tkt.c (get_ad_tkt):
pkt_clen.c (pkt_clen):
rd_err.c (krb_rd_err):
rd_priv.c (krb_rd_priv):
rd_req.c (krb_rd_req):

rd_safe.c (krb_rd_safe): Use krb4_swab32 and krb4_swab16 instead of
swap_u_long and swap_u_short.  The new byte swapping routines are
faster and cleaner.

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

src/lib/krb4/ChangeLog
src/lib/krb4/decomp_tkt.c
src/lib/krb4/g_ad_tkt.c
src/lib/krb4/g_in_tkt.c
src/lib/krb4/pkt_clen.c
src/lib/krb4/rd_err.c
src/lib/krb4/rd_priv.c
src/lib/krb4/rd_req.c
src/lib/krb4/rd_safe.c
src/lib/krb4/rd_svc_key.c

index 8f1b779528451bb6800f432668b11fb5272d3660..5b1554a2a28bafbcf83fee2992799a90750b2659 100644 (file)
@@ -1,3 +1,23 @@
+1998-12-05  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * rd_svc_key.c (krb54_get_service_keyblock): New function which
+               searches the appropaite krb5 keytab file for the key to be
+               used by the krb4 library.
+
+       * rd_req.c (krb_rd_req): If the appropriate key cannot be found in
+               the krb4 srvtab file, try calling krb54_get_service_keyblock.
+
+       * decomp_tkt.c (dcmp_tkt_int): 
+       * g_in_tkt.c (krb_mk_in_tkt_preauth): 
+       * g_ad_tkt.c (get_ad_tkt): 
+       * pkt_clen.c (pkt_clen): 
+       * rd_err.c (krb_rd_err): 
+       * rd_priv.c (krb_rd_priv): 
+       * rd_req.c (krb_rd_req): 
+       * rd_safe.c (krb_rd_safe): Use krb4_swab32 and krb4_swab16 instead
+               of swap_u_long and swap_u_short.  The new byte swapping
+               routines are faster and cleaner.
+
 1998-11-13  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * Makefile.in: Set the myfulldir and mydir variables (which are
index d4dfd4edcb5ae4cc21cb667ed596f7f3816cf683..03398acd587147404f8a91f1043220364e34fed7 100644 (file)
@@ -221,7 +221,7 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
     memcpy((char *) time_sec, ptr, 4); /* issue time */
     ptr += 4;
     if (tkt_swap_bytes)
-        swap_u_long(*time_sec);
+        *time_sec = krb4_swab32(*time_sec);
 
     (void) strcpy(sname,ptr);   /* service name */
     ptr += 1 + strlen(sname);
index 55a82bb71e712de14109f5c335914973f28b0923..b3abb2ddc6913c76ff79af284e67178d8f19056a 100644 (file)
@@ -170,7 +170,7 @@ get_ad_tkt(service,sinstance,realm,lifetime)
     case AUTH_MSG_ERR_REPLY:
        memcpy((char *) &rep_err_code, pkt_err_code(rpkt), 4);
        if (swap_bytes)
-           swap_u_long(rep_err_code);
+           rep_err_code = krb4_swab32(rep_err_code);
        return(rep_err_code);
 
     default:
@@ -221,7 +221,7 @@ get_ad_tkt(service,sinstance,realm,lifetime)
 
     /* check KDC time stamp */
     memcpy((char *)&kdc_time, ptr, 4); /* Time (coarse) */
-    if (swap_bytes) swap_u_long(kdc_time);
+    if (swap_bytes) kdc_time = krb4_swab32(kdc_time);
 
     ptr += 4;
 
index 3fc784e776d99eb1603473e49dcd2cd06188fed1..c9d6183820a92e0ac9fd8dde0a647af3288abde7 100644 (file)
@@ -204,7 +204,7 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
         break;
     case AUTH_MSG_ERR_REPLY:
         memcpy((char *) &rep_err_code, pkt_err_code(rpkt), 4);
-        if (swap_bytes) swap_u_long(rep_err_code);
+        if (swap_bytes) rep_err_code = krb4_swab32(rep_err_code);
         return((int)rep_err_code);
     default:
         return(INTK_PROT);
@@ -216,7 +216,7 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life,
     /* not used */
     /* get the principal's expiration date */
     memcpy((char *) &exp_date, pkt_x_date(rpkt), sizeof(exp_date));
-    if (swap_bytes) swap_u_long(exp_date);
+    if (swap_bytes) exp_data = krb4_swab32(exp_date);
 #endif
 
     /* Extract the ciphertext */
@@ -307,7 +307,7 @@ krb_parse_in_tkt(user, instance, realm, service, sinstance, life, cip)
 
     /* check KDC time stamp */
     memcpy((char *)&kdc_time, ptr, 4); /* Time (coarse) */
-    if (swap_bytes) swap_u_long(kdc_time);
+    if (swap_bytes) kdc_time = krb4_swab32(kdc_time);
 
     ptr += 4;
 
index 99a712b8d3e59ae15df459bab4c8f3055926f255..352c91d4ee8c0375d5f57887e78eb0538e965780 100644 (file)
@@ -27,7 +27,7 @@ int swap_bytes;
 pkt_clen(pkt)
     KTEXT pkt;
 {
-    static unsigned short temp,temp2;
+    static unsigned short temp;
     int clen = 0;
 
     /* Start of ticket list */
@@ -36,11 +36,8 @@ pkt_clen(pkt)
 
     /* Finally the length */
     memcpy((char *)&temp, (char *)(++ptr), 2); /* alignment */
-    if (swap_bytes) {
-        /* assume a short is 2 bytes?? */
-        swab((char *)&temp,(char *)&temp2,2);
-        temp = temp2;
-    }
+    if (swap_bytes)
+       temp = krb4_swab16(temp);    
 
     clen = (int) temp;
 
index b7f6a8cc9383f61840acf281b9ce8a1d8c843972..80f0d3abdbf6a28efc178eebd98c5bc9886cb538 100644 (file)
@@ -56,7 +56,7 @@ krb_rd_err(in,in_length,code,m_data)
       
       memcpy((char *)&raw_code, (char *)p, sizeof(raw_code));
       if (swap_bytes)
-        swap_u_long(raw_code);
+        raw_code = krb4_swab32(raw_code);
       p += sizeof(raw_code);         /* skip over */
       *code = raw_code;
     }
index 4a30886169688766b2ec9157e9ab731de9569d0c..44add9a76dc341b7cb06e8113af9b069481f1460 100644 (file)
@@ -96,7 +96,7 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
     /* get cipher length */
     memcpy((char *)&c_length, (char *)p, sizeof(c_length));
     if (swap_bytes)
-        swap_u_long(c_length);
+           c_length = krb4_swab32(c_length);
     p += sizeof(c_length);
     /* check for rational length so we don't go comatose */
     if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
@@ -121,7 +121,7 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
     memcpy((char *)&(m_data->app_length), (char *) p, 
           sizeof(m_data->app_length));
     if (swap_bytes)
-        swap_u_long(m_data->app_length);
+        m_data->app_length = krb4_swab32(m_data->app_length);
     p += sizeof(m_data->app_length);    /* skip over */
 
     if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
@@ -154,7 +154,7 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
     /* safely get time_sec */
     memcpy((char *)&(m_data->time_sec), (char *) p, 
          sizeof(m_data->time_sec));
-    if (swap_bytes) swap_u_long(m_data->time_sec);
+    if (swap_bytes) m_data->time_sec = krb4_swab32(m_data->time_sec);
 
     p += sizeof(m_data->time_sec);
 
@@ -201,7 +201,7 @@ krb_rd_priv(in,in_length,schedule,key,sender,receiver,m_data)
 
 #ifdef notdef
     memcpy((char *)&cksum, (char *) p, sizeof(cksum));
-    if (swap_bytes) swap_u_long(cksum)
+    if (swap_bytes) cksum = krb4_swab32(cksum)
     /*
      * calculate the checksum of the length, sequence,
      * and input data, on the sending byte order!!
index a78aadc881b71081ef1bcbb93725b5fe481a3a09..8da0b625b4f3f88c1354b3ea2651a8e9f2912ffa 100644 (file)
@@ -13,6 +13,8 @@
 #include "krb.h"
 #include "prot.h"
 #include <string.h>
+#include <krb5.h>
+#include <krb54proto.h>
 
 extern int krb_ap_req_debug;
 
@@ -63,7 +65,6 @@ static int krb5_key;          /* whether krb5 key is used for decrypt */
  * krb_rd_req().
  */
 
-#include <krb5.h>
 static krb5_keyblock srv_k5key;
 
 int
@@ -180,6 +181,7 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
     int mutual;                        /* Mutual authentication requested? */
     unsigned char s_kvno;      /* Version number of the server's key
                                   Kerberos used to encrypt ticket */
+    krb5_keyblock keyblock;
     int status;
 
     if (authent->length <= 0)
@@ -234,10 +236,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
         st_kvno = s_kvno;
 #ifndef NOENCRYPTION
         if (read_service_key(service,instance,realm,(int) s_kvno,
-                            fn,(char *)skey))
-            return(RD_AP_UNDEC);
-        if (status = krb_set_key((char *)skey,0))
-           return(status);
+                            fn,(char *)skey) == 0) {
+               if ((status = krb_set_key((char *)skey,0)))
+                       return(status);
+       } else if (krb54_get_service_keyblock(service,instance,
+                      realm, (int) s_kvno,fn, &keyblock) == 0) {
+               krb_set_key_krb5(krb5__krb4_context, &keyblock);
+               krb5_free_keyblock_contents(krb5__krb4_context, &keyblock);
+       } else
+               return(RD_AP_UNDEC);
+       
 #endif /* !NOENCRYPTION */
         (void) strcpy(st_rlm,realm);
         (void) strcpy(st_nam,service);
@@ -274,7 +282,7 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
        if (decomp_tkt_krb5(tkt, &ad->k_flags, ad->pname, ad->pinst,
                            ad->prealm, &ad->address, ad->session,
                            &ad->life, &ad->time_sec, sname, iname,
-                           srv_k5key)) {
+                           &srv_k5key)) {
            return RD_AP_UNDEC;
        }
     }
@@ -326,7 +334,7 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
     memcpy((char *)&ad->checksum, ptr, 4);     /* Checksum */
     ptr += 4;
     check_ptr();
-    if (swap_bytes) swap_u_long(ad->checksum);
+    if (swap_bytes) ad->checksum = krb4_swab32(ad->checksum);
     r_time_ms = *(ptr++);      /* Time (fine) */
 #ifdef lint
     /* XXX r_time_ms is set but not used.  why??? */
@@ -337,7 +345,7 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn)
     check_ptr();
     /* assume sizeof(r_time_sec) == 4 ?? */
     memcpy((char *)&r_time_sec, ptr, 4); /* Time (coarse) */
-    if (swap_bytes) swap_u_long(r_time_sec);
+    if (swap_bytes) r_time_sec = krb4_swab32(r_time_sec);
 
     /* Check for authenticity of the request */
 #ifdef KRB_CRYPT_DEBUG
index 52fdf3ab109d8d1f679c86f825022734083da931..f60e05922929a6cdaf93b2d57cdd45c92847e8b1 100644 (file)
@@ -88,7 +88,7 @@ krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
     /* safely get length */
     memcpy((char *)&(m_data->app_length), (char *)p, 
           sizeof(m_data->app_length));
-    if (swap_bytes) swap_u_long(m_data->app_length);
+    if (swap_bytes) m_data->app_length = krb4_swab32(m_data->app_length);
     p += sizeof(m_data->app_length); /* skip over */
 
     if (m_data->app_length + sizeof(in_length)
@@ -123,7 +123,7 @@ krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
     memcpy((char *)&(m_data->time_sec), (char *)p, 
           sizeof(m_data->time_sec));
     if (swap_bytes)
-        swap_u_long(m_data->time_sec);
+        m_data->time_sec = krb4_swab32(m_data->time_sec);
     p += sizeof(m_data->time_sec);
 
     /* check direction bit is the sign bit */
@@ -169,12 +169,10 @@ krb_rd_safe protocol err sizeof(u_long) != sizeof(struct in_addr)");
     memcpy((char *)big_cksum, (char *)p, sizeof(big_cksum));
     if (swap_bytes) {
       /* swap_u_16(big_cksum); */
-      unsigned KRB4_32 tt, *bb;
+      unsigned KRB4_32 *bb;
       bb = (unsigned KRB4_32*)big_cksum;
-      tt = bb[0]; swap_u_long(tt); bb[0] = tt;
-      tt = bb[1]; swap_u_long(tt); bb[1] = tt;
-      tt = bb[2]; swap_u_long(tt); bb[2] = tt;
-      tt = bb[3]; swap_u_long(tt); bb[3] = tt;
+      bb[0] = krb4_swab32(bb[0]);  bb[1] = krb4_swab32(bb[1]);
+      bb[2] = krb4_swab32(bb[2]);  bb[3] = krb4_swab32(bb[3]);
     }
 
 #ifdef NOENCRYPTION
index 34924baf505b209df6395cdf0bec4e696ff3c0f1..0ee9717a8c0437b785fdce2c94ebbfc516f323d1 100644 (file)
@@ -14,6 +14,7 @@
 #include <string.h>
 
 #include "k5-int.h"
+#include <krb54proto.h>
 
 extern char *krb__get_srvtabname();
 
@@ -113,78 +114,138 @@ int vxworks_srvtab_read(fd, s, n)
 }
 #endif
 
-KRB5_DLLIMP int KRB5_CALLCONV
-read_service_key(service,instance,realm,kvno,file,key)
+#ifdef KRB4_USE_KEYTAB
+/*
+ * This function looks up the requested Krb4 srvtab key using the krb5
+ * keytab format, if possible.
+ */
+extern krb5_error_code
+krb54_get_service_keyblock(service,instance,realm,kvno,file,keyblock)
     char FAR *service;         /* Service Name */
     char FAR *instance;                /* Instance name or "*" */
     char FAR *realm;           /* Realm */
     int kvno;                  /* Key version number */
     char FAR *file;            /* Filename */
-    char FAR *key;             /* Pointer to key to be filled in */
+    krb5_keyblock FAR * keyblock;
 {
-    int kret;
-    
-#ifdef KRB4_USE_KEYTAB
     krb5_error_code retval;
-    krb5_context context;
-    krb5_principal princ;
+    krb5_principal princ = NULL;
     krb5_keytab kt_id;
     krb5_keytab_entry kt_entry;
     char sname[ANAME_SZ+1];
     char sinst[INST_SZ+1];
     char srealm[REALM_SZ+1];
     char keytabname[MAX_KEYTAB_NAME_LEN + 1];  /* + 1 for NULL termination */
+
+    if (!krb5__krb4_context) {
+           retval = krb5_init_context(&krb5__krb4_context);
+           if (retval)
+                   return retval;
+    }
+
+    if (!strcmp(instance, "*")) {
+       if ((retval = krb5_sname_to_principal(krb5__krb4_context, NULL, NULL,
+                                             KRB5_NT_SRV_HST, &princ)))
+           goto errout;
+       
+       if ((retval = krb5_524_conv_principal(krb5__krb4_context, princ,
+                                             sname, sinst, srealm)))
+           goto errout;
+
+       instance = sinst;
+       krb5_free_principal(krb5__krb4_context, princ);
+       princ = 0;
+    }
+    
+    if ((retval = krb5_425_conv_principal(krb5__krb4_context, service,
+                                         instance, realm, &princ)))
+       goto errout;
+
+    /*
+     * Figure out what name to use; if the name is one of the standard
+     * /etc/srbtab, /etc/athena/srvtab, etc., use the default keytab
+     * name.  Otherwise, append .krb5 to the filename and try to use
+     * that.
+     */
+    if (file &&
+       strcmp(file, "/etc/srvtab") &&
+       strcmp(file, "/etc/athena/srvtab") &&
+       strcmp(file, KEYFILE)) {
+           strncpy(keytabname, file, sizeof(keytabname));
+           keytabname[sizeof(keytabname)-1] = 0;
+           if (strlen(keytabname)+6 < sizeof(keytabname))
+                   strcat(keytabname, ".krb5");
+    } else {
+           if ((retval = krb5_kt_default_name(krb5__krb4_context,
+                               (char *)keytabname, sizeof(keytabname)-1)))
+                   goto errout;
+    }
+    
+    if ((retval = krb5_kt_resolve(krb5__krb4_context, keytabname, &kt_id)))
+           goto errout;
+    
+    if ((retval = krb5_kt_get_entry(krb5__krb4_context, kt_id, princ, kvno,
+                                   0, &kt_entry))) {
+       krb5_kt_close(krb5__krb4_context, kt_id);
+       goto errout;
+    }
+
+    retval = krb5_copy_keyblock_contents(krb5__krb4_context,
+                                        &kt_entry.key, keyblock);
+    
+    krb5_kt_free_entry(krb5__krb4_context, &kt_entry);
+
+errout:
+    if (princ)
+       krb5_free_principal(krb5__krb4_context, princ);
+    return retval;
+}
 #endif
 
-    kret = get_service_key(service,instance,realm,&kvno,file,key);
 
+KRB5_DLLIMP int KRB5_CALLCONV
+read_service_key(service,instance,realm,kvno,file,key)
+    char FAR *service;         /* Service Name */
+    char FAR *instance;                /* Instance name or "*" */
+    char FAR *realm;           /* Realm */
+    int kvno;                  /* Key version number */
+    char FAR *file;            /* Filename */
+    char FAR *key;             /* Pointer to key to be filled in */
+{
+    int kret;
+    
 #ifdef KRB4_USE_KEYTAB
+    krb5_error_code    retval;
+    krb5_keyblock      keyblock;
+#endif
+
+    kret = get_service_key(service,instance,realm,&kvno,file,key);
+
     if (! kret)
        return KSUCCESS;
 
-    krb5_init_context(&context);
+#ifdef KRB4_USE_KEYTAB
+    kret = KFAILURE;
+    keyblock.magic = KV5M_KEYBLOCK;
+    keyblock.contents = 0;
+
+    retval = krb54_get_service_keyblock(service,instance,realm,kvno,file,
+                                       &keyblock);
+    if (retval)
+           goto errout;
 
-    if (!strcmp(instance, "*")) {
-       retval = krb5_sname_to_principal(context, NULL, NULL, KRB5_NT_SRV_HST,
-                                        &princ);
-       if (!retval) {
-           retval = krb5_524_conv_principal(context, princ,
-                                            sname, sinst, srealm);
-           krb5_free_principal(context, princ);
-       }
-       if (!retval)
-           instance = sinst;
+    if ((keyblock.length != sizeof(C_Block)) ||
+       ((keyblock.enctype != ENCTYPE_DES_CBC_CRC) &&
+        (keyblock.enctype != ENCTYPE_DES_CBC_MD4) &&
+        (keyblock.enctype != ENCTYPE_DES_CBC_MD5))) {
+           goto errout;
     }
+    (void) memcpy(key, keyblock.contents, sizeof(C_Block));
+    kret = KSUCCESS;
     
-    retval = krb5_425_conv_principal(context,
-                                    service,
-                                    instance,
-                                    realm,
-                                    &princ);
-    if (!retval)
-       retval = krb5_kt_default_name(context, (char *)keytabname,
-                                     sizeof(keytabname)-1);
-    if (!retval) {
-       retval = krb5_kt_resolve(context, (char *)keytabname, &kt_id);
-       if (!retval) {
-           retval = krb5_kt_get_entry(context, kt_id, princ, kvno,
-                                      ENCTYPE_DES_CBC_CRC, &kt_entry);
-           krb5_kt_close(context, kt_id);
-       }
-       krb5_free_principal(context, princ);
-    }
-    if (!retval) {
-       if (kt_entry.key.length == sizeof(C_Block)) {
-           (void) memcpy(key, kt_entry.key.contents, sizeof(C_Block));
-       } else {
-           retval = KRB5_BAD_KEYSIZE;
-       }
-       krb5_kt_free_entry(context, &kt_entry);
-    }
-    krb5_free_context(context);
-
-    if (! retval)
-       return KSUCCESS;
+errout:
+    if (keyblock.contents)
+           krb5_free_keyblock_contents(krb5__krb4_context, &keyblock);
 #endif
     
     return kret;