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:
65
lib/asn1/Makefile.in
Normal file
65
lib/asn1/Makefile.in
Normal 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
41
lib/asn1/der.h
Normal 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
239
lib/asn1/der_get.c
Normal 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
213
lib/asn1/der_put.c
Normal 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
535
lib/asn1/gen.c
Normal 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
11
lib/asn1/gen.h
Normal 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
181
lib/asn1/hash.c
Normal 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
54
lib/asn1/hash.h
Normal 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
328
lib/asn1/k5.asn1
Normal 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
3
lib/asn1/lex.h
Normal file
@@ -0,0 +1,3 @@
|
||||
/* $Id$ */
|
||||
|
||||
void error_message (char *, ...);
|
56
lib/asn1/lex.l
Normal file
56
lib/asn1/lex.l
Normal 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
31
lib/asn1/main.c
Normal 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
179
lib/asn1/parse.y
Normal 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
64
lib/asn1/symbol.c
Normal 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
49
lib/asn1/symbol.h
Normal 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
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user