Some kind of non-working TGS support.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1350 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1997-03-11 19:22:07 +00:00
parent 12a93922af
commit 3ee2980a80
2 changed files with 562 additions and 74 deletions

318
kdc/kdc.c
View File

@@ -2,6 +2,9 @@
RCSID("$Id$");
struct timeval now;
#define kdc_time now.tv_sec
struct db_entry*
db_fetch(krb5_context context, krb5_principal princ)
{
@@ -50,9 +53,175 @@ krb5_encrypt (krb5_context context,
krb5_keyblock *keyblock,
krb5_data *result);
krb5_mk_error(krb5_principal princ,
krb5_error_code error_code,
krb5_data *err)
{
KRB_ERROR msg;
unsigned char buf[1024];
memset(&msg, 0, sizeof(msg));
msg.pvno = 5;
msg.msg_type = krb_error;
msg.stime = time(0);
msg.error_code = error_code;
msg.realm = princ->realm.data;
krb5_principal2principalname(&msg.sname, princ);
err->length = encode_KRB_ERROR(buf + sizeof(buf) - 1, sizeof(buf), &msg);
err->data = malloc(err->length);
memcpy(err->data, buf + sizeof(buf) - err->length, err->length);
return 0;
}
krb5_error_code
foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
mk_des_keyblock(EncryptionKey *kb)
{
kb->keytype = KEYTYPE_DES;
kb->keyvalue.data = malloc(sizeof(des_cblock));
kb->keyvalue.length = sizeof(des_cblock);
des_rand_data_key(kb->keyvalue.data);
return 0;
}
krb5_error_code
as_rep(krb5_context context, KDC_REQ *req, EncTicketPart *et)
{
KDCOptions f = req->req_body.kdc_options;
if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey)
return KRB5KDC_ERR_BADOPTION;
et->flags.initial = 1;
et->flags.forwardable = f.forwardable;
et->flags.proxiable = f.proxiable;
et->flags.may_postdate = f.allow_postdate;
if(f.postdated && req->req_body.from){
et->starttime = malloc(sizeof(*et->starttime));
*et->starttime = *req->req_body.from;
et->flags.invalid = 1;
et->flags.postdated = 1;
}
return 0;
}
krb5_error_code
tgs_rep(krb5_context context, KDC_REQ *req, EncTicketPart *et)
{
KDCOptions f = req->req_body.kdc_options;
if(req->padata == NULL || req->padata->len < 1)
return KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
if(req->padata->val->padata_type != pa_tgs_req)
return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
{
krb5_auth_context ac = NULL;
krb5_principal princ;
krb5_flags ap_req_options;
krb5_ticket *ticket;
krb5_error_code err;
struct db_entry *ent;
err = krb5_build_principal(context,
&princ,
strlen(req->req_body.realm),
req->req_body.realm,
"krbtgt",
req->req_body.realm,
NULL);
if(err) return err;
ent = db_fetch(context, princ);
if(ent == NULL) return 17;
err = krb5_rd_req_with_keyblock(context, &ac,
&req->padata->val->padata_value,
princ,
&ent->keyblock,
&ap_req_options,
&ticket);
if(err) return err;
if(f.forwardable){
if(!ticket->tkt.flags.forwardable)
return KRB5KDC_ERR_BADOPTION;
et->flags.forwardable = 1;
}
if(f.forwarded){
if(!ticket->tkt.flags.forwardable)
return KRB5KDC_ERR_BADOPTION;
et->flags.forwarded = 1;
et->caddr = req->req_body.addresses;
}
if(ticket->tkt.flags.forwarded)
et->flags.forwarded = 1;
if(f.proxiable){
if(!ticket->tkt.flags.proxiable)
return KRB5KDC_ERR_BADOPTION;
et->flags.proxiable = 1;
}
if(f.proxy){
if(!ticket->tkt.flags.proxiable)
return KRB5KDC_ERR_BADOPTION;
et->flags.proxy = 1;
et->caddr = req->req_body.addresses;
}
if(f.allow_postdate){
if(!ticket->tkt.flags.may_postdate)
return KRB5KDC_ERR_BADOPTION;
et->flags.may_postdate = 1;
}
if(f.postdated){
if(!ticket->tkt.flags.may_postdate)
return KRB5KDC_ERR_BADOPTION;
et->flags.postdated = 1;
et->flags.invalid = 1;
et->starttime = malloc(sizeof(*et->starttime));
*et->starttime = *req->req_body.from;
}
if(f.validate){
if(!ticket->tkt.flags.invalid)
return KRB5KDC_ERR_BADOPTION;
if(*ticket->tkt.starttime > kdc_time)
return KRB5KRB_AP_ERR_TKT_NYV;
/* XXX tkt = tgt */
et->flags.invalid = 0;
}
/* check for excess flags */
if(f.renew){
time_t old_life;
if(!ticket->tkt.flags.renewable)
return KRB5KDC_ERR_BADOPTION;
if(*ticket->tkt.renew_till >= kdc_time)
return KRB5KRB_AP_ERR_TKT_EXPIRED;
/* XXX tkt = tgt */
et->starttime = malloc(sizeof(*et->starttime));
*et->starttime = kdc_time;
old_life = ticket->tkt.endtime - *ticket->tkt.starttime;
et->endtime = MIN(*ticket->tkt.renew_till,
*et->starttime + old_life);
}else{
time_t till;
et->starttime = malloc(sizeof(*et->starttime));
*et->starttime = kdc_time;
}
req->req_body.cname = malloc(sizeof(*req->req_body.cname));
krb5_principal2principalname(req->req_body.cname,
ticket->enc_part2.client);
}
}
krb5_error_code
process_request(krb5_context context,
KDC_REQ *req,
krb5_data *reply)
{
krb5_error_code err;
krb5_principal princ;
@@ -61,7 +230,6 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
DB *db;
DBT key, value;
struct timeval now;
KDC_REP rep;
EncTicketPart et;
@@ -69,57 +237,103 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
struct db_entry *cname, *sname;
gettimeofday(&now, NULL);
memset(&rep, 0, sizeof(rep));
rep.pvno = 5;
if(req->msg_type == krb_as_req)
rep.msg_type = krb_as_rep;
else if(req->msg_type == krb_tgs_req){
rep.msg_type = krb_tgs_rep;
}else{
/* XXX */
return KRB5KRB_AP_ERR_MSG_TYPE;
}
err = principalname2krb5_principal (&princ,
*req->req_body.sname,
req->req_body.realm);
if(err) return err;
sname = db_fetch(context, princ);
if(sname == NULL){
krb5_mk_error(princ,
KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN,
reply);
return 0;
}
krb5_free_principal(princ);
memset(&et, 0, sizeof(et));
if(req->msg_type == krb_as_req)
as_rep(context, req, &et);
else
tgs_rep(context, req, &et);
err = principalname2krb5_principal (&princ,
*req->req_body.cname,
req->req_body.realm);
if(err) return err;
cname = db_fetch(context, princ);
if(cname == NULL){
krb5_mk_error(sname->principal,
KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN,
reply);
return 0;
}
krb5_free_principal(princ);
err = principalname2krb5_principal (&princ,
*req->req_body.sname,
req->req_body.realm);
if(err) return err;
sname = db_fetch(context, princ);
krb5_free_principal(princ);
memset(&rep, 0, sizeof(rep));
rep.pvno = 5;
rep.msg_type = krb_as_rep;
rep.crealm = req->req_body.realm;
krb5_principal2principalname(&rep.cname, cname->principal);
memset(&rep.ticket, 0, sizeof(rep.ticket));
rep.ticket.tkt_vno = 5;
rep.ticket.realm = req->req_body.realm;
krb5_principal2principalname(&rep.ticket.sname, sname->principal);
memset(&et, 0, sizeof(et));
et.flags.initial = 1;
et.key.keytype = sname->keyblock.keytype;
et.key.keyvalue.data = sname->keyblock.contents.data;
et.key.keyvalue.length = sname->keyblock.contents.length;
mk_des_keyblock(&et.key);
et.crealm = req->req_body.realm;
krb5_principal2principalname(&et.cname, cname->principal);
gettimeofday(&now, NULL);
et.authtime = now.tv_sec;
et.cname = *req->req_body.cname;
et.authtime = kdc_time;
{
time_t till;
time_t start = et.authtime;
if(et.starttime)
start = *et.starttime;
till = req->req_body.till;
till = MIN(till, now.tv_sec + sname->max_life);
till = MIN(till, now.tv_sec + cname->max_life);
if(till == 0)
till = start + cname->max_life;
till = MIN(till, start + sname->max_life);
till = MIN(till, start + cname->max_life);
et.endtime = till;
}
if(req->req_body.kdc_options.renewable && req->req_body.rtime){
time_t rtime;
time_t start = et.authtime;
if(et.starttime)
start = *et.starttime;
rtime = *req->req_body.rtime;
if(rtime == 0)
rtime = start + cname->max_renew;
rtime = MIN(rtime, start + sname->max_renew);
rtime = MIN(rtime, start + cname->max_renew);
if(rtime > et.endtime){
et.renew_till = malloc(sizeof(*et.renew_till));
*et.renew_till = rtime;
et.flags.renewable = 1;
}
}
memset(&ek, 0, sizeof(ek));
ek.key = et.key;
/* MIT must have at least one last_req */
ek.last_req.len = 1;
ek.last_req.val = malloc(sizeof(*ek.last_req.val));
ek.last_req.val->lr_type = 1;
ek.last_req.val->lr_type = 0;
ek.last_req.val->lr_value = 0;
ek.nonce = req->req_body.nonce;
ek.flags = et.flags;
@@ -127,8 +341,9 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
ek.starttime = et.starttime;
ek.endtime = et.endtime;
ek.renew_till = et.renew_till;
ek.srealm = et.crealm;
krb5_principal2principalname(&ek.sname, sname->principal);
ek.srealm = req->req_body.realm;
ek.sname = *req->req_body.sname;
ek.caddr = req->req_body.addresses;
{
unsigned char buf[1024];
@@ -140,7 +355,18 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
&sname->keyblock,
&rep.ticket.enc_part.cipher);
err = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf), &ek);
switch(rep.msg_type){
case krb_as_rep:
err = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf), &ek);
break;
case krb_tgs_rep:
err = encode_EncTGSRepPart(buf + sizeof(buf) - 1, sizeof(buf),
&ek);
break;
default:
abort();
break;
}
rep.enc_part.etype = ETYPE_DES_CBC_CRC;
rep.enc_part.kvno = NULL;
@@ -148,26 +374,37 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
&cname->keyblock,
&rep.enc_part.cipher);
*len = encode_AS_REP(reply + 1023, 1024, &rep);
memmove(reply, reply + 1024 - *len, *len);
switch(rep.msg_type){
case krb_as_rep:
reply->length = encode_AS_REP(buf + sizeof(buf) - 1,
sizeof(buf), &rep);
break;
case krb_tgs_rep:
reply->length = encode_TGS_REP(buf + sizeof(buf) - 1,
sizeof(buf), &rep);
break;
}
reply->data = malloc(reply->length);
memcpy(reply->data, buf + sizeof(buf) - reply->length, reply->length);
}
return 0;
}
int
kerberos(krb5_context context, unsigned char *buf, size_t len)
kerberos(krb5_context context,
unsigned char *buf,
size_t len,
krb5_data *reply)
{
KDC_REQ req;
int i;
i = decode_AS_REQ(buf, len, &req);
if(i >= 0){
foo(context, &req, buf, &len);
return len;
return process_request(context, &req, reply);
}
i = decode_TGS_REQ(buf, len, &req);
if(i >= 0){
foo(context, &req, buf, &len);
return len;
return process_request(context, &req, reply);
}
return -1;
}
@@ -204,11 +441,18 @@ main(int argc, char **argv)
if(FD_ISSET(s, &fds)){
struct sockaddr_in from;
int from_len = sizeof(from);
krb5_error_code err;
krb5_data reply;
len = recvfrom(s, buf, sizeof(buf), 0,
(struct sockaddr*)&from, &from_len);
len = kerberos(context, buf, len);
sendto(s, buf, len, 0,
(struct sockaddr*)&from, from_len);
err = kerberos(context, buf, len, &reply);
if(err){
fprintf(stderr, "%s\n", krb5_get_err_text(context, err));
}else{
sendto(s, reply.data, reply.length, 0,
(struct sockaddr*)&from, from_len);
krb5_data_free(&reply);
}
}
}
}

