kinit now builds and works on some machines

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@302 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1996-03-17 14:59:05 +00:00
parent 2968019168
commit e2475934ac
33 changed files with 781 additions and 432 deletions

View File

@@ -1,16 +1,21 @@
CC=cc -std1 CC=cc
CFLAGS=-I/usr/athena/include -g CFLAGS=-I. -I/usr/athena/include -g
YFLAGS = -d #YACC=bison -y
YACC=yacc
SOURCES = cache.c principal.c principal_p.c data.c context.c misc.c \ SOURCES = cache.c principal.c principal_p.c data.c context.c misc.c \
krbhst.c getport.c send_to_kdc.c der.c e.c d.c str2key.c \ krbhst.c get_port.c send_to_kdc.c der.c e.c d.c str2key.c \
get_in_tkt.c get_in_tkt_pw.c get_in_tkt.c get_in_tkt_pw.c der_put.c constants.c get_addrs.c \
k5_der.c
OBJECTS = $(SOURCES:%.c=%.o) config_file.o OBJECTS = $(SOURCES:%.c=%.o) config_file.o
kinit: kinit.o libkrb5.a
$(CC) -o kinit kinit.o libkrb5.a -L/usr/local/lib -ldes
tt: test.o libkrb5.a tt: test.o libkrb5.a
$(CC) -o tt test.o libkrb5.a $(CC) -o tt test.o libkrb5.a
@@ -23,7 +28,7 @@ libkrb5.a: $(OBJECTS)
config_file.o: config_file.c config_file.o: config_file.c
config_file.c: config_file.y config_file.c: config_file.y
yacc -b y -p __k5cf_ $< $(YACC) -p __k5cf_ $<
mv -f y.tab.c config_file.c mv -f y.tab.c config_file.c
clean: clean:

View File

@@ -46,6 +46,10 @@ krb5_error_code
krb5_cc_default(krb5_context context, krb5_cc_default(krb5_context context,
krb5_ccache *id) krb5_ccache *id)
{ {
*id = malloc(sizeof(**id));
if (*id == NULL)
return ENOMEM;
return krb5_cc_resolve (context, id, "/tmp/foo");
} }
static krb5_error_code static krb5_error_code
@@ -112,7 +116,7 @@ krb5_cc_initialize(krb5_context context,
if(ret = erase_file(f->filename)) if(ret = erase_file(f->filename))
return ret; return ret;
fd = open(f->filename, O_RDWR, 0600); fd = open(f->filename, O_RDWR | O_CREAT | O_EXCL, 0600);
if(fd == -1) if(fd == -1)
return errno; return errno;
store_int16(fd, 0x503); store_int16(fd, 0x503);

View File

@@ -19,6 +19,9 @@ static krb5_config_relation **crel;
static krb5_config_relation **rels[16]; static krb5_config_relation **rels[16];
static int relp; static int relp;
static void yyerror (char *);
static int yylex (void);
%} %}
%union { %union {
@@ -143,7 +146,7 @@ static int yylex(void)
return type; return type;
} }
static void yyerror(char *s) void yyerror(char *s)
{ {
printf("yyerror: %s\n", s); printf("yyerror: %s\n", s);
} }

9
d.c
View File

