#include "krb.h"
#include "prot.h"
#include <string.h>
int KRB5_CALLCONV
krb4prot_encode_kdc_request(char *pname, char *pinst, char *prealm,
KRB4_32 tlocal, int life,
char *sname, char *sinst,
char *preauth, int preauthlen,
int chklen,
int le,
KTEXT pkt)
{
unsigned char *p;
int ret;
size_t snamelen, sinstlen;
p = pkt->dat;
*p++ = KRB_PROT_VERSION;
*p++ = AUTH_MSG_KDC_REQUEST | !!le;
ret = krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen,
pkt, &p);
if (ret)
return ret;
snamelen = strlen(sname) + 1;
sinstlen = strlen(sinst) + 1;
if (chklen && (snamelen > ANAME_SZ || sinstlen > INST_SZ))
return KRB4PROT_ERR_OVERRUN;
if ((sizeof(pkt->dat) - (p - pkt->dat))
< (4 + 1 + snamelen + sinstlen + preauthlen))
return KRB4PROT_ERR_OVERRUN;
KRB4_PUT32(p, tlocal, le);
*p++ = life;
memcpy(p, sname, snamelen);
p += snamelen;
memcpy(p, sinst, sinstlen);
p += sinstlen;
if (preauthlen)
memcpy(p, preauth, (size_t)preauthlen);
p += preauthlen;
pkt->length = p - pkt->dat;
return KRB4PROT_OK;
}
int KRB5_CALLCONV
krb4prot_decode_kdc_reply(KTEXT pkt,
int *le,
char *pname, char *pinst, char *prealm,
long *time_ws, int *n,
unsigned long *x_date, int *kvno,
KTEXT ciph)
{
unsigned char *p;
int msg_type;
int ret;
unsigned int ciph_len;
p = pkt->dat;
if (pkt->length < 2)
return KRB4PROT_ERR_UNDERRUN;
if (*p++ != KRB_PROT_VERSION)
return KRB4PROT_ERR_PROT_VERS;
msg_type = *p++;
*le = msg_type & 1;
msg_type &= ~1;
if (msg_type != AUTH_MSG_KDC_REPLY)
return KRB4PROT_ERR_MSG_TYPE;
ret = krb4prot_decode_naminstrlm(ciph, &p, pname, pinst, prealm);
if (ret)
return ret;
#define PKT_REMAIN (pkt->length - (p - pkt->dat))
if (PKT_REMAIN < (4
+ 1
+ 4
+ 1
+ 2))
return KRB4PROT_ERR_UNDERRUN;
if (time_ws != NULL)
KRB4_GET32(*time_ws, p, *le);
else
p += 4;
if (n != NULL)
*n = *p++;
else
p++;
if (x_date != NULL)
KRB4_GET32(*x_date, p, *le);
else
p += 4;
if (kvno != NULL)
*kvno = *p++;
else
p++;
KRB4_GET16(ciph_len, p, *le);
if (PKT_REMAIN < ciph_len)
return KRB4PROT_ERR_UNDERRUN;
ciph->length = ciph_len;
memcpy(ciph->dat, p, (size_t)ciph->length);
return KRB4PROT_OK;
#undef PKT_REMAIN
}
int KRB5_CALLCONV
krb4prot_decode_ciph(KTEXT ciph, int le,
C_Block session,
char *name, char *inst, char *realm,
int *life, int *kvno,
KTEXT tkt, unsigned long *kdc_time)
{
unsigned char *p;
int ret;
p = ciph->dat;
if (ciph->length < 8)
return KRB4PROT_ERR_UNDERRUN;
memcpy(session, p, 8);
p += 8;
ret = krb4prot_decode_naminstrlm(ciph, &p, name, inst, realm);
if (ret)
return ret;
#define CIPH_REMAIN (ciph->length - (p - ciph->dat))
if (CIPH_REMAIN < (1
+ 1
+ 1))
return KRB4PROT_ERR_UNDERRUN;
if (life != NULL)
*life = *p++;
else
p++;
if (kvno != NULL)
*kvno = *p++;
else
p++;
tkt->length = *p++;
if (CIPH_REMAIN < (tkt->length
+ 4))
return KRB4PROT_ERR_UNDERRUN;
memcpy(tkt->dat, p, (size_t)tkt->length);
p += tkt->length;
if (kdc_time != NULL)
KRB4_GET32(*kdc_time, p, le);
return KRB4PROT_OK;
#undef CIPH_REMAIN
}
int KRB5_CALLCONV
krb4prot_encode_apreq(int kvno, char *realm,
KTEXT tkt, KTEXT req_id,
int chklen,
int le,
KTEXT pkt)
{
unsigned char *p;
size_t realmlen;
p = pkt->dat;
*p++ = KRB_PROT_VERSION;
*p++ = AUTH_MSG_APPL_REQUEST | !!le;
*p++ = kvno;
realmlen = strlen(realm) + 1;
if (chklen && realmlen > REALM_SZ)
return KRB4PROT_ERR_OVERRUN;
if (tkt->length > 255 || req_id->length > 255)
return KRB4PROT_ERR_OVERRUN;
if ((sizeof(pkt->dat) - (p - pkt->dat))
< (realmlen
+ 1
+ 1
+ tkt->length + req_id->length))
return KRB4PROT_ERR_OVERRUN;
memcpy(p, realm, realmlen);
p += realmlen;
*p++ = tkt->length;
*p++ = req_id->length;
memcpy(p, tkt->dat, (size_t)tkt->length);
p += tkt->length;
memcpy(p, req_id->dat, (size_t)req_id->length);
p += req_id->length;
pkt->length = p - pkt->dat;
return KRB4PROT_OK;
}
int KRB5_CALLCONV
krb4prot_encode_authent(char *pname, char *pinst, char *prealm,
KRB4_32 checksum,
int time_usec, long time_sec,
int chklen,
int le,
KTEXT pkt)
{
unsigned char *p;
int ret;
p = pkt->dat;
ret = krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen,
pkt, &p);
if (ret)
return ret;
if ((sizeof(pkt->dat) - (p - pkt->dat)) / 8
< (4
+ 1
+ 4
+ 7) / 8)
return KRB4PROT_ERR_OVERRUN;
KRB4_PUT32(p, checksum, le);
*p++ = time_usec;
KRB4_PUT32(p, time_sec, le);
memset(p, 0, 7);
pkt->length = (((p - pkt->dat) + 7) / 8) * 8;
return KRB4PROT_OK;
}
int KRB5_CALLCONV
krb4prot_decode_error(KTEXT pkt, int *le,
char *pname, char *pinst, char *prealm,
unsigned long *time_ws,
unsigned long *err, char *err_string)
{
unsigned char *p;
int msg_type, ret, errstrlen;
p = pkt->dat;
if (pkt->length < 2)
return KRB4PROT_ERR_UNDERRUN;
if (*p++ != KRB_PROT_VERSION)
return KRB4PROT_ERR_PROT_VERS;
msg_type = *p++;
*le = msg_type & 1;
msg_type &= ~1;
if (msg_type != AUTH_MSG_ERR_REPLY)
return KRB4PROT_ERR_MSG_TYPE;
ret = krb4prot_decode_naminstrlm(pkt, &p, pname, pinst, prealm);
if (ret)
return ret;
#define PKT_REMAIN (pkt->length - (p - pkt->dat))
if (PKT_REMAIN < (4
+ 4))
return KRB4PROT_ERR_UNDERRUN;
if (time_ws != NULL)
KRB4_GET32(*time_ws, p, le);
else
p += 4;
if (err != NULL)
KRB4_GET32(*err, p, le);
else
p += 4;
if (PKT_REMAIN <= 0)
return KRB4PROT_OK;
errstrlen = krb4int_strnlen((char *)p, PKT_REMAIN) + 1;
if (errstrlen <= 0)
return KRB4PROT_ERR_OVERRUN;
if (err_string != NULL)
memcpy(err_string, p, (size_t)errstrlen);
return KRB4PROT_OK;
#undef PKT_REMAIN
}