View File

@@ -2,6 +2,9 @@
RCSID("$Id$");
struct timeval now;
#define kdc_time now.tv_sec
struct db_entry*
db_fetch(krb5_context context, krb5_principal princ)
{
@@ -50,9 +53,175 @@ krb5_encrypt (krb5_context context,
krb5_keyblock *keyblock,
krb5_data *result);
krb5_mk_error(krb5_principal princ,
krb5_error_code error_code,
krb5_data *err)
{
KRB_ERROR msg;
unsigned char buf[1024];
memset(&msg, 0, sizeof(msg));
msg.pvno = 5;
msg.msg_type = krb_error;
msg.stime = time(0);
msg.error_code = error_code;
msg.realm = princ->realm.data;
krb5_principal2principalname(&msg.sname, princ);
err->length = encode_KRB_ERROR(buf + sizeof(buf) - 1, sizeof(buf), &msg);
err->data = malloc(err->length);
memcpy(err->data, buf + sizeof(buf) - err->length, err->length);
return 0;
}
krb5_error_code
foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
mk_des_keyblock(EncryptionKey *kb)
{
kb->keytype = KEYTYPE_DES;
kb->keyvalue.data = malloc(sizeof(des_cblock));
kb->keyvalue.length = sizeof(des_cblock);
des_rand_data_key(kb->keyvalue.data);
return 0;
}
krb5_error_code
as_rep(krb5_context context, KDC_REQ *req, EncTicketPart *et)
{
KDCOptions f = req->req_body.kdc_options;
if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey)
return KRB5KDC_ERR_BADOPTION;
et->flags.initial = 1;
et->flags.forwardable = f.forwardable;
et->flags.proxiable = f.proxiable;
et->flags.may_postdate = f.allow_postdate;
if(f.postdated && req->req_body.from){
et->starttime = malloc(sizeof(*et->starttime));
*et->starttime = *req->req_body.from;
et->flags.invalid = 1;
et->flags.postdated = 1;
}
return 0;
}
krb5_error_code
tgs_rep(krb5_context context, KDC_REQ *req, EncTicketPart *et)
{
KDCOptions f = req->req_body.kdc_options;
if(req->padata == NULL || req->padata->len < 1)
return KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
if(req->padata->val->padata_type != pa_tgs_req)
return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
{
krb5_auth_context ac = NULL;
krb5_principal princ;
krb5_flags ap_req_options;
krb5_ticket *ticket;
krb5_error_code err;
struct db_entry *ent;
err = krb5_build_principal(context,
&princ,
strlen(req->req_body.realm),
req->req_body.realm,
"krbtgt",
req->req_body.realm,
NULL);
if(err) return err;
ent = db_fetch(context, princ);
if(ent == NULL) return 17;
err = krb5_rd_req_with_keyblock(context, &ac,
&req->padata->val->padata_value,
princ,
&ent->keyblock,
&ap_req_options,
&ticket);
if(err) return err;
if(f.forwardable){
if(!ticket->tkt.flags.forwardable)
return KRB5KDC_ERR_BADOPTION;
et->flags.forwardable = 1;
}
if(f.forwarded){
if(!ticket->tkt.flags.forwardable)
return KRB5KDC_ERR_BADOPTION;
et->flags.forwarded = 1;
et->caddr = req->req_body.addresses;
}
if(ticket->tkt.flags.forwarded)
et->flags.forwarded = 1;
if(f.proxiable){
if(!ticket->tkt.flags.proxiable)
return KRB5KDC_ERR_BADOPTION;
et->flags.proxiable = 1;
}
if(f.proxy){
if(!ticket->tkt.flags.proxiable)
return KRB5KDC_ERR_BADOPTION;
et->flags.proxy = 1;
et->caddr = req->req_body.addresses;
}
if(f.allow_postdate){
if(!ticket->tkt.flags.may_postdate)
return KRB5KDC_ERR_BADOPTION;
et->flags.may_postdate = 1;
}
if(f.postdated){
if(!ticket->tkt.flags.may_postdate)
return KRB5KDC_ERR_BADOPTION;
et->flags.postdated = 1;
et->flags.invalid = 1;
et->starttime = malloc(sizeof(*et->starttime));
*et->starttime = *req->req_body.from;
}
if(f.validate){
if(!ticket->tkt.flags.invalid)
return KRB5KDC_ERR_BADOPTION;
if(*ticket->tkt.starttime > kdc_time)
return KRB5KRB_AP_ERR_TKT_NYV;
/* XXX tkt = tgt */
et->flags.invalid = 0;
}
/* check for excess flags */
if(f.renew){
time_t old_life;
if(!ticket->tkt.flags.renewable)
return KRB5KDC_ERR_BADOPTION;
if(*ticket->tkt.renew_till >= kdc_time)
return KRB5KRB_AP_ERR_TKT_EXPIRED;
/* XXX tkt = tgt */
et->starttime = malloc(sizeof(*et->starttime));
*et->starttime = kdc_time;
old_life = ticket->tkt.endtime - *ticket->tkt.starttime;
et->endtime = MIN(*ticket->tkt.renew_till,
*et->starttime + old_life);
}else{
time_t till;
et->starttime = malloc(sizeof(*et->starttime));
*et->starttime = kdc_time;
}
req->req_body.cname = malloc(sizeof(*req->req_body.cname));
krb5_principal2principalname(req->req_body.cname,
ticket->enc_part2.client);
}
}
krb5_error_code
process_request(krb5_context context,
KDC_REQ *req,
krb5_data *reply)
{
krb5_error_code err;
krb5_principal princ;
@@ -61,7 +230,6 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
DB *db;
DBT key, value;
struct timeval now;
KDC_REP rep;
EncTicketPart et;
@@ -69,57 +237,103 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
struct db_entry *cname, *sname;
gettimeofday(&now, NULL);
memset(&rep, 0, sizeof(rep));
rep.pvno = 5;
if(req->msg_type == krb_as_req)
rep.msg_type = krb_as_rep;
else if(req->msg_type == krb_tgs_req){
rep.msg_type = krb_tgs_rep;
}else{
/* XXX */
return KRB5KRB_AP_ERR_MSG_TYPE;
}
err = principalname2krb5_principal (&princ,
*req->req_body.sname,
req->req_body.realm);
if(err) return err;
sname = db_fetch(context, princ);
if(sname == NULL){
krb5_mk_error(princ,
KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN,
reply);
return 0;
}
krb5_free_principal(princ);
memset(&et, 0, sizeof(et));
if(req->msg_type == krb_as_req)
as_rep(context, req, &et);
else
tgs_rep(context, req, &et);
err = principalname2krb5_principal (&princ,
*req->req_body.cname,
req->req_body.realm);
if(err) return err;
cname = db_fetch(context, princ);
if(cname == NULL){
krb5_mk_error(sname->principal,
KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN,
reply);
return 0;
}
krb5_free_principal(princ);
err = principalname2krb5_principal (&princ,
*req->req_body.sname,
req->req_body.realm);
if(err) return err;
sname = db_fetch(context, princ);
krb5_free_principal(princ);
memset(&rep, 0, sizeof(rep));
rep.pvno = 5;
rep.msg_type = krb_as_rep;
rep.crealm = req->req_body.realm;
krb5_principal2principalname(&rep.cname, cname->principal);
memset(&rep.ticket, 0, sizeof(rep.ticket));
rep.ticket.tkt_vno = 5;
rep.ticket.realm = req->req_body.realm;
krb5_principal2principalname(&rep.ticket.sname, sname->principal);
memset(&et, 0, sizeof(et));
et.flags.initial = 1;
et.key.keytype = sname->keyblock.keytype;
et.key.keyvalue.data = sname->keyblock.contents.data;
et.key.keyvalue.length = sname->keyblock.contents.length;
mk_des_keyblock(&et.key);
et.crealm = req->req_body.realm;
krb5_principal2principalname(&et.cname, cname->principal);
gettimeofday(&now, NULL);
et.authtime = now.tv_sec;
et.cname = *req->req_body.cname;
et.authtime = kdc_time;
{
time_t till;
time_t start = et.authtime;
if(et.starttime)
start = *et.starttime;
till = req->req_body.till;
till = MIN(till, now.tv_sec + sname->max_life);
till = MIN(till, now.tv_sec + cname->max_life);
if(till == 0)
till = start + cname->max_life;
till = MIN(till, start + sname->max_life);
till = MIN(till, start + cname->max_life);
et.endtime = till;
}
if(req->req_body.kdc_options.renewable && req->req_body.rtime){
time_t rtime;
time_t start = et.authtime;
if(et.starttime)
start = *et.starttime;
rtime = *req->req_body.rtime;
if(rtime == 0)
rtime = start + cname->max_renew;
rtime = MIN(rtime, start + sname->max_renew);
rtime = MIN(rtime, start + cname->max_renew);
if(rtime > et.endtime){
et.renew_till = malloc(sizeof(*et.renew_till));
*et.renew_till = rtime;
et.flags.renewable = 1;
}
}
memset(&ek, 0, sizeof(ek));
ek.key = et.key;
/* MIT must have at least one last_req */
ek.last_req.len = 1;
ek.last_req.val = malloc(sizeof(*ek.last_req.val));
ek.last_req.val->lr_type = 1;
ek.last_req.val->lr_type = 0;
ek.last_req.val->lr_value = 0;
ek.nonce = req->req_body.nonce;
ek.flags = et.flags;
@@ -127,8 +341,9 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
ek.starttime = et.starttime;
ek.endtime = et.endtime;
ek.renew_till = et.renew_till;
ek.srealm = et.crealm;
krb5_principal2principalname(&ek.sname, sname->principal);
ek.srealm = req->req_body.realm;
ek.sname = *req->req_body.sname;
ek.caddr = req->req_body.addresses;
{
unsigned char buf[1024];
@@ -140,7 +355,18 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
&sname->keyblock,
&rep.ticket.enc_part.cipher);
err = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf), &ek);
switch(rep.msg_type){
case krb_as_rep:
err = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf), &ek);
break;
case krb_tgs_rep:
err = encode_EncTGSRepPart(buf + sizeof(buf) - 1, sizeof(buf),
&ek);
break;
default:
abort();
break;
}
rep.enc_part.etype = ETYPE_DES_CBC_CRC;
rep.enc_part.kvno = NULL;
@@ -148,26 +374,37 @@ foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
&cname->keyblock,
&rep.enc_part.cipher);
*len = encode_AS_REP(reply + 1023, 1024, &rep);
memmove(reply, reply + 1024 - *len, *len);
switch(rep.msg_type){
case krb_as_rep:
reply->length = encode_AS_REP(buf + sizeof(buf) - 1,
sizeof(buf), &rep);
break;
case krb_tgs_rep:
reply->length = encode_TGS_REP(buf + sizeof(buf) - 1,
sizeof(buf), &rep);
break;
}
reply->data = malloc(reply->length);
memcpy(reply->data, buf + sizeof(buf) - reply->length, reply->length);
}
return 0;
}
int
kerberos(krb5_context context, unsigned char *buf, size_t len)
kerberos(krb5_context context,
unsigned char *buf,
size_t len,
krb5_data *reply)
{
KDC_REQ req;
int i;
i = decode_AS_REQ(buf, len, &req);
if(i >= 0){
foo(context, &req, buf, &len);
return len;
return process_request(context, &req, reply);
}
i = decode_TGS_REQ(buf, len, &req);
if(i >= 0){
foo(context, &req, buf, &len);
return len;
return process_request(context, &req, reply);
}
return -1;
}
@@ -204,11 +441,18 @@ main(int argc, char **argv)
if(FD_ISSET(s, &fds)){
struct sockaddr_in from;
int from_len = sizeof(from);
krb5_error_code err;
krb5_data reply;
len = recvfrom(s, buf, sizeof(buf), 0,
(struct sockaddr*)&from, &from_len);
len = kerberos(context, buf, len);
sendto(s, buf, len, 0,
(struct sockaddr*)&from, from_len);
err = kerberos(context, buf, len, &reply);
if(err){
fprintf(stderr, "%s\n", krb5_get_err_text(context, err));
}else{
sendto(s, reply.data, reply.length, 0,
(struct sockaddr*)&from, from_len);
krb5_data_free(&reply);
}
}
}
}