+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
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);
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:
/* 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;
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);
/* 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 */
/* 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;
pkt_clen(pkt)
KTEXT pkt;
{
- static unsigned short temp,temp2;
+ static unsigned short temp;
int clen = 0;
/* Start of ticket list */
/* 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;
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;
}
/* 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)
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) +
/* 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);
#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!!
#include "krb.h"
#include "prot.h"
#include <string.h>
+#include <krb5.h>
+#include <krb54proto.h>
extern int krb_ap_req_debug;
* krb_rd_req().
*/
-#include <krb5.h>
static krb5_keyblock srv_k5key;
int
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)
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);
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;
}
}
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??? */
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
/* 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)
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 */
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
#include <string.h>
#include "k5-int.h"
+#include <krb54proto.h>
extern char *krb__get_srvtabname();
}
#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;