Now uses generated ASN1-code.

kinit should be able to get a initial message from FOO.SE.


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@844 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1996-10-13 21:13:38 +00:00
parent 10f3cd6dbf
commit b55aed018f
43 changed files with 19385 additions and 157 deletions

65
lib/asn1/Makefile.in Normal file
View File

@@ -0,0 +1,65 @@
# $Id$
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
YACC = @YACC@
LEX = @LEX@
YFLAGS = -d
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
DEFS = @DEFS@
SHELL = /bin/sh
CFLAGS = -g
REALCFLAGS = $(CFLAGS) $(DEFS) -I$(srcdir) -I. -I..
FOO_SRCS = parse.y lex.l main.c hash.c symbol.c gen.c
FOO_OBJS = parse.o lex.o main.o hash.o symbol.o gen.o
FOO_HDRS = lex.h parse.h hash.h symbol.h gen.h
PROG = foo
ASN1_SRCS = der_get.c der_put.c
ASN1_OBJS = der_get.o der_put.o foo.o
ASN1_HDRS =
.c.o:
$(CC) -c $(CPPFLAGS) $(REALCFLAGS) $<
.l.c:
$(LEX) $(LFLAGS) -t $< >$@
all: foo libasn1.a
install:
echo "No installation yet"
foo: $(FOO_OBJS)
$(CC) $(LDFLAGS) -o $@ $(FOO_OBJS) $(LIBS)
libasn1.a: $(ASN1_OBJS)
ar cr $@ $(ASN1_OBJS)
foo.c foo.h: k5.asn1
./foo $(srcdir)/k5.asn1
parse.h: parse.c
mv y.tab.h parse.h
lex.o: parse.h
clean :
rm -f $(OBJS) $(PROG) lex.c parse.c parse.h *~ *.o core
mostlyclean: clean
distclean: clean
realclean: distclean
.PHONY: all install tags clean distclean realclean

41
lib/asn1/der.h Normal file
View File

@@ -0,0 +1,41 @@
/* $Id$ */
#ifndef DER_H
#define DER_H
typedef enum {UNIV = 0, APPL = 1, CONTEXT = 2 , PRIVATE = 3} Der_class;
typedef enum {PRIM = 0, CONS = 1} Der_type;
/* Universal tags */
enum {
UT_Integer = 2,
UT_BitString = 3,
UT_OctetString = 4,
UT_Null = 5,
UT_ObjID = 6,
UT_Sequence = 16,
UT_Set = 17,
UT_PrintableString = 19,
UT_IA5String = 22,
UT_UTCTime = 23,
UT_GeneralizedTime = 24,
UT_GeneralString = 27,
};
/**/
struct krb5_data {
unsigned len;
unsigned char *data;
};
typedef struct krb5_data krb5_data;
krb5_data string_make (char *);
krb5_data string_make_n (int len, char *);
void string_free (krb5_data);
#endif /* DER_H */

239
lib/asn1/der_get.c Normal file
View File

@@ -0,0 +1,239 @@
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <time.h>
#include "der.h"
/*
* All decoding functions take a pointer `p' to first position in
* which to read, from the left, `len' which means the maximum
* number of characters we are able to read and return an int
* indicating how many actually got read, or <0 in case of errors.
*/
int
der_get_int (unsigned char *p, int len, int *ret)
{
int val = 0;
int oldlen = len;
while (len--)
val = val * 256 + *p++;
*ret = val;
return oldlen;
}
int
der_get_length (unsigned char *p, int len, int *ret)
{
int val;
if (--len < 0)
return -1;
val = *p++;
if (val < 128) {
*ret = val;
return 1;
} else {
int l;
val &= 0x7F;
if (len < val)
return -1;
l = der_get_int (p, val, ret);
if (l < 0)
return l;
else
return l+1;
}
}
int
der_get_general_string (unsigned char *p, int len, char **str)
{
int l, slen;
char *s;
l = der_get_length (p, len, &slen);
if (l < 0)
return l;
p += l;
len -= l;
if (len < slen)
return -1;
s = malloc (slen + 1);
if (s == NULL)
return -1;
memcpy (s, p, slen);
s[slen] = '\0';
*str = s;
return slen + l;
}
int
der_get_octet_string (unsigned char *p, int len, krb5_data *data)
{
int l, slen;
l = der_get_length (p, len, &slen);
if (l < 0)
return l;
p += l;
len -= l;
if (len < slen)
return -1;
data->len = slen;
data->data = malloc(slen);
if (data->data == NULL)
return -1;
memcpy (data->data, p, slen);
return slen + l;
}
int
der_get_tag (unsigned char *p, int len, Der_class *class, Der_type *type,
int *tag)
{
if (len < 1)
return -1;
*class = ((*p) >> 6) & 0x03;
*type = ((*p) >> 5) & 0x01;
*tag = (*p) & 0x1F;
return 1;
}
int
der_match_tag (unsigned char *p, int len, Der_class class, Der_type type,
int tag)
{
int l;
Der_class thisclass;
Der_type thistype;
int thistag;
l = der_get_tag (p, len, &thisclass, &thistype, &thistag);
if (l < 0)
return l;
if (class == thisclass && type == thistype && tag == thistag)
return l;
else
return -1;
}
int
decode_integer (unsigned char *p, int len, void *data)
{
int *num = (int *)data;
int ret = 0;
int l, reallen;
l = der_match_tag (p, len, UNIV, PRIM, UT_Integer);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_length (p, len, &reallen);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_int (p, reallen, num);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
return ret;
}
int
decode_general_string (unsigned char *p, int len, void *data)
{
char **str = (char **)data;
int ret = 0;
int l;
l = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_general_string (p, len, str);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
return ret;
}
int
decode_octet_string (unsigned char *p, int len, void *data)
{
krb5_data *k = (krb5_data *)data;
int ret = 0;
int l;
l = der_match_tag (p, len, UNIV, PRIM, UT_OctetString);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_octet_string (p, len, k);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
return ret;
}
static void
generalizedtime2time (char *s, time_t *t)
{
struct tm tm;
sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
&tm.tm_min, &tm.tm_sec);
tm.tm_year -= 1900;
tm.tm_mon -= 1;
tm.tm_isdst = 0;
*t = mktime(&tm);
#if 0 /* XXX */
*t -= timezone;
#endif
}
int
decode_generalized_time (unsigned char *p, int len, void *data)
{
time_t *t = (time_t *)data;
krb5_data k;
int ret = 0;
int l;
l = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_octet_string (p, len, &k);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
generalizedtime2time (k.data, t);
free (k.data);
return ret;
}

213
lib/asn1/der_put.c Normal file
View File

