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
	 Johan Danielsson
					Johan Danielsson