@@ -1,6 +1,4 @@
#include <stdio.h> #include <krb5_locl.h>
#include <stdlib.h>
#include <time.h>
#include <d.h> #include <d.h>
int int
@@ -160,8 +158,8 @@ der_get_octetstring (Buffer *b, void *val)
char *p; char *p;
len = buf_bytesleft (b); len = buf_bytesleft (b);
str->len = len; str->length = len;
str->data = p = malloc (len + 1); str->data = p = malloc (len + 1);
while (len && (c = buf_getbyte (b)) != EOF) { while (len && (c = buf_getbyte (b)) != EOF) {
*p++ = c; *p++ = c;
--len; --len;
@@ -177,6 +175,7 @@ der_get_generalizedtime (Buffer *b, void *val)
int len; int len;
krb5_data str; krb5_data str;
struct tm tm; struct tm tm;
extern long timezone;
len = der_get_octetstring (b, &str); len = der_get_octetstring (b, &str);
sscanf (str.data, "%04d%02d%02d%02d%02d%02dZ", sscanf (str.data, "%04d%02d%02d%02d%02d%02dZ",

5
der.c
View File

@@ -1,5 +1,4 @@
#include <stdlib.h> #include <krb5_locl.h>
#include <string.h>
#include <der.h> #include <der.h>
/* /*
@@ -11,7 +10,7 @@ string_make_n (int n, char *s)
{ {
krb5_data ret; krb5_data ret;
ret.len = n; ret.length = n;
ret.data = s; ret.data = s;
return ret; return ret;
} }

2
der.h
View File

@@ -20,7 +20,7 @@ enum {
UT_IA5String = 22, UT_IA5String = 22,
UT_UTCTime = 23, UT_UTCTime = 23,
UT_GeneralizedTime = 24, UT_GeneralizedTime = 24,
UT_GeneralString = 27, UT_GeneralString = 27
}; };
krb5_data string_make (char *); krb5_data string_make (char *);

179
der_get.c
View File

@@ -1,179 +0,0 @@
#include <malloc.h>
#include <string.h>
#include <der.h>
/*
* Functions for parsing DER
*/
unsigned
der_get_length (unsigned char *ptr, unsigned *res)
{
unsigned char *p = ptr;
unsigned char c;
c = *p++;
if (c < 0x80) {
*res = c;
return 1;
} else {
c &= 0x7F;
*res = 0;
while (c--)
*res = *res * 0x100 + *p++;
return p - ptr;
}
}
unsigned
der_get_tag (unsigned char *ptr, Der_class *class, Der_type *type,
unsigned *tag)
{
unsigned char *p = ptr;
unsigned char o1;
o1 = *p++;
*class = o1 >> 6;
*type = (o1 >> 5) & 1;
*tag = o1 & 0x1F;
if (*tag == 0x1F) {
do {
o1 = *p++;
*tag = *tag * 0x80 + (o1 & 0x7F);
} while( o1 & 0x80);
}
return p - ptr;
}
unsigned
der_get_integer (unsigned char *ptr, int len, void *v)
{
unsigned char *p = ptr;
unsigned *res = v;
*res = 0;
while(len--)
*res = *res * 0x100 + *p++;
return p - ptr;
}
unsigned
der_get_octetstring (unsigned char *ptr, int len, void *v)
{
unsigned char *p = ptr;
krb5_data *res = v;
res->data = malloc(len + 1);
res->len = len;
memcpy (*res, p, len);
(*res)[len] = '\0';
p += len;
return p - ptr;
}
static unsigned (*get_univ_funcs[])(unsigned char *, int len, void *val) = {
NULL, /* 0 */
NULL, /* 1 */
der_get_integer, /* 2 */
NULL, /* 3 */
der_get_octetstring, /* 4 */
NULL, /* 5 */
NULL, /* 6 */
NULL, /* 7 */
NULL, /* 8 */
NULL, /* 9 */
NULL, /* 10 */
NULL, /* 11 */
NULL, /* 12 */
NULL, /* 13 */
NULL, /* 14 */
NULL, /* 15 */
NULL, /* 16 */
NULL, /* 17 */
NULL, /* 18 */
NULL, /* 19 */
NULL, /* 20 */
NULL, /* 21 */
NULL, /* 22 */
NULL, /* 23 */
der_get_octetstring, /* 24 */
NULL, /* 25 */
NULL, /* 26 */
der_get_octetstring, /* 27 */
};
unsigned
der_get_val (unsigned char *ptr, int type, int len, void *val)
{
return (*(get_univ_funcs[type]))(ptr, len, val);
}
unsigned
der_get_type (unsigned char *ptr, Der_class *class, Der_type *type,
unsigned *tag, unsigned *len)
{
unsigned char *p = ptr;
return p - ptr;
}
int
der_match_type (unsigned char **ptr, Der_class class, Der_type type,
unsigned tag, unsigned *len)
{
unsigned char *p = ptr;
Der_class c1;
Der_type t1;
unsigned tag1;
p += der_get_tag (p, &c1, &t1, &tag1);
if (c1 != class || t1 != type || tag != tag1)
return -1;
p += der_get_length (p, len);
return p - ptr;
}
int
der_get_context (unsigned char *ptr, unsigned *tag, unsigned *type,
unsigned *len)
{
unsigned char *p = ptr;
Der_class class;
Der_type foo;
p += der_get_tag (p, &class, &foo, tag);
if (class != CONTEXT || foo != CONS )
return -1;
p += der_get_length (p, len);
p += der_get_tag (p, &class, &foo, type);
if (class != UNIV || foo != PRIM)
return -1;
p += der_get_length (p, len);
return p - ptr;
}
int
der_match_context (unsigned char *ptr, unsigned tag, int type, void *arg)
{
unsigned char *p = ptr;
int len;
int tlen;
len = der_match_type (p, CONTEXT, CONS, tag, &tlen);
if (len < 0)
return len;
else
p += len;
len = der_match_type (p, UNIV, PRIM, type, &tlen);
if (len < 0)
return len;
else
p += len;
p += der_get_val (p, type, tlen, arg);
return p - ptr;
}

150
der_put.c Normal file
View File

@@ -0,0 +1,150 @@
#include <krb5_locl.h>
#include <der.h>
/*
* Functions for generating DER
*/
/*
* All these functions generate the data backwards starting at `ptr'
* and return the length.
*/
unsigned
der_put_integer (unsigned char *ptr, void *v)
{
unsigned char *p = ptr;
unsigned i = *(int *)v;
if (i) {
while(i) {
*p-- = i % 0x100;
i /= 0x100;
}
return ptr - p;
} else {
*p = 0;
return 1;
}
}
unsigned
der_put_length (unsigned char *ptr, unsigned len)
{
unsigned char *p = ptr;
if (len < 0x80) {
*p = len;
return 1;
} else {
unsigned q;
q = der_put_integer (p, &len);
p -= q;
*p = 0x80 | q;
return q + 1;
}
}
unsigned
der_put_octetstring (unsigned char *ptr, void *v)
{
unsigned char *p = ptr;
krb5_data *str = (krb5_data *)v;
int len = str->length;
p -= len;
memcpy (p + 1, str->data, len);
return ptr - p;
}
unsigned
der_put_tag (unsigned char *ptr, Der_class class, Der_type type, unsigned tag)
{
unsigned char o1;
unsigned char *p = ptr;
o1 = (class << 6) | (type << 5);
if (tag < 0x1F)
o1 |= tag;
else {
o1 |= 0x1F;
*p-- = tag % 0x80;
tag /= 0x80;
while(tag) {
*p-- = 0x80 | (tag % 0x80);
tag /= 0x80;
}
}
*p-- = o1;
return ptr - p;
}
unsigned
der_put_type (unsigned char *ptr, Der_class class, Der_type type,
unsigned tag, unsigned len)
{
unsigned char *p = ptr;
p -= der_put_length (p, len);
p -= der_put_tag (p, class, type, tag);
return ptr - p;
}
static unsigned (*put_univ_funcs[])(unsigned char *, void *val) = {
NULL, /* 0 */
NULL, /* 1 */
der_put_integer, /* 2 */
NULL, /* 3 */
der_put_octetstring, /* 4 */
NULL, /* 5 */
NULL, /* 6 */
NULL, /* 7 */
NULL, /* 8 */
NULL, /* 9 */
NULL, /* 10 */
NULL, /* 11 */
NULL, /* 12 */
NULL, /* 13 */
NULL, /* 14 */
NULL, /* 15 */
NULL, /* 16 */
NULL, /* 17 */
NULL, /* 18 */
NULL, /* 19 */
NULL, /* 20 */
NULL, /* 21 */
NULL, /* 22 */
NULL, /* 23 */
der_put_octetstring, /* 24 */
NULL, /* 25 */
NULL, /* 26 */
der_put_octetstring, /* 27 */
};
unsigned
der_put_val (unsigned char *ptr, int type, void *val)
{
return (*(put_univ_funcs[type]))(ptr, val);
}
unsigned
der_put_type_and_value (unsigned char *ptr, int type, void *val)
{
unsigned char *p = ptr;
p -= der_put_val (p, type, val);
p -= der_put_type (p, UNIV, PRIM, type, ptr - p);
return ptr - p;
}
unsigned
der_put_context (unsigned char *ptr, int tag, int type, void *val)
{
unsigned char *p = ptr;
p -= der_put_type_and_value (p, type, val);
p -= der_put_type (p, CONTEXT, CONS, tag, ptr - p);
return ptr - p;
}

31
e.c
View File

@@ -1,37 +1,38 @@
#include <stdio.h> #include <krb5_locl.h>
#include <stdlib.h>
#include <string.h>
#include <d.h> #include <d.h>
#include <k5_der.h> #include <k5_der.h>
int int
der_get_principalname (Buffer *b, PrincipalName *p) der_get_principalname (Buffer *b, krb5_principal *p)
{ {
Identifier i; Identifier i;
int cur, max; int cur, max;
char *str; char *str;
int len; int len;
p->num_strings = 0; *p = malloc(sizeof(**p));
if (*p == NULL)
return -1;
(*p)->ncomp = 0;
if (matchid3 (b, &i, UNIV, CONS, UT_Sequence) == NULL) if (matchid3 (b, &i, UNIV, CONS, UT_Sequence) == NULL)
return -1; return -1;
if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL)
return -1; return -1;
getdata (b, &i, &p->name_type); getdata (b, &i, &(*p)->type);
if (matchcontextid3 (b, &i, UNIV, CONS, UT_Sequence, 1) == NULL) if (matchcontextid3 (b, &i, UNIV, CONS, UT_Sequence, 1) == NULL)
return -1; return -1;
cur = 0; cur = 0;
max = 1; max = 1;
p->names = malloc(sizeof(char *) * max); (*p)->comp = malloc(sizeof(*(*p)->comp) * max);
while (matchid3 (b, &i, UNIV, PRIM, UT_GeneralString)) { while (matchid3 (b, &i, UNIV, PRIM, UT_GeneralString)) {
if (cur >= max) { if (cur >= max) {
max *= 2; max *= 2;
p->names = realloc (p->names, sizeof(char *) * max); (*p)->comp = realloc ((*p)->comp, sizeof(*(*p)->comp) * max);
} }
getdata (b, &i, &p->names[cur++]); getdata (b, &i, &(*p)->comp[cur++]);
} }
p->num_strings = cur; (*p)->ncomp = cur;
return buf_length (b); return buf_length (b);
} }
@@ -106,7 +107,7 @@ der_get_ticket (Buffer *b, Ticket *t)
} }
int int
der_get_kdc_rep (Buffer *b, int msg, Kdc_Rep *k) der_get_kdc_rep (Buffer *b, int msg, krb5_kdc_rep *k)
{ {
Identifier i, i0; Identifier i, i0;
Buffer tmp; Buffer tmp;
@@ -160,7 +161,7 @@ der_get_kdc_rep (Buffer *b, int msg, Kdc_Rep *k)
} }
static int static int
der_get_kdc_rep_msg (Buffer *b, int msg, Kdc_Rep *a) der_get_kdc_rep_msg (Buffer *b, int msg, krb5_kdc_rep *a)
{ {
Identifier i; Identifier i;
@@ -198,7 +199,7 @@ der_get_encryptionkey (Buffer *b, EncryptionKey *k)
} }
int int
der_get_hostaddresses (Buffer *b, HostAddresses *h) der_get_hostaddresses (Buffer *b, krb5_addresses *h)
{ {
Identifier i; Identifier i;
int cur, max; int cur, max;
@@ -215,10 +216,10 @@ der_get_hostaddresses (Buffer *b, HostAddresses *h)
} }
if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL)
return -1; return -1;
getdata (b, &i, &h->addrs[cur].addr_type); getdata (b, &i, &h->addrs[cur].type);
if (matchcontextid3 (b, &i, UNIV, PRIM, UT_OctetString, 1) == NULL) if (matchcontextid3 (b, &i, UNIV, PRIM, UT_OctetString, 1) == NULL)
return -1; return -1;
getdata (b, &i, &h->addrs[cur].addr); getdata (b, &i, &h->addrs[cur].address);
++cur; ++cur;
} }
h->number = cur; h->number = cur;

45
get_addrs.c Normal file
View File

@@ -0,0 +1,45 @@
#include "krb5_locl.h"
static krb5_error_code
get_addrs ()
{
/* here the code from krb4/lib/krb/getaddrs.c will go */
}
/*
* Try to get all addresses, but return the one corresponding to
* `hostname' if we fail.
*/
krb5_error_code
krb5_get_all_client_addrs (krb5_addresses *res)
{
krb5_error_code err;
char hostname[MAXHOSTNAMELEN];
struct hostent *hostent;
if (gethostname (hostname, sizeof(hostname)))
return errno;
hostent = gethostbyname (hostname);
if (hostent == NULL)
return errno;
res->number = 1;
res->addrs = malloc (sizeof(*res->addrs));
res->addrs[0].type = hostent->h_addrtype;
err = krb5_data_alloc (&res->addrs[0].address, hostent->h_length);
if (err)
return err;
memcpy (res->addrs[0].address.data,
hostent->h_addr,
hostent->h_length);
return 0;
}
/*
* Same as above, but with the fall-back to INADDR_ANY.
*/
krb5_error_code
krb5_get_all_server_addrs ()
{
}