@@ -0,0 +1,213 @@
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <time.h>
#include "der.h"
/*
* All encoding functions take a pointer `p' to first position in
* which to write, from the right, `len' which means the maximum
* number of characters we are able to write and return an int
* indicating how many actually got written, or <0 in case of errors.
*/
int
der_put_int (unsigned char *p, int len, int val)
{
unsigned char *base = p;
if (val) {
while (len > 0 && val) {
*p-- = val % 256;
val /= 256;
--len;
}
if (val)
return -1;
else
return base - p;
} else if (len < 1)
return -1;
else {
*p = 0;
return 1;
}
}
int
der_put_length (unsigned char *p, int len, int val)
{
if (val < 128) {
if (len < 1)
return -1;
else {
*p = val;
return 1;
}
} else {
int l;
l = der_put_int (p, len - 1,val);
if (l < 0)
return l;
p -= l;
*p = 0x80 | l;
return l + 1;
}
}
int
der_put_general_string (unsigned char *p, int len, char *str)
{
int slen = strlen(str);
int l;
if (len < slen)
return -1;
p -= slen;
len -= slen;
memcpy (p+1, str, slen);
l = der_put_length (p, len, slen);
if(l < 0)
return l;
return slen + l;
}
int
der_put_octet_string (unsigned char *p, int len, krb5_data *data)
{
int l;
if (len < data->len)
return -1;
p -= data->len;
len -= data->len;
memcpy (p+1, data->data, data->len);
l = der_put_length (p, len, data->len);
if (l < 0)
return l;
return l + data->len;
}
int
der_put_tag (unsigned char *p, int len, Der_class class, Der_type type,
int tag)
{
if (len < 1)
return -1;
*p = (class << 6) | (type << 5) | tag; /* XXX */
return 1;
}
int
encode_integer (unsigned char *p, int len, void *data)
{
int num = *((int *)data);
int ret = 0;
int l;
l = der_put_int (p, len, num);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_length (p, len, l);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, UNIV, PRIM, UT_Integer);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
}
int
encode_general_string (unsigned char *p, int len, void *data)
{
char *str = *((char **)data);
int ret = 0;
int l;
l = der_put_general_string (p, len, str);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, UNIV, PRIM, UT_GeneralString);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
}
int
encode_octet_string (unsigned char *p, int len, void *data)
{
krb5_data *k = (krb5_data *)data;
int ret = 0;
int l;
l = der_put_octet_string (p, len, k);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, UNIV, PRIM, UT_OctetString);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
}
static void
time2generalizedtime (time_t t, krb5_data *s)
{
struct tm *tm;
s->data = malloc(16);
s->len = 15;
tm = gmtime (&t);
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_sec);
}
int
encode_generalized_time (unsigned char *p, int len, void *data)
{
time_t *t = (time_t *)data;
krb5_data k;
int l;
int ret = 0;
time2generalizedtime (*t, &k);
l = der_put_octet_string (p, len, &k);
free (k.data);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, UNIV, PRIM, UT_GeneralizedTime);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
}

535
lib/asn1/gen.c Normal file
View File

