The beginnings of a kdc.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1305 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
10
admin/Makefile.am
Normal file
10
admin/Makefile.am
Normal file
@@ -0,0 +1,10 @@
|
||||
# $Id$
|
||||
|
||||
AUTOHEADER_FLAGS = no-dependencies
|
||||
|
||||
INCLUDES = -I$(top_builddir)/include
|
||||
|
||||
bin_PROGRAMS = load string2key kdc
|
||||
|
||||
LDADD = -L$(top_builddir)/lib/krb5 -lkrb5 -L$(top_builddir)/lib/des -ldes -L$(top_builddir)/lib/asn1 -lasn1
|
||||
|
99
admin/load.c
Normal file
99
admin/load.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *f;
|
||||
DB *db;
|
||||
krb5_context context;
|
||||
char s[1024];
|
||||
char *p;
|
||||
int line;
|
||||
unsigned char key_buf[1024];
|
||||
unsigned char *q;
|
||||
unsigned char value_buf[1024];
|
||||
krb5_keyblock keyblock;
|
||||
DBT key, value;
|
||||
int err;
|
||||
int i;
|
||||
krb5_storage *sp;
|
||||
|
||||
struct entry e;
|
||||
|
||||
krb5_principal princ;
|
||||
|
||||
krb5_init_context(&context);
|
||||
f = fopen(argv[1], "r");
|
||||
db = dbopen(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0600, DB_BTREE, NULL);
|
||||
line = 0;
|
||||
while(fgets(s, sizeof(s), f)){
|
||||
line++;
|
||||
e.principal = s;
|
||||
for(p = s; *p; p++){
|
||||
if(*p == '\\')
|
||||
p++;
|
||||
else if(isspace(*p)) {
|
||||
*p == 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.key = p;
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.kvno = p;
|
||||
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.max_life = p;
|
||||
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
e.max_renew = p;
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
|
||||
err = krb5_parse_name(context, e.principal, &princ);
|
||||
if(err){
|
||||
fprintf(stderr, "%s:%s:%s (%s)\n",
|
||||
argv[1],
|
||||
line,
|
||||
krb5_get_err_text(context, err),
|
||||
e.principal);
|
||||
continue;
|
||||
}
|
||||
|
||||
sp = krb5_storage_from_mem(key_buf, sizeof(key_buf));
|
||||
princ->type = 0;
|
||||
krb5_store_principal(sp, princ);
|
||||
key.data = key_buf;
|
||||
key.size = sp->seek(sp, 0, SEEK_CUR);
|
||||
krb5_storage_free(sp);
|
||||
|
||||
keyblock.keytype = KEYTYPE_DES;
|
||||
keyblock.contents.data = malloc(strlen(e.key)/2+1);
|
||||
for(i = 0; i < strlen(e.key); i += 2){
|
||||
sscanf(e.key + i, "%2x",
|
||||
(unsigned char *)keyblock.contents.data + (i/2));
|
||||
}
|
||||
keyblock.contents.length = i / 2;
|
||||
sp = krb5_storage_from_mem(value_buf, sizeof(value_buf));
|
||||
krb5_store_keyblock(sp, keyblock);
|
||||
krb5_store_int32(sp, atoi(e.kvno));
|
||||
krb5_store_int32(sp, atoi(e.max_life));
|
||||
krb5_store_int32(sp, atoi(e.max_renew));
|
||||
value.data = value_buf;
|
||||
value.size = sp->seek(sp, 0, SEEK_CUR);
|
||||
db->put(db, &key, &value, 0);
|
||||
krb5_storage_free(sp);
|
||||
}
|
||||
db->close(db);
|
||||
}
|
99
kadmin/load.c
Normal file
99
kadmin/load.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *f;
|
||||
DB *db;
|
||||
krb5_context context;
|
||||
char s[1024];
|
||||
char *p;
|
||||
int line;
|
||||
unsigned char key_buf[1024];
|
||||
unsigned char *q;
|
||||
unsigned char value_buf[1024];
|
||||
krb5_keyblock keyblock;
|
||||
DBT key, value;
|
||||
int err;
|
||||
int i;
|
||||
krb5_storage *sp;
|
||||
|
||||
struct entry e;
|
||||
|
||||
krb5_principal princ;
|
||||
|
||||
krb5_init_context(&context);
|
||||
f = fopen(argv[1], "r");
|
||||
db = dbopen(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0600, DB_BTREE, NULL);
|
||||
line = 0;
|
||||
while(fgets(s, sizeof(s), f)){
|
||||
line++;
|
||||
e.principal = s;
|
||||
for(p = s; *p; p++){
|
||||
if(*p == '\\')
|
||||
p++;
|
||||
else if(isspace(*p)) {
|
||||
*p == 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.key = p;
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.kvno = p;
|
||||
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.max_life = p;
|
||||
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
e.max_renew = p;
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
|
||||
err = krb5_parse_name(context, e.principal, &princ);
|
||||
if(err){
|
||||
fprintf(stderr, "%s:%s:%s (%s)\n",
|
||||
argv[1],
|
||||
line,
|
||||
krb5_get_err_text(context, err),
|
||||
e.principal);
|
||||
continue;
|
||||
}
|
||||
|
||||
sp = krb5_storage_from_mem(key_buf, sizeof(key_buf));
|
||||
princ->type = 0;
|
||||
krb5_store_principal(sp, princ);
|
||||
key.data = key_buf;
|
||||
key.size = sp->seek(sp, 0, SEEK_CUR);
|
||||
krb5_storage_free(sp);
|
||||
|
||||
keyblock.keytype = KEYTYPE_DES;
|
||||
keyblock.contents.data = malloc(strlen(e.key)/2+1);
|
||||
for(i = 0; i < strlen(e.key); i += 2){
|
||||
sscanf(e.key + i, "%2x",
|
||||
(unsigned char *)keyblock.contents.data + (i/2));
|
||||
}
|
||||
keyblock.contents.length = i / 2;
|
||||
sp = krb5_storage_from_mem(value_buf, sizeof(value_buf));
|
||||
krb5_store_keyblock(sp, keyblock);
|
||||
krb5_store_int32(sp, atoi(e.kvno));
|
||||
krb5_store_int32(sp, atoi(e.max_life));
|
||||
krb5_store_int32(sp, atoi(e.max_renew));
|
||||
value.data = value_buf;
|
||||
value.size = sp->seek(sp, 0, SEEK_CUR);
|
||||
db->put(db, &key, &value, 0);
|
||||
krb5_storage_free(sp);
|
||||
}
|
||||
db->close(db);
|
||||
}
|
10
kdc/Makefile.am
Normal file
10
kdc/Makefile.am
Normal file
@@ -0,0 +1,10 @@
|
||||
# $Id$
|
||||
|
||||
AUTOHEADER_FLAGS = no-dependencies
|
||||
|
||||
INCLUDES = -I$(top_builddir)/include
|
||||
|
||||
bin_PROGRAMS = load string2key kdc
|
||||
|
||||
LDADD = -L$(top_builddir)/lib/krb5 -lkrb5 -L$(top_builddir)/lib/des -ldes -L$(top_builddir)/lib/asn1 -lasn1
|
||||
|
214
kdc/kdc.c
Normal file
214
kdc/kdc.c
Normal file
@@ -0,0 +1,214 @@
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
struct db_entry*
|
||||
db_fetch(krb5_context context, krb5_principal princ)
|
||||
{
|
||||
DB *db;
|
||||
DBT key, value;
|
||||
krb5_storage *sp;
|
||||
struct db_entry *ent;
|
||||
int i;
|
||||
int32_t tmp;
|
||||
key.size = princ->realm.length;
|
||||
for(i = 0; i < princ->ncomp; i++)
|
||||
key.size += princ->comp[i].length;
|
||||
key.size += (princ->ncomp + 3) * 4;
|
||||
key.data = malloc(key.size);
|
||||
sp = krb5_storage_from_mem(key.data, key.size);
|
||||
tmp = princ->type;
|
||||
princ->type = 0;
|
||||
krb5_store_principal(sp, princ);
|
||||
princ->type = tmp;
|
||||
krb5_storage_free(sp);
|
||||
|
||||
db = dbopen("foo.db", O_RDONLY, 0, DB_BTREE, NULL);
|
||||
if(db->get(db, &key, &value, 0)){
|
||||
db->close(db);
|
||||
return NULL;
|
||||
}
|
||||
sp = krb5_storage_from_mem(value.data, value.size);
|
||||
ent = malloc(sizeof(struct db_entry));
|
||||
krb5_copy_principal(context, princ, &ent->principal);
|
||||
krb5_ret_keyblock(sp, &ent->keyblock);
|
||||
krb5_ret_int32(sp, &tmp);
|
||||
ent->kvno = tmp;
|
||||
krb5_ret_int32(sp, &tmp);
|
||||
ent->max_life = tmp;
|
||||
krb5_ret_int32(sp, &tmp);
|
||||
ent->max_renew = tmp;
|
||||
krb5_storage_free(sp);
|
||||
db->close(db);
|
||||
return ent;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_encrypt (krb5_context context,
|
||||
void *ptr,
|
||||
size_t len,
|
||||
krb5_keyblock *keyblock,
|
||||
krb5_data *result);
|
||||
|
||||
|
||||
krb5_error_code
|
||||
foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
|
||||
{
|
||||
krb5_error_code err;
|
||||
krb5_principal princ;
|
||||
unsigned char key_buf[1024];
|
||||
unsigned char *q;
|
||||
DB *db;
|
||||
DBT key, value;
|
||||
|
||||
struct timeval now;
|
||||
|
||||
KDC_REP rep;
|
||||
EncTicketPart et;
|
||||
EncKDCRepPart ek;
|
||||
|
||||
|
||||
struct db_entry *cname, *sname;
|
||||
|
||||
err = principalname2krb5_principal (&princ,
|
||||
*req->req_body.cname,
|
||||
req->req_body.realm);
|
||||
if(err) return err;
|
||||
cname = db_fetch(context, princ);
|
||||
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;
|
||||
et.crealm = req->req_body.realm;
|
||||
krb5_principal2principalname(&et.cname, cname->principal);
|
||||
gettimeofday(&now, NULL);
|
||||
et.authtime = now.tv_sec;
|
||||
{
|
||||
time_t till;
|
||||
till = req->req_body.till;
|
||||
till = MIN(till, now.tv_sec + sname->max_life);
|
||||
till = MIN(till, now.tv_sec + cname->max_life);
|
||||
et.endtime = till;
|
||||
}
|
||||
|
||||
|
||||
memset(&ek, 0, sizeof(ek));
|
||||
ek.key = et.key;
|
||||
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_value = 0;
|
||||
ek.nonce = req->req_body.nonce;
|
||||
ek.flags = et.flags;
|
||||
ek.authtime = et.authtime;
|
||||
ek.starttime = et.starttime;
|
||||
ek.endtime = et.endtime;
|
||||
ek.renew_till = et.renew_till;
|
||||
ek.srealm = et.crealm;
|
||||
krb5_principal2principalname(&ek.sname, sname->principal);
|
||||
|
||||
{
|
||||
unsigned char buf[1024];
|
||||
err = encode_EncTicketPart(buf + sizeof(buf) - 1, sizeof(buf), &et);
|
||||
|
||||
rep.ticket.enc_part.etype = ETYPE_DES_CBC_CRC;
|
||||
rep.ticket.enc_part.kvno = NULL;
|
||||
err = krb5_encrypt(context, buf + sizeof(buf) - err, err,
|
||||
&sname->keyblock,
|
||||
&rep.ticket.enc_part.cipher);
|
||||
|
||||
err = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf), &ek);
|
||||
|
||||
rep.enc_part.etype = ETYPE_DES_CBC_CRC;
|
||||
rep.enc_part.kvno = NULL;
|
||||
err = krb5_encrypt(context, buf + sizeof(buf) - err, err,
|
||||
&cname->keyblock,
|
||||
&rep.enc_part.cipher);
|
||||
|
||||
*len = encode_AS_REP(reply + 1023, 1024, &rep);
|
||||
memmove(reply, reply + 1024 - *len, *len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kerberos(krb5_context context, unsigned char *buf, size_t len)
|
||||
{
|
||||
KDC_REQ req;
|
||||
int i;
|
||||
i = decode_AS_REQ(buf, len, &req);
|
||||
if(i >= 0){
|
||||
foo(context, &req, buf, &len);
|
||||
return len;
|
||||
}
|
||||
i = decode_TGS_REQ(buf, len, &req);
|
||||
if(i >= 0){
|
||||
foo(context, &req, buf, &len);
|
||||
return len;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
krb5_context context;
|
||||
int s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
struct sockaddr_in sin;
|
||||
int one = 1;
|
||||
if(s < 0){
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
krb5_init_context(&context);
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(88);
|
||||
if(bind(s, (struct sockaddr*)&sin, sizeof(sin)) < 0){
|
||||
perror("bind");
|
||||
exit(1);
|
||||
}
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
while(1){
|
||||
fd_set fds;
|
||||
unsigned char buf[1024];
|
||||
size_t len;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(s, &fds);
|
||||
if(select(s + 1, &fds, NULL, NULL, NULL) < 0){
|
||||
perror("select");
|
||||
exit(1);
|
||||
}
|
||||
if(FD_ISSET(s, &fds)){
|
||||
struct sockaddr_in from;
|
||||
int from_len = sizeof(from);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
17
kdc/kdc.h
Normal file
17
kdc/kdc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __KDC_H__
|
||||
#define __KDC_H__
|
||||
|
||||
struct db_entry{
|
||||
krb5_principal principal;
|
||||
krb5_keyblock keyblock;
|
||||
int kvno;
|
||||
time_t max_life;
|
||||
time_t max_renew;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __KDC_H__ */
|
31
kdc/kdc_locl.h
Normal file
31
kdc/kdc_locl.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __KDC_LOCL_H__
|
||||
#define __KDC_LOCL_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <db.h>
|
||||
#include <krb5.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "kdc.h"
|
||||
|
||||
struct entry{
|
||||
char *principal;
|
||||
char *key;
|
||||
char *kvno;
|
||||
char *max_life;
|
||||
char *max_renew;
|
||||
};
|
||||
|
||||
#endif /* __KDC_LOCL_H__ */
|
214
kdc/kerberos5.c
Normal file
214
kdc/kerberos5.c
Normal file
@@ -0,0 +1,214 @@
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
struct db_entry*
|
||||
db_fetch(krb5_context context, krb5_principal princ)
|
||||
{
|
||||
DB *db;
|
||||
DBT key, value;
|
||||
krb5_storage *sp;
|
||||
struct db_entry *ent;
|
||||
int i;
|
||||
int32_t tmp;
|
||||
key.size = princ->realm.length;
|
||||
for(i = 0; i < princ->ncomp; i++)
|
||||
key.size += princ->comp[i].length;
|
||||
key.size += (princ->ncomp + 3) * 4;
|
||||
key.data = malloc(key.size);
|
||||
sp = krb5_storage_from_mem(key.data, key.size);
|
||||
tmp = princ->type;
|
||||
princ->type = 0;
|
||||
krb5_store_principal(sp, princ);
|
||||
princ->type = tmp;
|
||||
krb5_storage_free(sp);
|
||||
|
||||
db = dbopen("foo.db", O_RDONLY, 0, DB_BTREE, NULL);
|
||||
if(db->get(db, &key, &value, 0)){
|
||||
db->close(db);
|
||||
return NULL;
|
||||
}
|
||||
sp = krb5_storage_from_mem(value.data, value.size);
|
||||
ent = malloc(sizeof(struct db_entry));
|
||||
krb5_copy_principal(context, princ, &ent->principal);
|
||||
krb5_ret_keyblock(sp, &ent->keyblock);
|
||||
krb5_ret_int32(sp, &tmp);
|
||||
ent->kvno = tmp;
|
||||
krb5_ret_int32(sp, &tmp);
|
||||
ent->max_life = tmp;
|
||||
krb5_ret_int32(sp, &tmp);
|
||||
ent->max_renew = tmp;
|
||||
krb5_storage_free(sp);
|
||||
db->close(db);
|
||||
return ent;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_encrypt (krb5_context context,
|
||||
void *ptr,
|
||||
size_t len,
|
||||
krb5_keyblock *keyblock,
|
||||
krb5_data *result);
|
||||
|
||||
|
||||
krb5_error_code
|
||||
foo(krb5_context context, KDC_REQ *req, unsigned char *reply, size_t *len)
|
||||
{
|
||||
krb5_error_code err;
|
||||
krb5_principal princ;
|
||||
unsigned char key_buf[1024];
|
||||
unsigned char *q;
|
||||
DB *db;
|
||||
DBT key, value;
|
||||
|
||||
struct timeval now;
|
||||
|
||||
KDC_REP rep;
|
||||
EncTicketPart et;
|
||||
EncKDCRepPart ek;
|
||||
|
||||
|
||||
struct db_entry *cname, *sname;
|
||||
|
||||
err = principalname2krb5_principal (&princ,
|
||||
*req->req_body.cname,
|
||||
req->req_body.realm);
|
||||
if(err) return err;
|
||||
cname = db_fetch(context, princ);
|
||||
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;
|
||||
et.crealm = req->req_body.realm;
|
||||
krb5_principal2principalname(&et.cname, cname->principal);
|
||||
gettimeofday(&now, NULL);
|
||||
et.authtime = now.tv_sec;
|
||||
{
|
||||
time_t till;
|
||||
till = req->req_body.till;
|
||||
till = MIN(till, now.tv_sec + sname->max_life);
|
||||
till = MIN(till, now.tv_sec + cname->max_life);
|
||||
et.endtime = till;
|
||||
}
|
||||
|
||||
|
||||
memset(&ek, 0, sizeof(ek));
|
||||
ek.key = et.key;
|
||||
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_value = 0;
|
||||
ek.nonce = req->req_body.nonce;
|
||||
ek.flags = et.flags;
|
||||
ek.authtime = et.authtime;
|
||||
ek.starttime = et.starttime;
|
||||
ek.endtime = et.endtime;
|
||||
ek.renew_till = et.renew_till;
|
||||
ek.srealm = et.crealm;
|
||||
krb5_principal2principalname(&ek.sname, sname->principal);
|
||||
|
||||
{
|
||||
unsigned char buf[1024];
|
||||
err = encode_EncTicketPart(buf + sizeof(buf) - 1, sizeof(buf), &et);
|
||||
|
||||
rep.ticket.enc_part.etype = ETYPE_DES_CBC_CRC;
|
||||
rep.ticket.enc_part.kvno = NULL;
|
||||
err = krb5_encrypt(context, buf + sizeof(buf) - err, err,
|
||||
&sname->keyblock,
|
||||
&rep.ticket.enc_part.cipher);
|
||||
|
||||
err = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf), &ek);
|
||||
|
||||
rep.enc_part.etype = ETYPE_DES_CBC_CRC;
|
||||
rep.enc_part.kvno = NULL;
|
||||
err = krb5_encrypt(context, buf + sizeof(buf) - err, err,
|
||||
&cname->keyblock,
|
||||
&rep.enc_part.cipher);
|
||||
|
||||
*len = encode_AS_REP(reply + 1023, 1024, &rep);
|
||||
memmove(reply, reply + 1024 - *len, *len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kerberos(krb5_context context, unsigned char *buf, size_t len)
|
||||
{
|
||||
KDC_REQ req;
|
||||
int i;
|
||||
i = decode_AS_REQ(buf, len, &req);
|
||||
if(i >= 0){
|
||||
foo(context, &req, buf, &len);
|
||||
return len;
|
||||
}
|
||||
i = decode_TGS_REQ(buf, len, &req);
|
||||
if(i >= 0){
|
||||
foo(context, &req, buf, &len);
|
||||
return len;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
krb5_context context;
|
||||
int s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
struct sockaddr_in sin;
|
||||
int one = 1;
|
||||
if(s < 0){
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
krb5_init_context(&context);
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(88);
|
||||
if(bind(s, (struct sockaddr*)&sin, sizeof(sin)) < 0){
|
||||
perror("bind");
|
||||
exit(1);
|
||||
}
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
while(1){
|
||||
fd_set fds;
|
||||
unsigned char buf[1024];
|
||||
size_t len;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(s, &fds);
|
||||
if(select(s + 1, &fds, NULL, NULL, NULL) < 0){
|
||||
perror("select");
|
||||
exit(1);
|
||||
}
|
||||
if(FD_ISSET(s, &fds)){
|
||||
struct sockaddr_in from;
|
||||
int from_len = sizeof(from);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
99
kdc/load.c
Normal file
99
kdc/load.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *f;
|
||||
DB *db;
|
||||
krb5_context context;
|
||||
char s[1024];
|
||||
char *p;
|
||||
int line;
|
||||
unsigned char key_buf[1024];
|
||||
unsigned char *q;
|
||||
unsigned char value_buf[1024];
|
||||
krb5_keyblock keyblock;
|
||||
DBT key, value;
|
||||
int err;
|
||||
int i;
|
||||
krb5_storage *sp;
|
||||
|
||||
struct entry e;
|
||||
|
||||
krb5_principal princ;
|
||||
|
||||
krb5_init_context(&context);
|
||||
f = fopen(argv[1], "r");
|
||||
db = dbopen(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0600, DB_BTREE, NULL);
|
||||
line = 0;
|
||||
while(fgets(s, sizeof(s), f)){
|
||||
line++;
|
||||
e.principal = s;
|
||||
for(p = s; *p; p++){
|
||||
if(*p == '\\')
|
||||
p++;
|
||||
else if(isspace(*p)) {
|
||||
*p == 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.key = p;
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.kvno = p;
|
||||
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
while(*p && isspace(*p)) p++;
|
||||
e.max_life = p;
|
||||
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
e.max_renew = p;
|
||||
while(*p && !isspace(*p))
|
||||
*p++;
|
||||
*p++ = 0;
|
||||
|
||||
err = krb5_parse_name(context, e.principal, &princ);
|
||||
if(err){
|
||||
fprintf(stderr, "%s:%s:%s (%s)\n",
|
||||
argv[1],
|
||||
line,
|
||||
krb5_get_err_text(context, err),
|
||||
e.principal);
|
||||
continue;
|
||||
}
|
||||
|
||||
sp = krb5_storage_from_mem(key_buf, sizeof(key_buf));
|
||||
princ->type = 0;
|
||||
krb5_store_principal(sp, princ);
|
||||
key.data = key_buf;
|
||||
key.size = sp->seek(sp, 0, SEEK_CUR);
|
||||
krb5_storage_free(sp);
|
||||
|
||||
keyblock.keytype = KEYTYPE_DES;
|
||||
keyblock.contents.data = malloc(strlen(e.key)/2+1);
|
||||
for(i = 0; i < strlen(e.key); i += 2){
|
||||
sscanf(e.key + i, "%2x",
|
||||
(unsigned char *)keyblock.contents.data + (i/2));
|
||||
}
|
||||
keyblock.contents.length = i / 2;
|
||||
sp = krb5_storage_from_mem(value_buf, sizeof(value_buf));
|
||||
krb5_store_keyblock(sp, keyblock);
|
||||
krb5_store_int32(sp, atoi(e.kvno));
|
||||
krb5_store_int32(sp, atoi(e.max_life));
|
||||
krb5_store_int32(sp, atoi(e.max_renew));
|
||||
value.data = value_buf;
|
||||
value.size = sp->seek(sp, 0, SEEK_CUR);
|
||||
db->put(db, &key, &value, 0);
|
||||
krb5_storage_free(sp);
|
||||
}
|
||||
db->close(db);
|
||||
}
|
20
kdc/string2key.c
Normal file
20
kdc/string2key.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
krb5_context context;
|
||||
krb5_principal princ;
|
||||
krb5_data salt;
|
||||
krb5_keyblock key;
|
||||
int i;
|
||||
krb5_init_context(&context);
|
||||
krb5_parse_name(context, argv[1], &princ);
|
||||
salt.length = salt.data = 0;
|
||||
krb5_get_salt(princ, &salt);
|
||||
krb5_string_to_key(argv[2], &salt, &key);
|
||||
for(i = 0; i < key.contents.length; i++)
|
||||
printf("%02x", ((unsigned char*)key.contents.data)[i]);
|
||||
printf("\n");
|
||||
}
|
Reference in New Issue
Block a user