View File

@@ -1,4 +1,7 @@
#include "krb5_locl.h" #include "krb5_locl.h"
#include <krb5_error.h>
#include <d.h>
#include <k5_der.h>
static krb5_error_code static krb5_error_code
krb5_get_salt (krb5_principal princ, krb5_get_salt (krb5_principal princ,
@@ -10,22 +13,52 @@ krb5_get_salt (krb5_principal princ,
krb5_error_code err; krb5_error_code err;
char *p; char *p;
len = realm->len; len = realm.length;
for (i = 0; i < princ->ncomp; ++i) for (i = 0; i < princ->ncomp; ++i)
len += princ->comp[i].length; len += princ->comp[i].length;
err = krb5_alloc (salt, len); err = krb5_data_alloc (salt, len);
if (err) if (err)
return err; return err;
p = salt->data; p = salt->data;
strncpy (p, realm->data, realm->len); strncpy (p, realm.data, realm.length);
p += realm->len; p += realm.length;
for (i = 0; i < princ->cnomp; ++i) { for (i = 0; i < princ->ncomp; ++i) {
strncpy (p, princ->comp[i].data, princ->comp[i].length); strncpy (p, princ->comp[i].data, princ->comp[i].length);
p += princ->comp[i].length; p += princ->comp[i].length;
} }
return 0; return 0;
} }
static krb5_error_code
decrypt_tkt (krb5_context context,
const krb5_keyblock *key,
krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep)
{
des_key_schedule sched;
char *buf;
Buffer buffer;
des_set_key (key->contents.data, sched);
buf = malloc (dec_rep->enc_part.cipher.length);
if (buf == NULL)
return ENOMEM;
des_cbc_encrypt ((des_cblock *)dec_rep->enc_part.cipher.data,
(des_cblock *)buf,
dec_rep->enc_part.cipher.length,
sched,
key->contents.data,
DES_DECRYPT);
/* XXX: Check CRC */
buf_init (&buffer, buf + 12, dec_rep->enc_part.cipher.length - 12);
if (der_get_enctgsreppart (&buffer, &dec_rep->enc_part2) == -1) {
free (buf);
return ASN1_PARSE_ERROR;
}
free (buf);
return 0;
}
/* /*
* *
*/ */
@@ -44,65 +77,82 @@ krb5_get_in_tkt(krb5_context context,
krb5_ccache ccache, krb5_ccache ccache,
krb5_kdc_rep **ret_as_reply) krb5_kdc_rep **ret_as_reply)
{ {
krb5_error_code err;
As_Req a; As_Req a;
Kdc_Rep rep; krb5_kdc_rep rep;
krb5_principal server; krb5_principal_data server;
krb5_data req, resp; krb5_data req, resp;
char buf[BUFSIZ]; char buf[BUFSIZ];
Buffer buf; Buffer buffer;
krb5_data salt; krb5_data salt;
krb5_keyblock *key; krb5_keyblock *key;
server.type = KRB_NT_SRV_INST; server.type = KRB5_NT_SRV_INST;
server.ncomp = 2; server.ncomp = 2;
server.comp = malloc (sizeof(*server.comp) * server.ncomp); server.comp = malloc (sizeof(*server.comp) * server.ncomp);
server.comp[0] = string_make ("krbtgt"); server.comp[0] = string_make ("krbtgt");
server.comp[1] = creds->client.realm; server.comp[1] = creds->client->realm;
a.pvno = 5; a.pvno = 5;
a.msg_type = KRB_AS_REQ; a.msg_type = KRB_AS_REQ;
/* a.kdc_options */ /* a.kdc_options */
a.cname = &creds->client; a.cname = creds->client;
a.sname = &server; a.sname = &server;
a.realm = creds->client.realm; a.realm = creds->client->realm;
a.till = creds->times.endtime; a.till = creds->times.endtime;
a.nonce = 17; a.nonce = 17;
if (etypes) if (etypes)
a.etypes = etypes; a.etypes = etypes;
else else {
a.etypes = context->etypes; err = krb5_get_default_in_tkt_etypes (context, &a.etypes);
if (addrs) if (err)
a.addresses = addrs; return err;
else a.num_etypes = 1;
a.addresses = krb5_get_all_client_addrs (); }
if (addrs){
} else {
err = krb5_get_all_client_addrs (&a.addrs);
if (err)
return err;
}
req.data = buf; req.length = der_put_as_req (buf + sizeof(buf) - 1, &a);
req.data = buf + sizeof(buf) - req.length;
req.len = der_put_as_req (req.data + sizeof(buf) - 1, &a);
string_free (server.comp[0]);
free (server.comp); free (server.comp);
if (addrs == NULL) if (addrs == NULL) {
free (a.addresses); int i;
err = krb5_sendto_kdc (context, &req, a.realm, &resp); for (i = 0; i < a.addrs.number; ++i)
krb5_data_free (&a.addrs.addrs[i].address);
free (a.addrs.addrs);
}
err = krb5_sendto_kdc (context, &req, &a.realm, &resp);
if (err) { if (err) {
return err; return err;
} }
buf_init (&buffer, resp.data, resp.len); buf_init (&buffer, resp.data, resp.length);
if (der_get_as_rep (&buffer, &rep) == -1) { if (der_get_as_rep (&buffer, &rep) == -1) {
return ASN1_PARSE_ERROR; return ASN1_PARSE_ERROR;
} }
err = krb5_get_salt (creds->client, creds->client.realm, &salt); salt.length = 0;
salt.data = NULL;
err = krb5_get_salt (creds->client, creds->client->realm, &salt);
if (err) if (err)
return err; return err;
err = (*key_proc)(context, b.enc_part.etype, salt, keyseed, &key); err = (*key_proc)(context, rep.enc_part.etype, &salt, keyseed, &key);
krb5_data_free (&salt); krb5_data_free (&salt);
if (err) if (err)
return err; return err;
if (decrypt_proc == NULL)
decrypt_proc = decrypt_tkt;
err = (*decrypt_proc)(context, key, decryptarg, &rep); err = (*decrypt_proc)(context, key, decryptarg, &rep);
memset (&key.contents.data, 0, key.contents.length); memset (key->contents.data, 0, key->contents.length);
krb5_data_free (&key.contents); krb5_data_free (&key->contents);
free (key);
if (err) if (err)
return err; return err;
return 0;
} }

View File

@@ -11,15 +11,17 @@ key_proc (krb5_context context,
char *password = (char *)keyseed; char *password = (char *)keyseed;
char buf[BUFSIZ]; char buf[BUFSIZ];
key = malloc (sizeof (*key)); *key = malloc (sizeof (**key));
if (key == NULL) if (*key == NULL)
return ENOMEM; return ENOMEM;
key->keytype = type; (*key)->keytype = type;
(*key)->contents.length = 0;
(*key)->contents.data = NULL;
if (password == NULL) { if (password == NULL) {
des_read_pw_string (buf, sizeof(buf), "Password: ", 0); des_read_pw_string (buf, sizeof(buf), "Password: ", 0);
password = buf; password = buf;
} }
err = krb5_string_to_key (password, salt, key); err = krb5_string_to_key (password, salt, *key);
memset (buf, 0, sizeof(buf)); memset (buf, 0, sizeof(buf));
return err; return err;
} }
@@ -33,9 +35,9 @@ krb5_get_in_tkt_with_password (krb5_context context,
const char *password, const char *password,
krb5_ccache ccache, krb5_ccache ccache,
krb5_creds *creds, krb5_creds *creds,
krb5_kdc-rep **ret_as_reply) krb5_kdc_rep **ret_as_reply)
{ {
return krb5_get_in_tkt (context, options, addrs, etypes, return krb5_get_in_tkt (context, options, addrs, etypes,
pre_auth_types, key_proc, password, pre_auth_types, key_proc, password,
NULL, NULL, creds, cache, ret_as_reply); NULL, NULL, creds, ccache, ret_as_reply);
} }

View File