@@ -0,0 +1,535 @@
/* $Id$ */
#include <stdio.h>
#include <stdlib.h>
#include "der.h"
#include "gen.h"
FILE *headerfile, *codefile;
void
init_generate (char *filename)
{
headerfile = fopen ("foo.h", "w");
fprintf (headerfile,
"/* Genereated from %s */\n"
"/* Do not edit */\n\n",
filename);
codefile = fopen ("foo.c", "w");
fprintf (codefile,
"/* Generated from %s */\n"
"/* Do not edit */\n\n"
"#include <stdlib.h>\n"
"#include <time.h>\n"
"#include <der.h>\n"
"#include <foo.h>\n\n",
filename);
}
void
close_generate ()
{
fclose (headerfile);
fclose (codefile);
}
void
generate_constant (Symbol *s)
{
fprintf (headerfile, "static const int %s = %d;\n\n",
s->gen_name, s->constant);
}
static void
define_type (char *name, Type *t)
{
switch (t->type) {
case TType:
fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name);
break;
case TInteger:
fprintf (headerfile, "int %s;\n", name);
break;
case TOctetString:
fprintf (headerfile, "krb5_data %s;\n", name);
break;
case TBitString: {
Member *m;
Type i;
int tag = -1;
i.type = TInteger;
fprintf (headerfile, "struct {\n");
for (m = t->members; m && m->val != tag; m = m->next) {
char *n = malloc(strlen(m->gen_name) + 3);
strcpy (n, m->gen_name);
strcat (n, ":1");
define_type (n, &i);
free (n);
if (tag == -1)
tag = m->val;
}
fprintf (headerfile, "} %s;\n\n", name);
break;
}
case TSequence: {
Member *m;
int tag = -1;
fprintf (headerfile, "struct {\n");
for (m = t->members; m && m->val != tag; m = m->next) {
if (m->optional) {
char *n = malloc(strlen(m->gen_name) + 2);
*n = '*';
strcpy (n+1, m->gen_name);
define_type (n, m->type);
free (n);
} else
define_type (m->gen_name, m->type);
if (tag == -1)
tag = m->val;
}
fprintf (headerfile, "} %s;\n\n", name);
break;
}
case TSequenceOf: {
Type i;
i.type = TInteger;
i.application = 0;
fprintf (headerfile, "struct {\n");
define_type ("len", &i);
define_type ("*val", t->subtype);
fprintf (headerfile, "} %s;\n\n", name);
break;
}
case TGeneralizedTime:
fprintf (headerfile, "time_t %s;\n", name);
break;
case TGeneralString:
fprintf (headerfile, "char *%s;\n", name);
break;
case TApplication:
define_type (name, t->subtype);
break;
default:
abort ();
}
}
static void
generate_type_header (Symbol *s)
{
fprintf (headerfile, "typedef ");
define_type (s->gen_name, s->type);
fprintf (headerfile, "\n");
}
static void
encode_primitive (char *typename, char *name)
{
fprintf (codefile,
"l = encode_%s(p, len, %s);\n"
"if(l < 0)\n"
"return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n",
typename,
name);
}
static void
encode_type (char *name, Type *t)
{
switch (t->type) {
case TType:
#if 0
encode_type (name, t->symbol->type);
#endif
fprintf (codefile,
"l = encode_%s(p, len, %s);\n"
"if(l < 0)\n"
"return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n",
t->symbol->gen_name, name);
break;
case TInteger:
encode_primitive ("integer", name);
break;
case TOctetString:
encode_primitive ("octet_string", name);
break;
case TBitString: {
Member *m;
int pos;
int rest;
int tag = -1;
if (t->members == NULL)
break;
fprintf (codefile, "{\n"
"unsigned char c = 0;\n");
pos = t->members->prev->val;
rest = 7 - (t->members->prev->val % 8);
for (m = t->members->prev; m && tag != m->val; m = m->prev) {
while (m->val / 8 < pos / 8) {
fprintf (codefile,
"*p-- = c; len--; ret++;\n"
"c = 0;\n");
pos -= 8;
}
fprintf (codefile,
"if(%s->%s) c |= 1<<%d;\n", name, m->gen_name,
m->val % 8);
if (tag == -1)
tag = m->val;
}
fprintf (codefile,
"*p-- = c;\n"
"*p-- = %d;\n"
"len -= 2;\n"
"ret += 2;\n"
"}\n\n"
"l = der_put_length (p, len, ret);\n"
"if(l < 0)\n"
" return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n"
"l = der_put_tag (p, len, UNIV, PRIM, UT_BitString);\n"
"if(l < 0)\n"
"return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n",
rest);
break;
}
case TSequence: {
Member *m;
int tag = -1;
if (t->members == NULL)
break;
for (m = t->members->prev; m && tag != m->val; m = m->prev) {
char *s = malloc(1 + strlen(name) + 1 + strlen(m->gen_name) + 3);
sprintf (s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
if (m->optional)
fprintf (codefile,
"if(%s)\n",
s);
fprintf (codefile, "{\n"
"int oldret = ret;\n"
"ret = 0;\n");
encode_type (s, m->type);
fprintf (codefile,
"l = der_put_length (p, len, ret);\n"
"if (l < 0)\n"
"return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n"
"l = der_put_tag (p, len, CONTEXT, CONS, %d);\n"
"if(l < 0)\n"
"return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n",
m->val);
fprintf (codefile,
"ret += oldret;\n"
"}\n");
if (tag == -1)
tag = m->val;
free (s);
}
fprintf (codefile,
"l = der_put_length (p, len, ret);\n"
"if(l < 0)\n"
" return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n"
"l = der_put_tag (p, len, UNIV, CONS, UT_Sequence);\n"
"if(l < 0)\n"
"return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n");
break;
}
case TSequenceOf: {
char *n = malloc(strlen(name) + 12);
fprintf (codefile,
"for(i = (%s)->len - 1; i >= 0; --i) {\n"
"int oldret = ret;\n"
"ret = 0;\n",
name);
sprintf (n, "&(%s)->val[i]", name);
encode_type (n, t->subtype);
fprintf (codefile,
"ret += oldret;\n"
"}\n"
"l = der_put_length (p, len, ret);\n"
"if(l < 0)\n"
" return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n"
"l = der_put_tag (p, len, UNIV, CONS, UT_Sequence);\n"
"if(l < 0)\n"
"return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n");
free (n);
break;
}
case TGeneralizedTime:
encode_primitive ("generalized_time", name);
break;
case TGeneralString:
encode_primitive ("general_string", name);
break;
case TApplication:
encode_type (name, t->subtype);
fprintf (codefile,
"l = der_put_length (p, len, ret);\n"
"if(l < 0)\n"
" return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n"
"l = der_put_tag (p, len, APPL, CONS, %d);\n"
"if(l < 0)\n"
"return l;\n"
"p -= l;\n"
"len -= l;\n"
"ret += l;\n\n",
t->application);
break;
default:
abort ();
}
}
static void
generate_type_encode (Symbol *s)
{
fprintf (codefile, "int\n"
"encode_%s(unsigned char *p, int len, void *d)\n"
"{\n"
"%s *data = (%s *)d;\n"
"int ret = 0;\n"
"int l, i;\n\n",
s->gen_name, s->gen_name, s->gen_name);
encode_type ("data", s->type);
fprintf (codefile, "return ret;\n"
"}\n\n");
}
static void
decode_primitive (char *typename, char *name)
{
fprintf (codefile,
"l = decode_%s(p, len, %s);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n\n",
typename,
name);
}
static void
decode_type (char *name, Type *t)
{
switch (t->type) {
case TType:
#if 0
decode_type (name, t->symbol->type);
#endif
fprintf (codefile,
"l = decode_%s(p, len, %s);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n\n",
t->symbol->gen_name, name);
break;
case TInteger:
decode_primitive ("integer", name);
break;
case TOctetString:
decode_primitive ("octet_string", name);
break;
case TBitString:
break;
case TSequence: {
Member *m;
int tag = -1;
if (t->members == NULL)
break;
fprintf (codefile,
"l = der_match_tag (p, len, UNIV, CONS, UT_Sequence);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"l = der_get_length (p, len, &reallen);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"if(len < reallen)\n"
"return -1;\n"
"len = reallen;\n");
for (m = t->members; m && tag != m->val; m = m->next) {
char *s = malloc(1 + strlen(name) + 1 + strlen(m->gen_name) + 3);
sprintf (s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
fprintf (codefile, "{\n"
"int newlen, oldlen;\n\n"
"l = der_match_tag (p, len, CONTEXT, CONS, %d);\n",
m->val);
fprintf (codefile,
"if(l >= 0) {\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"l = der_get_length (p, len, &newlen);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"if(len < newlen)\n"
"return -1;\n"
"oldlen = len;\n"
"len = newlen;\n");
decode_type (s, m->type);
fprintf (codefile,
"len = oldlen - newlen;\n"
"}\n");
if (!m->optional)
fprintf (codefile,
"else {\n"
"return l;\n"
"}\n");
fprintf (codefile,
"}\n");
if (tag == -1)
tag = m->val;
free (s);
}
break;
}
case TSequenceOf: {
char *n = malloc(2*strlen(name) + 20);
fprintf (codefile,
"l = der_match_tag (p, len, UNIV, CONS, UT_Sequence);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"l = der_get_length (p, len, &reallen);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"if(len < reallen)\n"
"return -1;\n"
"len = reallen;\n");
fprintf (codefile,
"(%s)->len = 0;\n"
"(%s)->val = NULL;\n"
"while(len > 0) {\n"
"(%s)->len++;\n"
"(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n",
name, name, name, name, name, name, name);
sprintf (n, "&(%s)->val[(%s)->len-1]", name, name);
decode_type (n, t->subtype);
fprintf (codefile,
"}\n");
free (n);
break;
}
case TGeneralizedTime:
decode_primitive ("generalized_time", name);
break;
case TGeneralString:
decode_primitive ("general_string", name);
break;
case TApplication:
fprintf (codefile,
"l = der_match_tag (p, len, APPL, CONS, %d);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"l = der_get_length(p, len, &reallen);\n"
"if(l < 0)\n"
"return l;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"if(len < reallen)\n"
"return -1;\n"
"len = reallen;\n",
t->application);
decode_type (name, t->subtype);
break;
default :
abort ();
}
}
static void
generate_type_decode (Symbol *s)
{
fprintf (codefile, "int\n"
"decode_%s(unsigned char *p, int len, void *d)\n"
"{\n"
"%s *data = (%s *)d;\n"
"int ret = 0, reallen;\n"
"int l, i;\n\n",
s->gen_name, s->gen_name, s->gen_name);
decode_type ("data", s->type);
fprintf (codefile, "return ret;\n"
"}\n\n");
}
void
generate_type (Symbol *s)
{
generate_type_header (s);
generate_type_encode (s);
generate_type_decode (s);
}

11
lib/asn1/gen.h Normal file
View File

@@ -0,0 +1,11 @@
/* $Id$ */
#include <stdio.h>
#include "symbol.h"
void init_generate (char *);
void close_generate ();
void generate_constant (Symbol *);
void generate_type (Symbol *);
extern FILE *headerfile, *codefile;

181
lib/asn1/hash.c Normal file
View File

@@ -0,0 +1,181 @@
/*
* Hash table functions
*/
/* $Id$ */
static char rcsid[] = "$Id$";
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include "hash.h"
static Hashentry *_search(Hashtab * htab, /* The hash table */
void *ptr); /* And key */
Hashtab *
hashtabnew(int sz,
int (*cmp) (void *, void *),
unsigned (*hash) (void *))
{
Hashtab *htab;
int i;
assert(sz > 0);
htab = (Hashtab *) malloc(sizeof(Hashtab) + (sz - 1) * sizeof(Hashentry *));
for (i = 0; i < sz; ++i)
htab->tab[i] = NULL;
if (htab == NULL) {
return NULL;
} else {
htab->cmp = cmp;
htab->hash = hash;
htab->sz = sz;
return htab;
}
}
/* Intern search function */
static Hashentry *
_search(Hashtab * htab, void *ptr)
{
Hashentry *hptr;
assert(htab && ptr);
for (hptr = htab->tab[(*htab->hash) (ptr) % htab->sz];
hptr;
hptr = hptr->next)
if ((*htab->cmp) (ptr, hptr->ptr) == 0)
break;
return hptr;
}
/* Search for element in hash table */
void *
hashtabsearch(Hashtab * htab, void *ptr)
{
Hashentry *tmp;
tmp = _search(htab, ptr);
return tmp ? tmp->ptr : tmp;
}
/* add element to hash table */
/* if already there, set new value */
/* !NULL if succesful */
void *
hashtabadd(Hashtab * htab, void *ptr)
{
Hashentry *h = _search(htab, ptr);
Hashentry **tabptr;
assert(htab && ptr);
if (h)
free((void *) h->ptr);
else {
h = (Hashentry *) malloc(sizeof(Hashentry));
if (h == NULL) {
return NULL;
}
tabptr = &htab->tab[(*htab->hash) (ptr) % htab->sz];
h->next = *tabptr;
*tabptr = h;
h->prev = tabptr;
if (h->next)
h->next->prev = &h->next;
}
h->ptr = ptr;
return h;
}
/* delete element with key key. Iff freep, free Hashentry->ptr */
int
_hashtabdel(Hashtab * htab, void *ptr, int freep)
{
Hashentry *h;
assert(htab && ptr);
h = _search(htab, ptr);
if (h) {
if (freep)
free(h->ptr);
if (*(h->prev) = h->next)
h->next->prev = h->prev;
free(h);
return 0;
} else
return -1;
}
/* Do something for each element */
void
hashtabforeach(Hashtab * htab, int (*func) (void *ptr, void *arg),
void *arg)
{
Hashentry **h, *g;
assert(htab);
for (h = htab->tab; h < &htab->tab[htab->sz]; ++h)
for (g = *h; g; g = g->next)
if ((*func) (g->ptr, arg))
return;
}
/* standard hash-functions for strings */
unsigned
hashadd(const char *s)
{ /* Standard hash function */
unsigned i;
assert(s);
for (i = 0; *s; ++s)
i += *s;
return i;
}
unsigned
hashcaseadd(const char *s)
{ /* Standard hash function */
unsigned i;
assert(s);
for (i = 0; *s; ++s)
i += toupper(*s);
return i;
}
#define TWELVE (sizeof(unsigned))
#define SEVENTYFIVE (6*sizeof(unsigned))
#define HIGH_BITS (~((unsigned)(~0) >> TWELVE))
unsigned
hashjpw(const char *ss)
{ /* another hash function */
unsigned h = 0;
unsigned g;
unsigned const char *s = ss;
for (; *s; ++s) {
h = (h << TWELVE) + *s;
if (g = h & HIGH_BITS)
h = (h ^ (g >> SEVENTYFIVE)) & ~HIGH_BITS;
}
return h;
}

54
lib/asn1/hash.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* hash.h. Header file for hash table functions
*/
/* $Id$ */
struct hashentry { /* Entry in bucket */
struct hashentry **prev;
struct hashentry *next;
void *ptr;
};
typedef struct hashentry Hashentry;
struct hashtab { /* Hash table */
int (*cmp)(void *, void *); /* Compare function */
unsigned (*hash)(void *); /* hash function */
int sz; /* Size */
Hashentry *tab[1]; /* The table */
};
typedef struct hashtab Hashtab;
/* prototypes */
Hashtab *hashtabnew(int sz,
int (*cmp)(void *, void *),
unsigned (*hash)(void *)); /* Make new hash table */
void *hashtabsearch(Hashtab *htab, /* The hash table */
void *ptr); /* The key */
void *hashtabadd(Hashtab *htab, /* The hash table */
void *ptr); /* The element */
int _hashtabdel(Hashtab *htab, /* The table */
void *ptr, /* Key */
int freep); /* Free data part? */
void hashtabforeach(Hashtab *htab,
int (*func)(void *ptr, void *arg),
void *arg);
unsigned hashadd(const char *s); /* Standard hash function */
unsigned hashcaseadd(const char *s); /* Standard hash function */
unsigned hashjpw(const char *s); /* another hash function */
/* macros */
/* Don't free space */
#define hashtabdel(htab,key) _hashtabdel(htab,key,FALSE)
#define hashtabfree(htab,key) _hashtabdel(htab,key,TRUE) /* Do! */

328
lib/asn1/k5.asn1 Normal file
View File

@@ -0,0 +1,328 @@
KERBEROS5 DEFINITIONS ::=
BEGIN
nt-unknown INTEGER ::= 0 -- Name type not known
nt-principal INTEGER ::= 1 -- Just the name of the principal as in
nt-srv-inst INTEGER ::= 2 -- Service and other unique instance (krbtgt)
nt-srv-hst INTEGER ::= 3 -- Service with host name as instance
nt-srv-xhst INTEGER ::= 4 -- Service with host as remaining components
nt-uid INTEGER ::= 5 -- Unique ID
Realm ::= GeneralString
PrincipalName ::= SEQUENCE {
name-type[0] INTEGER,
name-string[1] SEQUENCE OF GeneralString
}
HostAddress ::= SEQUENCE {
addr-type[0] INTEGER,
address[1] OCTET STRING
}
HostAddresses ::= SEQUENCE OF SEQUENCE {
addr-type[0] INTEGER,
address[1] OCTET STRING
}
KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z)
AuthorizationData ::= SEQUENCE OF SEQUENCE {
ad-type[0] INTEGER,
ad-data[1] OCTET STRING
}
APOptions ::= BIT STRING {
reserved(0),
use-session-key(1),
mutual-required(2)
}
TicketFlags ::= BIT STRING {
reserved(0),
forwardable(1),
forwarded(2),
proxiable(3),
proxy(4),
may-postdate(5),
postdated(6),
invalid(7),
renewable(8),
initial(9),
pre-authent(10),
hw-authent(11)
}
KDCOptions ::= BIT STRING {
reserved(0),
forwardable(1),
forwarded(2),
proxiable(3),
proxy(4),
allow-postdate(5),
postdated(6),
unused7(7),
renewable(8),
unused9(9),
unused10(10),
unused11(11),
renewable-ok(27),
enc-tkt-in-skey(28),
renew(30),
validate(31)
}
LastReq ::= SEQUENCE OF SEQUENCE {
lr-type[0] INTEGER,
lr-value[1] KerberosTime
}
EncryptedData ::= SEQUENCE {
etype[0] INTEGER, -- EncryptionType
kvno[1] INTEGER OPTIONAL,
cipher[2] OCTET STRING -- ciphertext
}
EncryptionKey ::= SEQUENCE {
keytype[0] INTEGER,
keyvalue[1] OCTET STRING
}
-- encoded Transited field
TransitedEncoding ::= SEQUENCE {
tr-type[0] INTEGER, -- must be registered
contents[1] OCTET STRING
}
Ticket ::= [APPLICATION 1] SEQUENCE {
tkt-vno[0] INTEGER,
realm[1] Realm,
sname[2] PrincipalName,
enc-part[3] EncryptedData
}
-- Encrypted part of ticket
EncTicketPart ::= [APPLICATION 3] SEQUENCE {
flags[0] TicketFlags,
key[1] EncryptionKey,
crealm[2] Realm,
cname[3] PrincipalName,
transited[4] TransitedEncoding,
authtime[5] KerberosTime,
starttime[6] KerberosTime OPTIONAL,
endtime[7] KerberosTime,
renew-till[8] KerberosTime OPTIONAL,
caddr[9] HostAddresses OPTIONAL,
authorization-data[10] AuthorizationData OPTIONAL
}
Checksum ::= SEQUENCE {
cksumtype[0] INTEGER,
checksum[1] OCTET STRING
}
Authenticator ::= [APPLICATION 2] SEQUENCE {
authenticator-vno[0] INTEGER,
crealm[1] Realm,
cname[2] PrincipalName,
cksum[3] Checksum OPTIONAL,
cusec[4] INTEGER,
ctime[5] KerberosTime,
subkey[6] EncryptionKey OPTIONAL,
seq-number[7] INTEGER OPTIONAL,
authorization-data[8] AuthorizationData OPTIONAL
}
PA-DATA ::= SEQUENCE {
padata-type[1] INTEGER,
padata-value[2] OCTET STRING
-- ,
-- might be encoded AP-REQ
}
KDC-REQ-BODY ::= SEQUENCE {
kdc-options[0] KDCOptions,
cname[1] PrincipalName OPTIONAL,
-- Used only in AS-REQ
realm[2] Realm, -- Server's realm
-- Also client's in AS-REQ
sname[3] PrincipalName OPTIONAL,
from[4] KerberosTime OPTIONAL,
till[5] KerberosTime,
rtime[6] KerberosTime OPTIONAL,
nonce[7] INTEGER,
etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
-- in preference order
addresses[9] HostAddresses OPTIONAL,
enc-authorization-data[10] EncryptedData OPTIONAL,
-- Encrypted AuthorizationData encoding
additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
}
KDC-REQ ::= SEQUENCE {
pvno[1] INTEGER,
msg-type[2] INTEGER,
padata[3] SEQUENCE OF PA-DATA OPTIONAL,
req-body[4] KDC-REQ-BODY
}
AS-REQ ::= [APPLICATION 10] KDC-REQ
TGS-REQ ::= [APPLICATION 12] KDC-REQ
-- padata-type ::= PA-ENC-TIMESTAMP
-- padata-value ::= EncryptedData - PA-ENC-TS-ENC
PA-ENC-TS-ENC ::= SEQUENCE {
patimestamp[0] KerberosTime, -- client's time
pausec[1] INTEGER OPTIONAL
}
KDC-REP ::= SEQUENCE {
pvno[0] INTEGER,
msg-type[1] INTEGER,
padata[2] SEQUENCE OF PA-DATA OPTIONAL,
crealm[3] Realm,
cname[4] PrincipalName,
ticket[5] Ticket,
enc-part[6] EncryptedData
}
AS-REP ::= [APPLICATION 11] KDC-REP
TGS-REP ::= [APPLICATION 13] KDC-REP
EncKDCRepPart ::= SEQUENCE {
key[0] EncryptionKey,
last-req[1] LastReq,
nonce[2] INTEGER,
key-expiration[3] KerberosTime OPTIONAL,
flags[4] TicketFlags,
authtime[5] KerberosTime,
starttime[6] KerberosTime OPTIONAL,
endtime[7] KerberosTime,
renew-till[8] KerberosTime OPTIONAL,
srealm[9] Realm,
sname[10] PrincipalName,
caddr[11] HostAddresses OPTIONAL
}
EncASRepPart ::= [APPLICATION 25] EncKDCRepPart
EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
AP-REQ ::= [APPLICATION 14] SEQUENCE {
pvno[0] INTEGER,
msg-type[1] INTEGER,
ap-options[2] APOptions,
ticket[3] Ticket,
authenticator[4] EncryptedData
}
AP-REP ::= [APPLICATION 15] SEQUENCE {
pvno[0] INTEGER,
msg-type[1] INTEGER,
enc-part[2] EncryptedData
}
EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
ctime[0] KerberosTime,
cusec[1] INTEGER,
subkey[2] EncryptionKey OPTIONAL,
seq-number[3] INTEGER OPTIONAL
}
KRB-SAFE-BODY ::= SEQUENCE {
user-data[0] OCTET STRING,
timestamp[1] KerberosTime OPTIONAL,
usec[2] INTEGER OPTIONAL,
seq-number[3] INTEGER OPTIONAL,
s-address[4] HostAddress,
r-address[5] HostAddress OPTIONAL
}
KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
pvno[0] INTEGER,
msg-type[1] INTEGER,
safe-body[2] KRB-SAFE-BODY,
cksum[3] Checksum
}
KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
pvno[0] INTEGER,
msg-type[1] INTEGER,
enc-part[3] EncryptedData
}
EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
user-data[0] OCTET STRING,
timestamp[1] KerberosTime OPTIONAL,
usec[2] INTEGER OPTIONAL,
seq-number[3] INTEGER OPTIONAL,
s-address[4] HostAddress, -- sender's addr
r-address[5] HostAddress OPTIONAL
-- recip's addr
}
KRB-CRED ::= [APPLICATION 22] SEQUENCE {
pvno[0] INTEGER,
msg-type[1] INTEGER, -- KRB_CRED
tickets[2] SEQUENCE OF Ticket,
enc-part[3] EncryptedData
}
KrbCredInfo ::= SEQUENCE {
key[0] EncryptionKey,
prealm[1] Realm OPTIONAL,
pname[2] PrincipalName OPTIONAL,
flags[3] TicketFlags OPTIONAL,
authtime[4] KerberosTime OPTIONAL,
starttime[5] KerberosTime OPTIONAL,
endtime[6] KerberosTime OPTIONAL,
renew-till[7] KerberosTime OPTIONAL,
srealm[8] Realm OPTIONAL,
sname[9] PrincipalName OPTIONAL,
caddr[10] HostAddresses OPTIONAL
}
EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
ticket-info[0] SEQUENCE OF KrbCredInfo,
nonce[1] INTEGER OPTIONAL,
timestamp[2] KerberosTime OPTIONAL,
usec[3] INTEGER OPTIONAL,
s-address[4] HostAddress OPTIONAL,
r-address[5] HostAddress OPTIONAL
}
KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
pvno[0] INTEGER,
msg-type[1] INTEGER,
ctime[2] KerberosTime OPTIONAL,
cusec[3] INTEGER OPTIONAL,
stime[4] KerberosTime,
susec[5] INTEGER,
error-code[6] INTEGER,
crealm[7] Realm OPTIONAL,
cname[8] PrincipalName OPTIONAL,
realm[9] Realm, -- Correct realm
sname[10] PrincipalName, -- Correct name
e-text[11] GeneralString OPTIONAL,
e-data[12] OCTET STRING OPTIONAL
}
pvno INTEGER ::= 5 -- current Kerberos protocol version number
-- message types
krb-as-req INTEGER ::= 10 -- Request for initial authentication
krb-as-rep INTEGER ::= 11 -- Response to KRB_AS_REQ request
krb-tgs-req INTEGER ::= 12 -- Request for authentication based on TGT
krb-tgs-rep INTEGER ::= 13 -- Response to KRB_TGS_REQ request
krb-ap-req INTEGER ::= 14 -- application request to server
krb-ap-rep INTEGER ::= 15 -- Response to KRB_AP_REQ_MUTUAL
krb-safe INTEGER ::= 20 -- Safe (checksummed) application message
krb-priv INTEGER ::= 21 -- Private (encrypted) application message
krb-cred INTEGER ::= 22 -- Private (encrypted) message to forward credentials
krb-error INTEGER ::= 30 -- Error response
END

