#include "des.h"
#include "krb.h"
#include "prot.h"
#include <string.h>
#include <krb5.h>
#include "krb54proto.h"
#include "port-sockets.h"
#ifdef KRB_CRYPT_DEBUG
extern int krb_debug;
#endif
static int dcmp_tkt_int (KTEXT tkt, unsigned char *flags,
char *pname, char *pinstance, char *prealm,
unsigned KRB4_32 *paddress, C_Block session,
int *life, unsigned KRB4_32 *time_sec,
char *sname, char *sinstance, C_Block key,
Key_schedule key_s, krb5_keyblock *k5key);
int KRB5_CALLCONV
decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session,
life, time_sec, sname, sinstance, key, key_s)
KTEXT tkt;
unsigned char *flags;
char *pname;
char *pinstance;
char *prealm;
unsigned KRB4_32 *paddress;
C_Block session;
int *life;
unsigned KRB4_32 *time_sec;
char *sname;
char *sinstance;
C_Block key;
Key_schedule key_s;
{
return
dcmp_tkt_int(tkt, flags, pname, pinstance, prealm,
paddress, session, life, time_sec, sname, sinstance,
key, key_s, NULL);
}
int
decomp_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress, session,
life, time_sec, sname, sinstance, k5key)
KTEXT tkt;
unsigned char *flags;
char *pname;
char *pinstance;
char *prealm;
unsigned KRB4_32 *paddress;
C_Block session;
int *life;
unsigned KRB4_32 *time_sec;
char *sname;
char *sinstance;
krb5_keyblock *k5key;
{
C_Block key;
Key_schedule key_s;
return
dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
life, time_sec, sname, sinstance, key, key_s, k5key);
}
static int
dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
life, time_sec, sname, sinstance, key, key_s, k5key)
KTEXT tkt;
unsigned char *flags;
char *pname;
char *pinstance;
char *prealm;
unsigned KRB4_32 *paddress;
C_Block session;
int *life;
unsigned KRB4_32 *time_sec;
char *sname;
char *sinstance;
C_Block key;
Key_schedule key_s;
krb5_keyblock *k5key;
{
int tkt_le;
unsigned char *ptr = tkt->dat;
int kret, len;
struct in_addr paddr;
if (sizeof(paddr.s_addr) != 4)
return KFAILURE;
#ifndef NOENCRYPTION
#ifdef KRB_CRYPT_DEBUG
if (krb_debug) {
FILE *fp;
char *keybuf[BUFSIZ];
fp = fopen("/kerberos/tkt.des", "wb");
setbuf(fp, keybuf);
fwrite(tkt->dat, 1, tkt->length, fp);
fclose(fp);
memset(keybuf, 0, sizeof(keybuf));
}
#endif
if (k5key != NULL) {
krb5_enc_data in;
krb5_data out;
krb5_error_code ret;
in.enctype = k5key->enctype;
in.kvno = 0;
in.ciphertext.length = tkt->length;
in.ciphertext.data = (char *)tkt->dat;
out.length = tkt->length;
out.data = malloc((size_t)tkt->length);
if (out.data == NULL)
return KFAILURE;
ret =
krb5_c_decrypt(NULL, k5key,
KRB5_KEYUSAGE_KDC_REP_TICKET, NULL, &in, &out);
if (ret) {
free(out.data);
return KFAILURE;
} else {
memcpy(tkt->dat, out.data, out.length);
memset(out.data, 0, out.length);
free(out.data);
}
} else {
pcbc_encrypt((C_Block *)tkt->dat, (C_Block *)tkt->dat,
(long)tkt->length, key_s, (C_Block *)key, 0);
}
#endif
#ifdef KRB_CRYPT_DEBUG
if (krb_debug) {
FILE *fp;
char *keybuf[BUFSIZ];
fp = fopen("/kerberos/tkt.clear", "wb");
setbuf(fp, keybuf);
fwrite(tkt->dat, 1, tkt->length, fp);
fclose(fp);
memset(keybuf, 0, sizeof(keybuf));
}
#endif
#define TKT_REMAIN (tkt->length - (ptr - tkt->dat))
kret = KFAILURE;
if (TKT_REMAIN < 1)
goto cleanup;
*flags = *ptr++;
tkt_le = (*flags >> K_FLAG_ORDER) & 1;
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
if (len <= 0 || len > ANAME_SZ)
goto cleanup;
memcpy(pname, ptr, (size_t)len);
ptr += len;
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
if (len <= 0 || len > INST_SZ)
goto cleanup;
memcpy(pinstance, ptr, (size_t)len);
ptr += len;
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
if (len <= 0 || len > REALM_SZ)
goto cleanup;
memcpy(prealm, ptr, (size_t)len);
ptr += len;
if (*prealm == '\0')
krb_get_lrealm(prealm, 1);
if (TKT_REMAIN < 4 + 8 + 1 + 4)
goto cleanup;
memcpy(&paddr.s_addr, ptr, sizeof(paddr.s_addr));
ptr += sizeof(paddr.s_addr);
*paddress = paddr.s_addr;
memcpy(session, ptr, 8);
memset(ptr, 0, 8);
ptr += 8;
#ifdef notdef
if (tkt_swap_bytes)
swap_C_Block(session);
#endif
*life = *ptr++;
KRB4_GET32(*time_sec, ptr, tkt_le);
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
if (len <= 0 || len > SNAME_SZ)
goto cleanup;
memcpy(sname, ptr, (size_t)len);
ptr += len;
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
if (len <= 0 || len > INST_SZ)
goto cleanup;
memcpy(sinstance, ptr, (size_t)len);
ptr += len;
kret = KSUCCESS;
#ifdef KRB_CRYPT_DEBUG
if (krb_debug) {
krb_log("service=%s.%s len(sname)=%d, len(sinstance)=%d",
sname, sinstance, strlen(sname), strlen(sinstance));
krb_log("ptr - tkt->dat=%d",(char *)ptr - (char *)tkt->dat);
}
#endif
cleanup:
if (kret != KSUCCESS) {
memset(session, 0, sizeof(session));
memset(tkt->dat, 0, (size_t)tkt->length);
return kret;
}
return KSUCCESS;
}