@@ -1,8 +1,4 @@
#include <stdio.h> #include <krb5_locl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
#include <sys/time.h>
#include <k5_der.h> #include <k5_der.h>
static void static void
@@ -11,7 +7,7 @@ time2generalizedtime (krb5_data *s, time_t t)
struct tm *tm; struct tm *tm;
s->data = malloc(16); s->data = malloc(16);
s->len = 15; s->length = 15;
tm = gmtime (&t); tm = gmtime (&t);
sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900, sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
@@ -20,7 +16,7 @@ time2generalizedtime (krb5_data *s, time_t t)
unsigned unsigned
der_put_context_etypes (unsigned char *ptr, int tag, der_put_context_etypes (unsigned char *ptr, int tag,
EncryptionType *etypes, unsigned num_etypes) krb5_enctype *etypes, unsigned num_etypes)
{ {
unsigned char *p = ptr; unsigned char *p = ptr;
int i; int i;
@@ -34,19 +30,19 @@ der_put_context_etypes (unsigned char *ptr, int tag,
unsigned unsigned
der_put_context_principalname (unsigned char *ptr, int tag, der_put_context_principalname (unsigned char *ptr, int tag,
PrincipalName *name) krb5_principal name)
{ {
unsigned char *p = ptr; unsigned char *p = ptr;
int i; int i;
if (name == NULL) if (name == NULL)
return 0; return 0;
for (i = name->num_strings - 1; i >= 0; --i) for (i = name->ncomp - 1; i >= 0; --i)
p -= der_put_type_and_value (p, UT_GeneralString, p -= der_put_type_and_value (p, UT_GeneralString,
&name->names[i]); &name->comp[i]);
p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p);
p -= der_put_type (p, CONTEXT, CONS, 1, ptr - p); p -= der_put_type (p, CONTEXT, CONS, 1, ptr - p);
p -= der_put_context (p, 0, UT_Integer, &name->name_type); p -= der_put_context (p, 0, UT_Integer, &name->type);
p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p);
p -= der_put_type (p, CONTEXT, CONS, tag, ptr - p); p -= der_put_type (p, CONTEXT, CONS, tag, ptr - p);
return ptr - p; return ptr - p;
@@ -71,15 +67,16 @@ der_put_context_kdcoptions (unsigned char *ptr, int tag, KdcOptions *k)
unsigned unsigned
der_put_context_hostaddresses (unsigned char *ptr, int tag, der_put_context_hostaddresses (unsigned char *ptr, int tag,
HostAddress *addrs, krb5_addresses addrs)
unsigned naddr)
{ {
unsigned char *p = ptr; unsigned char *p = ptr;
int i; int i;
for(i = naddr - 1; i >= 0; --i) { for(i = addrs.number - 1; i >= 0; --i) {
p -= der_put_context (p, 1, UT_OctetString, &addrs[i].addr); p -= der_put_context (p, 1, UT_OctetString,
p -= der_put_context (p, 0, UT_Integer, &addrs[i].addr_type); &addrs.addrs[i].address);
p -= der_put_context (p, 0, UT_Integer,
&addrs.addrs[i].type);
} }
p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p);
p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p);
@@ -91,15 +88,13 @@ unsigned
der_put_kdc_req_body (unsigned char *ptr, Kdc_Req *k) der_put_kdc_req_body (unsigned char *ptr, Kdc_Req *k)
{ {
unsigned char *p = ptr; unsigned char *p = ptr;
unsigned random = 17;
/* additional-tickets[11] SEQUENCE OF Ticket OPTIONAL */ /* additional-tickets[11] SEQUENCE OF Ticket OPTIONAL */
/* enc-authorization-data[10] EncryptedData OPTIONAL */ /* enc-authorization-data[10] EncryptedData OPTIONAL */
p -= der_put_context_hostaddresses (p, 9, k->addrs, p -= der_put_context_hostaddresses (p, 9, k->addrs);
k->num_addrs);
/* addresses[9] HostAddresses OPTIONAL */ /* addresses[9] HostAddresses OPTIONAL */
p -= der_put_context_etypes (p, 8, k->etypes, k->num_etypes); p -= der_put_context_etypes (p, 8, k->etypes, k->num_etypes);
p -= der_put_context (p, 7, UT_Integer, &random); p -= der_put_context (p, 7, UT_Integer, &k->nonce);
/* rtime[6] KerberosTime OPTIONAL */ /* rtime[6] KerberosTime OPTIONAL */
{ {
krb5_data t; krb5_data t;
@@ -180,7 +175,7 @@ der_get_principalname (unsigned char *ptr, Principalname *name)
int int
der_get_kdc_rep (unsigned char *ptr, unsigned mylen, int msg_type, der_get_kdc_rep (unsigned char *ptr, unsigned mylen, int msg_type,
Kdc_Rep *k) krb5_kdc_rep *k)
{ {
unsigned char *p = ptr; unsigned char *p = ptr;
unsigned tlen, slen; unsigned tlen, slen;

View File

@@ -28,37 +28,6 @@ enum {
APPL_TICKET = 1 APPL_TICKET = 1
}; };
struct HostAddress {
int addr_type;
krb5_data addr;
};
typedef struct HostAddress HostAddress;
struct HostAddresses {
int number;
HostAddress *addrs;
};
typedef struct HostAddresses HostAddresses;
struct PrincipalName {
int name_type;
unsigned num_strings;
krb5_data *names;
};
enum {
nt_unknown = 0,
nt_principal = 1,
nt_srv_inst = 2,
nt_srv_hst = 3,
nt_srv_xhst = 4,
nt_uid = 5
};
typedef struct PrincipalName PrincipalName;
struct KdcOptions { struct KdcOptions {
unsigned unsigned
reserved : 1, reserved : 1,
@@ -81,22 +50,20 @@ struct KdcOptions {
typedef struct KdcOptions KdcOptions; typedef struct KdcOptions KdcOptions;
typedef krb5_data Realm;
typedef int EncryptionType; typedef int EncryptionType;
struct Kdc_Req { struct Kdc_Req {
int pvno; int pvno;
int msg_type; int msg_type;
KdcOptions kdc_options; KdcOptions kdc_options;
PrincipalName *cname; krb5_principal cname;
Realm realm; krb5_realm realm;
PrincipalName *sname; krb5_principal sname;
time_t till; krb5_time till;
int nonce;
unsigned num_etypes; unsigned num_etypes;
EncryptionType *etypes; krb5_enctype *etypes;
HostAddress *addrs; krb5_addresses addrs;
unsigned num_addrs;
}; };
typedef struct Kdc_Req Kdc_Req; typedef struct Kdc_Req Kdc_Req;
@@ -113,28 +80,13 @@ typedef struct EncryptedData EncryptedData;
struct Ticket { struct Ticket {
int tkt_vno; int tkt_vno;
Realm realm; krb5_realm realm;
PrincipalName sname; krb5_principal sname;
EncryptedData enc_part; EncryptedData enc_part;
}; };
typedef struct Ticket Ticket; typedef struct Ticket Ticket;
struct Kdc_Rep {
int pvno;
int msg_type;
Realm realm;
PrincipalName cname;
Ticket ticket;
EncryptedData enc_part;
};
typedef struct Kdc_Rep Kdc_Rep;
typedef Kdc_Rep As_Rep;
typedef Kdc_Rep Tgs_Rep;
struct EncryptionKey { struct EncryptionKey {
int keytype; int keytype;
krb5_data keyvalue; krb5_data keyvalue;
@@ -146,7 +98,7 @@ struct LastReq {
int number; int number;
struct { struct {
int lr_type; int lr_type;
time_t lr_value; krb5_time lr_value;
} *values; } *values;
}; };
@@ -172,18 +124,33 @@ struct EncKdcRepPart {
EncryptionKey key; EncryptionKey key;
LastReq req; LastReq req;
int nonce; int nonce;
time_t *key_expiration; krb5_time *key_expiration;
TicketFlags flags; TicketFlags flags;
time_t authtime; krb5_time authtime;
time_t *starttime; krb5_time *starttime;
time_t endtime; krb5_time endtime;
time_t *renew_till; krb5_time *renew_till;
Realm srealm; krb5_realm srealm;
PrincipalName sname; krb5_principal sname;
HostAddresses caddr; krb5_addresses caddr;
}; };
typedef struct EncKdcRepPart EncKdcRepPart; typedef struct EncKdcRepPart EncKdcRepPart;
typedef EncKdcRepPart EncASRepPart; typedef EncKdcRepPart EncASRepPart;
typedef EncKdcRepPart EncTGSRepPart; typedef EncKdcRepPart EncTGSRepPart;
struct krb5_kdc_rep {
int pvno;
int msg_type;
krb5_realm realm;
krb5_principal cname;
Ticket ticket;
EncryptedData enc_part;
EncASRepPart enc_part2;
};
typedef krb5_kdc_rep As_Rep;
typedef krb5_kdc_rep Tgs_Rep;

44
kinit.c Normal file
View File

@@ -0,0 +1,44 @@
#include <stdio.h>
#include <krb5.h>
int
main (int argc, char **argv)
{
krb5_error_code err;
krb5_context context;
krb5_ccache ccache;
krb5_principal principal;
krb5_creds cred;
err = krb5_init_context (&context);
if (err)
abort ();
err = krb5_cc_default (context, &ccache);
if (err)
abort ();
err = krb5_parse_name (context, argv[1], &principal);
if (err)
abort ();
err = krb5_cc_initialize (context, ccache, principal);
if (err)
abort ();
cred.client = principal;
cred.times.endtime = time (NULL) + 4711;
err = krb5_get_in_tkt_with_password (context,
0,
NULL,
NULL,
NULL,
NULL,
ccache,
&cred,
NULL);
if (err)
abort ();
return 0;
}

44
krb5.h
View File

@@ -8,6 +8,13 @@
#include "config_file.h" #include "config_file.h"
/* simple constants */
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/* types */ /* types */
typedef int32_t krb5_int32; typedef int32_t krb5_int32;
typedef int16_t krb5_int16; typedef int16_t krb5_int16;
@@ -40,7 +47,7 @@ typedef enum krb5_cksumtype {
CKSUMTYPE_DES_MAC = 4, CKSUMTYPE_DES_MAC = 4,
CKSUMTYPE_DES_MAC_K = 5, CKSUMTYPE_DES_MAC_K = 5,
CKSUMTYPE_RSA_MD4_DES_K = 6, CKSUMTYPE_RSA_MD4_DES_K = 6,
CKSUMTYPE_RSA_MD5_DES = 7, CKSUMTYPE_RSA_MD5_DES = 7
} krb5_cksumtype; } krb5_cksumtype;
@@ -63,7 +70,7 @@ typedef enum krb5_preauthtype {
typedef enum krb5_address_type { typedef enum krb5_address_type {
KRB5_ADDRESS_INET = 2, KRB5_ADDRESS_INET = 2
} krb5_address_type; } krb5_address_type;
typedef struct krb5_address{ typedef struct krb5_address{
@@ -71,7 +78,10 @@ typedef struct krb5_address{
krb5_data address; krb5_data address;
} krb5_address; } krb5_address;
typedef struct krb5_addresses {
int number;
krb5_address *addrs;
} krb5_addresses;
typedef enum krb5_keytype { KEYTYPE_DES } krb5_keytype; typedef enum krb5_keytype { KEYTYPE_DES } krb5_keytype;
@@ -80,7 +90,6 @@ typedef struct krb5_keyblock{
krb5_data contents; krb5_data contents;
} krb5_keyblock; } krb5_keyblock;
typedef struct krb5_context_data{ typedef struct krb5_context_data{
krb5_enctype *etypes; krb5_enctype *etypes;
char *default_realm; char *default_realm;
@@ -107,6 +116,7 @@ enum{
KRB5_NT_SRV_XHST = 4, KRB5_NT_SRV_XHST = 4,
KRB5_NT_UID = 5 KRB5_NT_UID = 5
}; };
typedef struct krb5_principal_data{ typedef struct krb5_principal_data{
int type; int type;
krb5_data realm; krb5_data realm;
@@ -117,6 +127,7 @@ typedef struct krb5_principal_data{
typedef krb5_principal_data *krb5_principal; typedef krb5_principal_data *krb5_principal;
typedef const krb5_principal_data *krb5_const_principal; typedef const krb5_principal_data *krb5_const_principal;
typedef krb5_data krb5_realm;
typedef struct krb5_ticket{ typedef struct krb5_ticket{
int kvno; int kvno;
@@ -198,10 +209,7 @@ typedef struct krb5_auth_context{
typedef krb5_uint32 krb5_flags; typedef krb5_uint32 krb5_flags;
typedef struct krb5_kdc_rep{ typedef struct krb5_kdc_rep krb5_kdc_rep;
int dummy;
}krb5_kdc_rep;
krb5_error_code krb5_error_code
krb5_init_context(krb5_context *context); krb5_init_context(krb5_context *context);
@@ -223,13 +231,13 @@ krb5_get_credentials(krb5_context context,
krb5_creds *out_creds); krb5_creds *out_creds);
typedef krb5_error_code (*krb5_key_proc)(krb5_context context, typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
const krb5_keytype type, krb5_keytype type,
krb5_data *salt, krb5_data *salt,
krb5_const_pointer keyseed, krb5_const_pointer keyseed,
krb5_keyblock **key); krb5_keyblock **key);
typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context, typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context,
const krb5_keyblock *key, const krb5_keyblock *key,
krb5_const_pointer *decrypt_arg, krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep); krb5_kdc_rep *dec_rep);
krb5_error_code krb5_error_code
@@ -246,6 +254,16 @@ krb5_get_in_tkt(krb5_context context,
krb5_ccache ccache, krb5_ccache ccache,
krb5_kdc_rep **ret_as_reply); krb5_kdc_rep **ret_as_reply);
krb5_error_code
krb5_get_in_tkt_with_password (krb5_context context,
krb5_flags options,
krb5_address *const *addrs,
const krb5_enctype *etypes,
const krb5_preauthtype *pre_auth_types,
const char *password,
krb5_ccache ccache,
krb5_creds *creds,
krb5_kdc_rep **ret_as_reply);
krb5_error_code krb5_error_code
krb5_mk_req(krb5_context context, krb5_mk_req(krb5_context context,
@@ -354,5 +372,11 @@ krb5_free_krbhst (krb5_context context,
char *const *hostlist); char *const *hostlist);
/* variables */
extern const char krb5_config_file[];
extern const char krb5_defkeyname[];
#endif /* __KRB5_H__ */ #endif /* __KRB5_H__ */

View File

@@ -49,4 +49,10 @@
#define KRB_ERR_GENERIC 60 #define KRB_ERR_GENERIC 60
#define KRB_ERR_FIELD_TOOLONG 61 #define KRB_ERR_FIELD_TOOLONG 61
#define KRB5_KDC_UNREACH 155
/* Just some random number */
#define ASN1_PARSE_ERROR 274
#endif /* __KRB5_ERROR_H__ */ #endif /* __KRB5_ERROR_H__ */

View File

@@ -7,7 +7,16 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <time.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <des.h> #include <des.h>

View File

@@ -9,11 +9,11 @@ krb5_get_krbhst (krb5_context context,
char buf[BUFSIZ]; char buf[BUFSIZ];
char *val; char *val;
sprintf (buf, "realms %s kdc", realm.data); sprintf (buf, "realms %.*s kdc", realm->length, realm->data);
err = krb5_get_config_tag (context.cf, buf, &val); err = krb5_get_config_tag (context->cf, buf, &val);
if (err) if (err)
return err; return err;
**hostlist = malloc (2 * sizeof (char *)); *hostlist = malloc (2 * sizeof (char *));
(*hostlist)[0] = val; (*hostlist)[0] = val;
(*hostlist)[1] = NULL; (*hostlist)[1] = NULL;
return 0; return 0;

44
kuser/kinit.c Normal file
View File

@@ -0,0 +1,44 @@
#include <stdio.h>
#include <krb5.h>
int
main (int argc, char **argv)
{
krb5_error_code err;
krb5_context context;
krb5_ccache ccache;
krb5_principal principal;
krb5_creds cred;
err = krb5_init_context (&context);
if (err)
abort ();
err = krb5_cc_default (context, &ccache);
if (err)
abort ();
err = krb5_parse_name (context, argv[1], &principal);
if (err)
abort ();
err = krb5_cc_initialize (context, ccache, principal);
if (err)
abort ();
cred.client = principal;
cred.times.endtime = time (NULL) + 4711;
err = krb5_get_in_tkt_with_password (context,
0,
NULL,
NULL,
NULL,
NULL,
ccache,
&cred,
NULL);
if (err)
abort ();
return 0;
}

View File

@@ -46,6 +46,10 @@ krb5_error_code
krb5_cc_default(krb5_context context, krb5_cc_default(krb5_context context,
krb5_ccache *id) krb5_ccache *id)
{ {
*id = malloc(sizeof(**id));
if (*id == NULL)
return ENOMEM;
return krb5_cc_resolve (context, id, "/tmp/foo");
} }
static krb5_error_code static krb5_error_code
@@ -112,7 +116,7 @@ krb5_cc_initialize(krb5_context context,
if(ret = erase_file(f->filename)) if(ret = erase_file(f->filename))
return ret; return ret;
fd = open(f->filename, O_RDWR, 0600); fd = open(f->filename, O_RDWR | O_CREAT | O_EXCL, 0600);
if(fd == -1) if(fd == -1)
return errno; return errno;
store_int16(fd, 0x503); store_int16(fd, 0x503);

View File

@@ -19,6 +19,9 @@ static krb5_config_relation **crel;
static krb5_config_relation **rels[16]; static krb5_config_relation **rels[16];
static int relp; static int relp;
static void yyerror (char *);
static int yylex (void);
%} %}
%union { %union {
@@ -143,7 +146,7 @@ static int yylex(void)
return type; return type;
} }
static void yyerror(char *s) void yyerror(char *s)
{ {
printf("yyerror: %s\n", s); printf("yyerror: %s\n", s);
} }

45
lib/krb5/get_addrs.c Normal file
View File

@@ -0,0 +1,45 @@
#include "krb5_locl.h"
static krb5_error_code
get_addrs ()
{
/* here the code from krb4/lib/krb/getaddrs.c will go */
}
/*
* Try to get all addresses, but return the one corresponding to
* `hostname' if we fail.
*/
krb5_error_code
krb5_get_all_client_addrs (krb5_addresses *res)
{
krb5_error_code err;
char hostname[MAXHOSTNAMELEN];
struct hostent *hostent;
if (gethostname (hostname, sizeof(hostname)))
return errno;
hostent = gethostbyname (hostname);
if (hostent == NULL)
return errno;
res->number = 1;
res->addrs = malloc (sizeof(*res->addrs));
res->addrs[0].type = hostent->h_addrtype;
err = krb5_data_alloc (&res->addrs[0].address, hostent->h_length);
if (err)
return err;
memcpy (res->addrs[0].address.data,
hostent->h_addr,
hostent->h_length);
return 0;
}
/*
* Same as above, but with the fall-back to INADDR_ANY.
*/
krb5_error_code
krb5_get_all_server_addrs ()
{
}

View File

@@ -1,4 +1,7 @@
#include "krb5_locl.h" #include "krb5_locl.h"
#include <krb5_error.h>
#include <d.h>
#include <k5_der.h>
static krb5_error_code static krb5_error_code
krb5_get_salt (krb5_principal princ, krb5_get_salt (krb5_principal princ,
@@ -10,22 +13,52 @@ krb5_get_salt (krb5_principal princ,
krb5_error_code err; krb5_error_code err;
char *p; char *p;
len = realm->len; len = realm.length;
for (i = 0; i < princ->ncomp; ++i) for (i = 0; i < princ->ncomp; ++i)
len += princ->comp[i].length; len += princ->comp[i].length;
err = krb5_alloc (salt, len); err = krb5_data_alloc (salt, len);
if (err) if (err)
return err; return err;
p = salt->data; p = salt->data;
strncpy (p, realm->data, realm->len); strncpy (p, realm.data, realm.length);
p += realm->len; p += realm.length;
for (i = 0; i < princ->cnomp; ++i) { for (i = 0; i < princ->ncomp; ++i) {
strncpy (p, princ->comp[i].data, princ->comp[i].length); strncpy (p, princ->comp[i].data, princ->comp[i].length);
p += princ->comp[i].length; p += princ->comp[i].length;
} }
return 0; return 0;
} }
static krb5_error_code
decrypt_tkt (krb5_context context,
const krb5_keyblock *key,
krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep)
{
des_key_schedule sched;
char *buf;
Buffer buffer;
des_set_key (key->contents.data, sched);
buf = malloc (dec_rep->enc_part.cipher.length);
if (buf == NULL)
return ENOMEM;
des_cbc_encrypt ((des_cblock *)dec_rep->enc_part.cipher.data,
(des_cblock *)buf,
dec_rep->enc_part.cipher.length,
sched,
key->contents.data,
DES_DECRYPT);
/* XXX: Check CRC */
buf_init (&buffer, buf + 12, dec_rep->enc_part.cipher.length - 12);
if (der_get_enctgsreppart (&buffer, &dec_rep->enc_part2) == -1) {
free (buf);
return ASN1_PARSE_ERROR;
}
free (buf);
return 0;
}
/* /*
* *
*/ */
@@ -44,65 +77,82 @@ krb5_get_in_tkt(krb5_context context,
krb5_ccache ccache, krb5_ccache ccache,
krb5_kdc_rep **ret_as_reply) krb5_kdc_rep **ret_as_reply)
{ {
krb5_error_code err;
As_Req a; As_Req a;
Kdc_Rep rep; krb5_kdc_rep rep;
krb5_principal server; krb5_principal_data server;
krb5_data req, resp; krb5_data req, resp;
char buf[BUFSIZ]; char buf[BUFSIZ];
Buffer buf; Buffer buffer;
krb5_data salt; krb5_data salt;
krb5_keyblock *key; krb5_keyblock *key;
server.type = KRB_NT_SRV_INST; server.type = KRB5_NT_SRV_INST;
server.ncomp = 2; server.ncomp = 2;
server.comp = malloc (sizeof(*server.comp) * server.ncomp); server.comp = malloc (sizeof(*server.comp) * server.ncomp);
server.comp[0] = string_make ("krbtgt"); server.comp[0] = string_make ("krbtgt");
server.comp[1] = creds->client.realm; server.comp[1] = creds->client->realm;
a.pvno = 5; a.pvno = 5;
a.msg_type = KRB_AS_REQ; a.msg_type = KRB_AS_REQ;
/* a.kdc_options */ /* a.kdc_options */
a.cname = &creds->client; a.cname = creds->client;
a.sname = &server; a.sname = &server;
a.realm = creds->client.realm; a.realm = creds->client->realm;
a.till = creds->times.endtime; a.till = creds->times.endtime;
a.nonce = 17; a.nonce = 17;
if (etypes) if (etypes)
a.etypes = etypes; a.etypes = etypes;
else else {
a.etypes = context->etypes; err = krb5_get_default_in_tkt_etypes (context, &a.etypes);
if (addrs) if (err)
a.addresses = addrs; return err;
else a.num_etypes = 1;
a.addresses = krb5_get_all_client_addrs (); }
if (addrs){
} else {
err = krb5_get_all_client_addrs (&a.addrs);
if (err)
return err;
}
req.data = buf; req.length = der_put_as_req (buf + sizeof(buf) - 1, &a);
req.data = buf + sizeof(buf) - req.length;
req.len = der_put_as_req (req.data + sizeof(buf) - 1, &a);
string_free (server.comp[0]);
free (server.comp); free (server.comp);
if (addrs == NULL) if (addrs == NULL) {
free (a.addresses); int i;
err = krb5_sendto_kdc (context, &req, a.realm, &resp); for (i = 0; i < a.addrs.number; ++i)
krb5_data_free (&a.addrs.addrs[i].address);
free (a.addrs.addrs);
}
err = krb5_sendto_kdc (context, &req, &a.realm, &resp);
if (err) { if (err) {
return err; return err;
} }
buf_init (&buffer, resp.data, resp.len); buf_init (&buffer, resp.data, resp.length);
if (der_get_as_rep (&buffer, &rep) == -1) { if (der_get_as_rep (&buffer, &rep) == -1) {
return ASN1_PARSE_ERROR; return ASN1_PARSE_ERROR;
} }
err = krb5_get_salt (creds->client, creds->client.realm, &salt); salt.length = 0;
salt.data = NULL;
err = krb5_get_salt (creds->client, creds->client->realm, &salt);
if (err) if (err)
return err; return err;
err = (*key_proc)(context, b.enc_part.etype, salt, keyseed, &key); err = (*key_proc)(context, rep.enc_part.etype, &salt, keyseed, &key);
krb5_data_free (&salt); krb5_data_free (&salt);
if (err) if (err)
return err; return err;
if (decrypt_proc == NULL)
decrypt_proc = decrypt_tkt;
err = (*decrypt_proc)(context, key, decryptarg, &rep); err = (*decrypt_proc)(context, key, decryptarg, &rep);
memset (&key.contents.data, 0, key.contents.length); memset (key->contents.data, 0, key->contents.length);
krb5_data_free (&key.contents); krb5_data_free (&key->contents);
free (key);
if (err) if (err)
return err; return err;
return 0;
} }

View File

@@ -11,15 +11,17 @@ key_proc (krb5_context context,
char *password = (char *)keyseed; char *password = (char *)keyseed;
char buf[BUFSIZ]; char buf[BUFSIZ];
key = malloc (sizeof (*key)); *key = malloc (sizeof (**key));
if (key == NULL) if (*key == NULL)
return ENOMEM; return ENOMEM;
key->keytype = type; (*key)->keytype = type;
(*key)->contents.length = 0;
(*key)->contents.data = NULL;
if (password == NULL) { if (password == NULL) {
des_read_pw_string (buf, sizeof(buf), "Password: ", 0); des_read_pw_string (buf, sizeof(buf), "Password: ", 0);
password = buf; password = buf;
} }
err = krb5_string_to_key (password, salt, key); err = krb5_string_to_key (password, salt, *key);
memset (buf, 0, sizeof(buf)); memset (buf, 0, sizeof(buf));
return err; return err;
} }
@@ -33,9 +35,9 @@ krb5_get_in_tkt_with_password (krb5_context context,
const char *password, const char *password,
krb5_ccache ccache, krb5_ccache ccache,
krb5_creds *creds, krb5_creds *creds,
krb5_kdc-rep **ret_as_reply) krb5_kdc_rep **ret_as_reply)
{ {
return krb5_get_in_tkt (context, options, addrs, etypes, return krb5_get_in_tkt (context, options, addrs, etypes,
pre_auth_types, key_proc, password, pre_auth_types, key_proc, password,
NULL, NULL, creds, cache, ret_as_reply); NULL, NULL, creds, ccache, ret_as_reply);
} }

View File

@@ -8,6 +8,13 @@
#include "config_file.h" #include "config_file.h"
/* simple constants */
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/* types */ /* types */
typedef int32_t krb5_int32; typedef int32_t krb5_int32;
typedef int16_t krb5_int16; typedef int16_t krb5_int16;
@@ -40,7 +47,7 @@ typedef enum krb5_cksumtype {
CKSUMTYPE_DES_MAC = 4, CKSUMTYPE_DES_MAC = 4,
CKSUMTYPE_DES_MAC_K = 5, CKSUMTYPE_DES_MAC_K = 5,
CKSUMTYPE_RSA_MD4_DES_K = 6, CKSUMTYPE_RSA_MD4_DES_K = 6,
CKSUMTYPE_RSA_MD5_DES = 7, CKSUMTYPE_RSA_MD5_DES = 7
} krb5_cksumtype; } krb5_cksumtype;
@@ -63,7 +70,7 @@ typedef enum krb5_preauthtype {
typedef enum krb5_address_type { typedef enum krb5_address_type {
KRB5_ADDRESS_INET = 2, KRB5_ADDRESS_INET = 2
} krb5_address_type; } krb5_address_type;
typedef struct krb5_address{ typedef struct krb5_address{
@@ -71,7 +78,10 @@ typedef struct krb5_address{
krb5_data address; krb5_data address;
} krb5_address; } krb5_address;
typedef struct krb5_addresses {
int number;
krb5_address *addrs;
} krb5_addresses;
typedef enum krb5_keytype { KEYTYPE_DES } krb5_keytype; typedef enum krb5_keytype { KEYTYPE_DES } krb5_keytype;
@@ -80,7 +90,6 @@ typedef struct krb5_keyblock{
krb5_data contents; krb5_data contents;
} krb5_keyblock; } krb5_keyblock;
typedef struct krb5_context_data{ typedef struct krb5_context_data{
krb5_enctype *etypes; krb5_enctype *etypes;
char *default_realm; char *default_realm;
@@ -107,6 +116,7 @@ enum{
KRB5_NT_SRV_XHST = 4, KRB5_NT_SRV_XHST = 4,
KRB5_NT_UID = 5 KRB5_NT_UID = 5
}; };
typedef struct krb5_principal_data{ typedef struct krb5_principal_data{
int type; int type;
krb5_data realm; krb5_data realm;
@@ -117,6 +127,7 @@ typedef struct krb5_principal_data{
typedef krb5_principal_data *krb5_principal; typedef krb5_principal_data *krb5_principal;
typedef const krb5_principal_data *krb5_const_principal; typedef const krb5_principal_data *krb5_const_principal;
typedef krb5_data krb5_realm;
typedef struct krb5_ticket{ typedef struct krb5_ticket{
int kvno; int kvno;
@@ -198,10 +209,7 @@ typedef struct krb5_auth_context{
typedef krb5_uint32 krb5_flags; typedef krb5_uint32 krb5_flags;
typedef struct krb5_kdc_rep{ typedef struct krb5_kdc_rep krb5_kdc_rep;
int dummy;
}krb5_kdc_rep;
krb5_error_code krb5_error_code
krb5_init_context(krb5_context *context); krb5_init_context(krb5_context *context);
@@ -223,13 +231,13 @@ krb5_get_credentials(krb5_context context,
krb5_creds *out_creds); krb5_creds *out_creds);
typedef krb5_error_code (*krb5_key_proc)(krb5_context context, typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
const krb5_keytype type, krb5_keytype type,
krb5_data *salt, krb5_data *salt,
krb5_const_pointer keyseed, krb5_const_pointer keyseed,
krb5_keyblock **key); krb5_keyblock **key);
typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context, typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context,
const krb5_keyblock *key, const krb5_keyblock *key,
krb5_const_pointer *decrypt_arg, krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep); krb5_kdc_rep *dec_rep);
krb5_error_code krb5_error_code
@@ -246,6 +254,16 @@ krb5_get_in_tkt(krb5_context context,
krb5_ccache ccache, krb5_ccache ccache,
krb5_kdc_rep **ret_as_reply); krb5_kdc_rep **ret_as_reply);
krb5_error_code
krb5_get_in_tkt_with_password (krb5_context context,
krb5_flags options,
krb5_address *const *addrs,
const krb5_enctype *etypes,
const krb5_preauthtype *pre_auth_types,
const char *password,
krb5_ccache ccache,
krb5_creds *creds,
krb5_kdc_rep **ret_as_reply);
krb5_error_code krb5_error_code
krb5_mk_req(krb5_context context, krb5_mk_req(krb5_context context,
@@ -354,5 +372,11 @@ krb5_free_krbhst (krb5_context context,
char *const *hostlist); char *const *hostlist);
/* variables */
extern const char krb5_config_file[];
extern const char krb5_defkeyname[];
#endif /* __KRB5_H__ */ #endif /* __KRB5_H__ */

View File

@@ -49,4 +49,10 @@
#define KRB_ERR_GENERIC 60 #define KRB_ERR_GENERIC 60
#define KRB_ERR_FIELD_TOOLONG 61 #define KRB_ERR_FIELD_TOOLONG 61
#define KRB5_KDC_UNREACH 155
/* Just some random number */
#define ASN1_PARSE_ERROR 274
#endif /* __KRB5_ERROR_H__ */ #endif /* __KRB5_ERROR_H__ */

View File

@@ -7,7 +7,16 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <time.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <des.h> #include <des.h>

View File

@@ -9,11 +9,11 @@ krb5_get_krbhst (krb5_context context,
char buf[BUFSIZ]; char buf[BUFSIZ];
char *val; char *val;
sprintf (buf, "realms %s kdc", realm.data); sprintf (buf, "realms %.*s kdc", realm->length, realm->data);
err = krb5_get_config_tag (context.cf, buf, &val); err = krb5_get_config_tag (context->cf, buf, &val);
if (err) if (err)
return err; return err;
**hostlist = malloc (2 * sizeof (char *)); *hostlist = malloc (2 * sizeof (char *));
(*hostlist)[0] = val; (*hostlist)[0] = val;
(*hostlist)[1] = NULL; (*hostlist)[1] = NULL;
return 0; return 0;

View File

@@ -1,17 +1,18 @@
#include "krb5_locl.h" #include "krb5_locl.h"
#include "krb5_error.h"
static int static int
send_and_recv (int fd, send_and_recv (int fd,
struct sockaddr_in *addr, struct sockaddr_in *addr,
krb5_data *send, const krb5_data *send,
krb5_data *recv) krb5_data *recv)
{ {
struct fdset fdset; struct fd_set fdset;
struct timeval timeout; struct timeval timeout;
int ret; int ret;
long nbytes; long nbytes;
if (sendto (fd, send->data, send->len, 0, if (sendto (fd, send->data, send->length, 0,
(struct sockaddr *)addr, sizeof(*addr)) < 0) (struct sockaddr *)addr, sizeof(*addr)) < 0)
return -1; return -1;
FD_ZERO(&fdset); FD_ZERO(&fdset);
@@ -22,24 +23,25 @@ send_and_recv (int fd,
if (ret <= 0) if (ret <= 0)
return -1; return -1;
else { else {
ioctl (fd, FIONREAD, &nbytes); int len;
nbytes -= sizeof(struct udphdr) + sizeof(struct iphdr); if (ioctl (fd, FIONREAD, &nbytes) < 0)
return -1;
recv->data = malloc (nbytes); recv->data = malloc (nbytes);
ret = recvfrom (fd, recv->data, nbytes, 0, NULL, 0); ret = recvfrom (fd, recv->data, nbytes, 0, NULL, &len);
if (ret < 0) { if (ret < 0) {
free (recv->data); free (recv->data);
return -1; return -1;
} }
recv->data = realloc (recv->data, ret); recv->data = realloc (recv->data, ret);
recv->len = ret; recv->length = ret;
return 0; return 0;
} }
} }
krb5_error_code krb5_error_code
krb5_sentdo_kdc (krb5_context context, krb5_sendto_kdc (krb5_context context,
const krb5_data *send, const krb5_data *send,
const krb5_data *realm, const krb5_data *realm,
krb5_data *receive) krb5_data *receive)
@@ -51,35 +53,52 @@ krb5_sentdo_kdc (krb5_context context,
int port; int port;
int i; int i;
port = krb5_getportbyname ("kerberos", "udp", htons(750)); port = krb5_getportbyname ("kerberos", "udp", htons(88));
fd = socket (AF_INET, SOCK_DGRAM, 0); fd = socket (AF_INET, SOCK_DGRAM, 0);
if (fd < 0) if (fd < 0) {
krb5_free_krbhst (context, hostlist);
return errno; return errno;
}
err = krb5_get_krbhst (context, realm, &hostlist); err = krb5_get_krbhst (context, realm, &hostlist);
if (err) { if (err) {
close (fd); close (fd);
return err; return err;
} }
for (i = 0; i < 3; ++i) for (i = 0; i < 3; ++i)
for (hp = hostlist; p = *hp; ++hp) { for (hp = hostlist; p = *hp; ++hp) {
char *addr; char *addr;
char *colon;
colon = strchr (p, ':');
if (colon)
*colon = '\0';
hostent = gethostbyname (p); hostent = gethostbyname (p);
if (colon)
*colon++ = ':';
while (addr = *hostent->h_addr_list++) { while (addr = *hostent->h_addr_list++) {
struct sockaddr_in a; struct sockaddr_in a;
memset (a, 0, sizeof(a)); memset (&a, 0, sizeof(a));
a.sin_family = AF_INET; a.sin_family = AF_INET;
a.sin_port = port; if (colon) {
int tmp;
sscanf (colon, "%d", &tmp);
a.sin_port = htons(tmp);
} else
a.sin_port = port;
a.sin_addr = *((struct in_addr *)addr); a.sin_addr = *((struct in_addr *)addr);
if (send_and_recv (fd, &a, send, recv) == 0) { if (send_and_recv (fd, &a, send, receive) == 0) {
close (fd);
krb5_free_krbhst (context, hostlist); krb5_free_krbhst (context, hostlist);
return KDC_ERR_NONE; return 0;
} }
} }
} }
close (fd);
krb5_free_krbhst (context, hostlist); krb5_free_krbhst (context, hostlist);
return KRB5_KDC_UNREACH; return KRB5_KDC_UNREACH;
} }

View File

@@ -86,7 +86,7 @@ init (unsigned char *a, unsigned char *b)
a[7] = b[7] << 1; a[7] = b[7] << 1;
} }
void krb5_error_code
krb5_string_to_key (char *str, krb5_string_to_key (char *str,
krb5_data *salt, krb5_data *salt,
krb5_keyblock *key) krb5_keyblock *key)
@@ -98,7 +98,7 @@ krb5_string_to_key (char *str,
des_key_schedule sched; des_key_schedule sched;
krb5_error_code err; krb5_error_code err;
len = strlen(str) + salt->len; len = strlen(str) + salt->length;
#if 1 #if 1
len = (len + 7) / 8 * 8; len = (len + 7) / 8 * 8;
#endif #endif
@@ -113,7 +113,7 @@ krb5_string_to_key (char *str,
memset (s, 0, len); memset (s, 0, len);
strncpy (p, str, strlen(str)); strncpy (p, str, strlen(str));
p += strlen(str); p += strlen(str);
strncpy (p, salt->data, salt->len); strncpy (p, salt->data, salt->length);
odd = 1; odd = 1;
memset (tempkey, 0, sizeof(tempkey)); memset (tempkey, 0, sizeof(tempkey));
for (i = 0; i < len; i += 8) { for (i = 0; i < len; i += 8) {

View File

@@ -1,17 +1,18 @@
#include "krb5_locl.h" #include "krb5_locl.h"
#include "krb5_error.h"
static int static int
send_and_recv (int fd, send_and_recv (int fd,
struct sockaddr_in *addr, struct sockaddr_in *addr,
krb5_data *send, const krb5_data *send,
krb5_data *recv) krb5_data *recv)
{ {
struct fdset fdset; struct fd_set fdset;
struct timeval timeout; struct timeval timeout;
int ret; int ret;
long nbytes; long nbytes;
if (sendto (fd, send->data, send->len, 0, if (sendto (fd, send->data, send->length, 0,
(struct sockaddr *)addr, sizeof(*addr)) < 0) (struct sockaddr *)addr, sizeof(*addr)) < 0)
return -1; return -1;
FD_ZERO(&fdset); FD_ZERO(&fdset);
@@ -22,24 +23,25 @@ send_and_recv (int fd,
if (ret <= 0) if (ret <= 0)
return -1; return -1;
else { else {
ioctl (fd, FIONREAD, &nbytes); int len;
nbytes -= sizeof(struct udphdr) + sizeof(struct iphdr); if (ioctl (fd, FIONREAD, &nbytes) < 0)
return -1;
recv->data = malloc (nbytes); recv->data = malloc (nbytes);
ret = recvfrom (fd, recv->data, nbytes, 0, NULL, 0); ret = recvfrom (fd, recv->data, nbytes, 0, NULL, &len);
if (ret < 0) { if (ret < 0) {
free (recv->data); free (recv->data);
return -1; return -1;
} }
recv->data = realloc (recv->data, ret); recv->data = realloc (recv->data, ret);
recv->len = ret; recv->length = ret;
return 0; return 0;
} }
} }
krb5_error_code krb5_error_code
krb5_sentdo_kdc (krb5_context context, krb5_sendto_kdc (krb5_context context,
const krb5_data *send, const krb5_data *send,
const krb5_data *realm, const krb5_data *realm,
krb5_data *receive) krb5_data *receive)
@@ -51,35 +53,52 @@ krb5_sentdo_kdc (krb5_context context,
int port; int port;
int i; int i;
port = krb5_getportbyname ("kerberos", "udp", htons(750)); port = krb5_getportbyname ("kerberos", "udp", htons(88));
fd = socket (AF_INET, SOCK_DGRAM, 0); fd = socket (AF_INET, SOCK_DGRAM, 0);
if (fd < 0) if (fd < 0) {
krb5_free_krbhst (context, hostlist);
return errno; return errno;
}
err = krb5_get_krbhst (context, realm, &hostlist); err = krb5_get_krbhst (context, realm, &hostlist);
if (err) { if (err) {
close (fd); close (fd);
return err; return err;
} }
for (i = 0; i < 3; ++i) for (i = 0; i < 3; ++i)
for (hp = hostlist; p = *hp; ++hp) { for (hp = hostlist; p = *hp; ++hp) {
char *addr; char *addr;
char *colon;
colon = strchr (p, ':');
if (colon)
*colon = '\0';
hostent = gethostbyname (p); hostent = gethostbyname (p);
if (colon)
*colon++ = ':';
while (addr = *hostent->h_addr_list++) { while (addr = *hostent->h_addr_list++) {
struct sockaddr_in a; struct sockaddr_in a;
memset (a, 0, sizeof(a)); memset (&a, 0, sizeof(a));
a.sin_family = AF_INET; a.sin_family = AF_INET;
a.sin_port = port; if (colon) {
int tmp;
sscanf (colon, "%d", &tmp);
a.sin_port = htons(tmp);
} else
a.sin_port = port;
a.sin_addr = *((struct in_addr *)addr); a.sin_addr = *((struct in_addr *)addr);
if (send_and_recv (fd, &a, send, recv) == 0) { if (send_and_recv (fd, &a, send, receive) == 0) {
close (fd);
krb5_free_krbhst (context, hostlist); krb5_free_krbhst (context, hostlist);
return KDC_ERR_NONE; return 0;
} }
} }
} }
close (fd);
krb5_free_krbhst (context, hostlist); krb5_free_krbhst (context, hostlist);
return KRB5_KDC_UNREACH; return KRB5_KDC_UNREACH;
} }

View File

@@ -86,7 +86,7 @@ init (unsigned char *a, unsigned char *b)
a[7] = b[7] << 1; a[7] = b[7] << 1;
} }
void krb5_error_code
krb5_string_to_key (char *str, krb5_string_to_key (char *str,
krb5_data *salt, krb5_data *salt,
krb5_keyblock *key) krb5_keyblock *key)
@@ -98,7 +98,7 @@ krb5_string_to_key (char *str,
des_key_schedule sched; des_key_schedule sched;
krb5_error_code err; krb5_error_code err;
len = strlen(str) + salt->len; len = strlen(str) + salt->length;
#if 1 #if 1
len = (len + 7) / 8 * 8; len = (len + 7) / 8 * 8;
#endif #endif
@@ -113,7 +113,7 @@ krb5_string_to_key (char *str,
memset (s, 0, len); memset (s, 0, len);
strncpy (p, str, strlen(str)); strncpy (p, str, strlen(str));
p += strlen(str); p += strlen(str);
strncpy (p, salt->data, salt->len); strncpy (p, salt->data, salt->length);
odd = 1; odd = 1;
memset (tempkey, 0, sizeof(tempkey)); memset (tempkey, 0, sizeof(tempkey));
for (i = 0; i < len; i += 8) { for (i = 0; i < len; i += 8) {