3
lib/asn1/lex.h Normal file
View File

@@ -0,0 +1,3 @@
/* $Id$ */
void error_message (char *, ...);

56
lib/asn1/lex.l Normal file
View File

@@ -0,0 +1,56 @@
/* $Id$ */
%{
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "symbol.h"
#include "parse.h"
static unsigned lineno = 1;
static char filename[256];
%}
%%
INTEGER { return INTEGER; }
SEQUENCE { return SEQUENCE; }
OF { return OF; }
OCTET { return OCTET; }
STRING { return STRING; }
GeneralizedTime { return GeneralizedTime; }
GeneralString { return GeneralString; }
BIT { return BIT; }
APPLICATION { return APPLICATION; }
OPTIONAL { return OPTIONAL; }
BEGIN { return TBEGIN; }
END { return END; }
DEFINITIONS { return DEFINITIONS; }
[][|{},()] { return *yytext; }
::= { return EEQUAL; }
--[^\n]*\n { ; }
-?[0-9]+ { yylval.constant = atoi(yytext); return CONSTANT; }
[A-Za-z][-A-Za-z0-9_]* { yylval.name = strdup (yytext); return IDENTIFIER; }
[ \t] ;
\n { lineno++; }
. { fprintf(stderr, "Ignoring char(%c)\n", *yytext); }
%%
int
yywrap ()
{
return 1;
}
void
error_message (char *format, ...)
{
va_list args;
va_start (args, format);
fprintf (stderr, ":%d: ", lineno);
vfprintf (stderr, format, args);
va_end (args);
}

31
lib/asn1/main.c Normal file
View File

@@ -0,0 +1,31 @@
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include "symbol.h"
extern FILE *yyin;
int
main(int argc, char **argv)
{
int ret;
char *name;
if (argc == 1) {
name = "stdin";
yyin = stdin;
} else {
name = argv[1];
yyin = fopen (name, "r");
}
init_generate (name);
initsym ();
ret = yyparse ();
close_generate ();
return ret;
}

179
lib/asn1/parse.y Normal file
View File

@@ -0,0 +1,179 @@
/* $Id$ */
%{
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include "symbol.h"
#include "lex.h"
#include "gen.h"
static Type *new_type (Typetype t);
void yyerror (char *);
%}
%union {
int constant;
char *name;
Type *type;
Member *member;
}
%token INTEGER SEQUENCE OF OCTET STRING GeneralizedTime GeneralString
%token BIT APPLICATION OPTIONAL EEQUAL TBEGIN END DEFINITIONS
%token <name> IDENTIFIER
%token <constant> CONSTANT
%token IDENTIFIER CONSTANT
%type <constant> constant optional2
%type <type> type
%type <member> memberdecls memberdecl bitdecls bitdecl
%start envelope
%%
envelope : IDENTIFIER DEFINITIONS EEQUAL TBEGIN specification END {}
;
specification :
| specification declaration
;
declaration : type_decl
| constant_decl
;
type_decl : IDENTIFIER EEQUAL type
{
Symbol *s = addsym ($1);
s->stype = Stype;
s->type = $3;
generate_type (s);
}
;
constant_decl : IDENTIFIER type EEQUAL constant
{
Symbol *s = addsym ($1);
s->stype = SConstant;
s->constant = $4;
generate_constant (s);
}
;
type : INTEGER { $$ = new_type(TInteger); }
| OCTET STRING { $$ = new_type(TOctetString); }
| GeneralString { $$ = new_type(TGeneralString); }
| GeneralizedTime { $$ = new_type(TGeneralizedTime); }
| SEQUENCE OF type
{
$$ = new_type(TSequenceOf);
$$->subtype = $3;
}
| SEQUENCE '{' memberdecls '}'
{
$$ = new_type(TSequence);
$$->members = $3;
}
| BIT STRING '{' bitdecls '}'
{
$$ = new_type(TBitString);
$$->members = $4;
}
| IDENTIFIER
{
Symbol *s = addsym($1);
$$ = new_type(TType);
if(s->stype != Stype)
error_message ("%s is not a type\n", $1);
else
$$->symbol = s;
}
| '[' APPLICATION constant ']' type
{
$$ = new_type(TApplication);
$$->subtype = $5;
$$->application = $3;
}
;
memberdecls : { $$ = NULL; }
| memberdecl { $$ = $1; }
| memberdecls ',' memberdecl { $$ = $1; append($$, $3); }
;
memberdecl : IDENTIFIER '[' constant ']' type optional2
{
$$ = malloc(sizeof(*$$));
$$->name = $1;
$$->gen_name = strdup($1);
output_name ($$->gen_name);
$$->val = $3;
$$->optional = $6;
$$->type = $5;
$$->next = $$->prev = $$;
}
;
optional2 : { $$ = 0; }
| OPTIONAL { $$ = 1; }
;
bitdecls : { $$ = NULL; }
| bitdecl { $$ = $1; }
| bitdecls ',' bitdecl { $$ = $1; append($$, $3); }
;
bitdecl : IDENTIFIER '(' constant ')'
{
$$ = malloc(sizeof(*$$));
$$->name = $1;
$$->gen_name = strdup($1);
output_name ($$->gen_name);
$$->val = $3;
$$->optional = 0;
$$->type = NULL;
$$->prev = $$->next = $$;
}
;
constant : CONSTANT { $$ = $1; }
| IDENTIFIER {
Symbol *s = addsym($1);
if(s->stype != SConstant)
error_message ("%s is not a constant\n",
s->name);
else
$$ = s->constant;
}
;
%%
void
yyerror (char *s)
{
error_message ("%s\n", s);
}
static Type *
new_type (Typetype tt)
{
Type *t = malloc(sizeof(*t));
t->type = tt;
t->application = 0;
t->members = NULL;
t->subtype = NULL;
t->symbol = NULL;
}
static void
append (Member *l, Member *r)
{
l->prev->next = r;
r->prev = l->prev;
l->prev = r;
r->next = l;
}

64
lib/asn1/symbol.c Normal file
View File

@@ -0,0 +1,64 @@
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include "symbol.h"
#include "hash.h"
static Hashtab *htab;
static int
cmp (void *a, void *b)
{
Symbol *s1 = (Symbol *)a;
Symbol *s2 = (Symbol *)b;
return strcmp (s1->name, s2->name);
}
static unsigned
hash (void *a)
{
Symbol *s = (Symbol *)a;
return hashjpw (s->name);
}
void
initsym ()
{
htab = hashtabnew (101, cmp, hash);
}
void
output_name (char *s)
{
char *p;
for (p = s; *p; ++p)
if (*p == '-')
*p = '_';
}
Symbol*
addsym (char *name)
{
Symbol key, *s;
key.name = name;
s = (Symbol *)hashtabsearch (htab, (void *)&key);
if (s == NULL) {
char *p;
s = (Symbol *)malloc (sizeof (*s));
s->name = name;
s->gen_name = strdup(name);
output_name (s->gen_name);
s->stype = SUndefined;
hashtabadd (htab, s);
}
return s;
}

49
lib/asn1/symbol.h Normal file
View File

@@ -0,0 +1,49 @@
/* $Id$ */
#ifndef _SYMBOL_H
#define _SYMBOL_H
enum typetype { TInteger, TOctetString, TBitString, TSequence, TSequenceOf,
TGeneralizedTime, TGeneralString, TApplication, TType };
typedef enum typetype Typetype;
struct type;
struct member {
char *name;
char *gen_name;
int val;
int optional;
struct type *type;
struct member *next, *prev;
};
typedef struct member Member;
struct symbol;
struct type {
Typetype type;
int application;
Member *members;
struct type *subtype;
struct symbol *symbol;
};
typedef struct type Type;
struct symbol {
char *name;
char *gen_name;
enum { SUndefined, SConstant, Stype } stype;
int constant;
Type *type;
};
typedef struct symbol Symbol;
void initsym ();
Symbol *addsym (char *);
void output_name (char *);
#endif

View File

@@ -1,6 +1,4 @@
#include <krb5_locl.h>
#include <d.h>
#include <k5_der.h>
#include <krb5_error.h>
/*
@@ -14,6 +12,10 @@ krb5_get_credentials (krb5_context context,
krb5_creds *in_creds,
krb5_creds *out_creds)
{
return 17;
}
#if 0
krb5_error_code err;
Tgs_Req a;
krb5_kdc_rep rep;
@@ -75,4 +77,6 @@ krb5_get_credentials (krb5_context context,
return ASN1_PARSE_ERROR;
}
}
#endif

View File

@@ -1,7 +1,5 @@
#include "krb5_locl.h"
#include <krb5_error.h>
#include <d.h>
#include <k5_der.h>
static krb5_error_code
krb5_get_salt (krb5_principal princ,
@@ -37,28 +35,70 @@ decrypt_tkt (krb5_context context,
{
des_key_schedule sched;
char *buf;
Buffer buffer;
int i;
int len = dec_rep->part1.enc_part.cipher.length;
des_set_key (key->contents.data, sched);
buf = malloc (dec_rep->enc_part.cipher.length);
buf = malloc (len);
if (buf == NULL)
return ENOMEM;
des_cbc_encrypt ((des_cblock *)dec_rep->enc_part.cipher.data,
des_cbc_encrypt ((des_cblock *)dec_rep->part1.enc_part.cipher.data,
(des_cblock *)buf,
dec_rep->enc_part.cipher.length,
len,
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;
}
i = decode_EncTGSRepPart(buf + 12, len - 12, &dec_rep->part2);
free (buf);
if (i < 0)
return ASN1_PARSE_ERROR;
return 0;
}
/*
*
*/
krb5_error_code
krb5_principal2principalname (PrincipalName *p,
krb5_principal from)
{
int i;
p->name_type = from->type;
p->name_string.len = from->ncomp;
p->name_string.val = malloc(from->ncomp * sizeof(*p->name_string.val));
for (i = 0; i < from->ncomp; ++i) {
int len = from->comp[i].length;
p->name_string.val[i] = malloc(len + 1);
strncpy (p->name_string.val[i], from->comp[i].data, len);
p->name_string.val[i][len] = '\0';
}
return 0;
}
krb5_error_code
principalname2krb5_principal (krb5_principal p,
PrincipalName from,
krb5_data realm)
{
int i;
p = malloc (sizeof(*p));
p->type = from.name_type;
p->ncomp = from.name_string.len;
p->comp = malloc (p->ncomp * sizeof(*p->comp));
for (i = 0; i < p->ncomp; ++i) {
int len = strlen(from.name_string.val[i]) + 1;
p->comp[i].length = len;
p->comp[i].data = strdup(from.name_string.val[i]);
}
p->realm = realm;
return 0;
}
/*
*
*/
@@ -78,78 +118,93 @@ krb5_get_in_tkt(krb5_context context,
krb5_kdc_rep **ret_as_reply)
{
krb5_error_code err;
As_Req a;
AS_REQ a;
krb5_kdc_rep rep;
krb5_data req, resp;
char buf[BUFSIZ];
Buffer buffer;
krb5_data salt;
krb5_keyblock *key;
a.pvno = 5;
a.msg_type = KRB_AS_REQ;
memset (&a.kdc_options, 0, sizeof(a.kdc_options));
a.msg_type = krb_as_req;
memset (&a.req_body.kdc_options, 0, sizeof(a.req_body.kdc_options));
/* a.kdc_options */
a.cname = creds->client;
a.sname = creds->server;
a.realm = creds->client->realm;
a.till = creds->times.endtime;
a.nonce = 17;
a.req_body.cname = malloc(sizeof(*a.req_body.cname));
a.req_body.sname = malloc(sizeof(*a.req_body.sname));
krb5_principal2principalname (a.req_body.cname, creds->client);
krb5_principal2principalname (a.req_body.sname, creds->server);
a.req_body.realm = malloc(creds->client->realm.length + 1);
strncpy (a.req_body.realm, creds->client->realm.data,
creds->client->realm.length);
a.req_body.realm[creds->client->realm.length] = '\0';
a.req_body.till = creds->times.endtime;
a.req_body.nonce = 17;
if (etypes)
a.etypes = etypes;
abort ();
else {
err = krb5_get_default_in_tkt_etypes (context, &a.etypes);
err = krb5_get_default_in_tkt_etypes (context,
&a.req_body.etype.val);
if (err)
return err;
a.num_etypes = 1;
a.req_body.etype.len = 1;
}
if (addrs){
} else {
err = krb5_get_all_client_addrs (&a.addrs);
a.req_body.addresses = malloc(sizeof(*a.req_body.addresses));
err = krb5_get_all_client_addrs (a.req_body.addresses);
if (err)
return err;
}
req.length = der_put_as_req (buf + sizeof(buf) - 1, &a);
req.data = buf + sizeof(buf) - req.length;
a.req_body.enc_authorization_data = NULL;
a.req_body.additional_tickets = NULL;
a.padata = NULL;
req.length = encode_AS_REQ (buf + sizeof(buf) - 1,
sizeof(buf),
&a);
if (req.length < 0)
return ASN1_PARSE_ERROR;
req.data = buf + sizeof(buf) - req.length;
if (addrs == NULL) {
int i;
for (i = 0; i < a.addrs.number; ++i)
krb5_data_free (&a.addrs.addrs[i].address);
free (a.addrs.addrs);
for (i = 0; i < a.req_body.addresses->len; ++i)
krb5_data_free (&a.req_body.addresses->val[i].address);
free (a.req_body.addresses->val);
}
err = krb5_sendto_kdc (context, &req, &a.realm, &resp);
err = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
if (err) {
return err;
}
buf_init (&buffer, resp.data, resp.length);
if (der_get_as_rep (&buffer, &rep) == -1) {
return ASN1_PARSE_ERROR;
}
krb5_data_free (&rep.realm);
krb5_principal_free (rep.cname);
creds->ticket.kvno = rep.ticket.kvno;
creds->ticket.etype = rep.ticket.etype;
if(decode_AS_REP(resp.data, resp.length, &rep) < 0)
return ASN1_PARSE_ERROR;
free (rep.part1.crealm);
/* krb5_principal_free (rep.part1.cname);*/
creds->ticket.kvno = rep.part1.ticket.tkt_vno;
creds->ticket.etype = rep.part1.enc_part.etype;
creds->ticket.enc_part.length = 0;
creds->ticket.enc_part.data = NULL;
krb5_data_copy (&creds->ticket.enc_part,
rep.ticket.enc_part.data,
rep.ticket.enc_part.length);
krb5_data_free (&rep.ticket.enc_part);
rep.part1.ticket.enc_part.cipher.data,
rep.part1.ticket.enc_part.cipher.length);
krb5_data_free (&rep.part1.ticket.enc_part.cipher);
krb5_copy_principal (context,
rep.ticket.sprinc,
&creds->ticket.sprinc);
krb5_free_principal (rep.ticket.sprinc);
principalname2krb5_principal (creds->ticket.sprinc,
rep.part1.ticket.sname,
creds->client->realm);
/* krb5_free_principal (rep.part1.ticket.sprinc);*/
salt.length = 0;
salt.data = NULL;
err = krb5_get_salt (creds->client, creds->client->realm, &salt);
if (err)
return err;
err = (*key_proc)(context, rep.enc_part.etype, &salt, keyseed, &key);
err = (*key_proc)(context, rep.part1.enc_part.etype, &salt,
keyseed, &key);
krb5_data_free (&salt);
if (err)
return err;
@@ -161,45 +216,49 @@ krb5_get_in_tkt(krb5_context context,
memset (key->contents.data, 0, key->contents.length);
krb5_data_free (&key->contents);
free (key);
if (rep.enc_part2.key_expiration)
free (rep.enc_part2.key_expiration);
if (rep.enc_part2.starttime) {
creds->times.starttime = *rep.enc_part2.starttime;
free (rep.enc_part2.starttime);
if (rep.part2.key_expiration)
free (rep.part2.key_expiration);
if (rep.part2.starttime) {
creds->times.starttime = *rep.part2.starttime;
free (rep.part2.starttime);
} else
creds->times.starttime = rep.enc_part2.authtime;
if (rep.enc_part2.renew_till) {
creds->times.renew_till = *rep.enc_part2.renew_till;
free (rep.enc_part2.renew_till);
creds->times.starttime = rep.part2.authtime;
if (rep.part2.renew_till) {
creds->times.renew_till = *rep.part2.renew_till;
free (rep.part2.renew_till);
} else
creds->times.renew_till = rep.enc_part2.endtime;
creds->times.authtime = rep.enc_part2.authtime;
creds->times.endtime = rep.enc_part2.endtime;
if (rep.enc_part2.req.values)
free (rep.enc_part2.req.values);
if (rep.enc_part2.caddr.addrs) {
creds->times.renew_till = rep.part2.endtime;
creds->times.authtime = rep.part2.authtime;
creds->times.endtime = rep.part2.endtime;
#if 0 /* What? */
if (rep.part2.req.values)
free (rep.part2.req.values);
#endif
#if 0
if (rep.part2.caddr.addrs) {
int i;
for (i = 0; i < rep.enc_part2.caddr.number; ++i) {
krb5_data_free (&rep.enc_part2.caddr.addrs[i].address);
for (i = 0; i < rep.part2.caddr.number; ++i) {
krb5_data_free (&rep.part2.caddr.addrs[i].address);
}
free (rep.enc_part2.caddr.addrs);
free (rep.part2.caddr.addrs);
}
krb5_principal_free (rep.enc_part2.sname);
krb5_data_free (&rep.enc_part2.srealm);
krb5_principal_free (rep.part2.sname);
krb5_data_free (&rep.part2.srealm);
#endif
if (err)
return err;
creds->session.contents.length = 0;
creds->session.contents.data = NULL;
creds->session.keytype = rep.enc_part2.key.keytype;
creds->session.keytype = rep.part2.key.keytype;
err = krb5_data_copy (&creds->session.contents,
rep.enc_part2.key.contents.data,
rep.enc_part2.key.contents.length);
memset (rep.enc_part2.key.contents.data, 0,
rep.enc_part2.key.contents.length);
krb5_data_free (&rep.enc_part2.key.contents);
rep.part2.key.keyvalue.data,
rep.part2.key.keyvalue.length);
memset (rep.part2.key.keyvalue.data, 0,
rep.part2.key.keyvalue.length);
krb5_data_free (&rep.part2.key.keyvalue);
if (err)
return err;

View File

@@ -1,10 +1,16 @@
#ifndef __KRB5_H__
#define __KRB5_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <stdarg.h>
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#include "config_file.h"
@@ -213,7 +219,12 @@ typedef struct krb5_auth_context{
typedef krb5_uint32 krb5_flags;
typedef struct krb5_kdc_rep krb5_kdc_rep;
#include <foo.h>
typedef struct {
KDC_REP part1;
EncTGSRepPart part2;
} krb5_kdc_rep;
krb5_error_code
krb5_init_context(krb5_context *context);