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:
@@ -1,9 +1,15 @@
|
||||
CC=cc
|
||||
CFLAGS=-I. -I/usr/athena/include -g
|
||||
# $Id$
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
#YACC=bison -y
|
||||
YACC=yacc
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
DEFS = @DEFS@
|
||||
YACC = @YACC@
|
||||
|
||||
CFLAGS = -g -I$(srcdir) -Iasn1 -I.
|
||||
|
||||
SOURCES = cache.c principal.c principal_p.c data.c context.c misc.c \
|
||||
krbhst.c get_port.c send_to_kdc.c str2key.c \
|
||||
@@ -15,7 +21,7 @@ OBJECTS = $(SOURCES:%.c=%.o) config_file.o
|
||||
all: kinit klist
|
||||
|
||||
kinit: kinit.o libkrb5.a
|
||||
$(CC) -o kinit kinit.o libkrb5.a -L/usr/local/lib -ldes
|
||||
$(CC) -o kinit kinit.o libkrb5.a -Lasn1 -lasn1 -L/usr/local/lib -ldes
|
||||
|
||||
klist: klist.o libkrb5.a
|
||||
$(CC) -o klist klist.o libkrb5.a -L/usr/local/lib -ldes
|
302
aclocal.m4
vendored
Normal file
302
aclocal.m4
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
dnl
|
||||
dnl General tests
|
||||
dnl
|
||||
|
||||
dnl
|
||||
dnl Look for function in any of the specified libraries
|
||||
dnl
|
||||
|
||||
AC_DEFUN(AC_FIND_FUNC_NO_LIBS, [
|
||||
|
||||
AC_MSG_CHECKING([for $1])
|
||||
AC_CACHE_VAL(ac_cv_funclib_$1,
|
||||
[
|
||||
if eval "test \"\$ac_cv_func_$1\" != yes" ; then
|
||||
ac_save_LIBS="$LIBS"
|
||||
for ac_lib in "" $2; do
|
||||
if test -n "$ac_lib"; then
|
||||
ac_lib="-l$ac_lib"
|
||||
LIBS="$ac_lib $ac_save_LIBS"
|
||||
fi
|
||||
AC_TRY_LINK([],[$1()],eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break)
|
||||
done
|
||||
eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
])
|
||||
|
||||
eval "ac_res=\$ac_cv_funclib_$1"
|
||||
|
||||
# autoheader tricks *sigh*
|
||||
: << END
|
||||
@@@funcs="$funcs $1"@@@
|
||||
@@@libs="$libs $2"@@@
|
||||
END
|
||||
|
||||
changequote(, )dnl
|
||||
eval "ac_tr_func=HAVE_`echo $1 | tr '[a-z]' '[A-Z]'`"
|
||||
eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr '[a-z]' '[A-Z]'`"
|
||||
eval "LIB_$1=$ac_res"
|
||||
changequote([, ])dnl
|
||||
|
||||
case "$ac_res" in
|
||||
yes)
|
||||
eval "ac_cv_func_$1=yes"
|
||||
eval "LIB_$1="
|
||||
AC_DEFINE_UNQUOTED($ac_tr_func)
|
||||
AC_MSG_RESULT([yes])
|
||||
;;
|
||||
no)
|
||||
eval "ac_cv_func_$1=no"
|
||||
eval "LIB_$1="
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
*)
|
||||
eval "ac_cv_func_$1=yes"
|
||||
eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
|
||||
AC_DEFINE_UNQUOTED($ac_tr_func)
|
||||
AC_DEFINE_UNQUOTED($ac_tr_lib)
|
||||
AC_MSG_RESULT([yes, in $ac_res])
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(LIB_$1)
|
||||
])
|
||||
|
||||
AC_DEFUN(AC_FIND_FUNC, [
|
||||
AC_FIND_FUNC_NO_LIBS($1, $2)
|
||||
if test -n "$LIB_$1"; then
|
||||
LIBS="$LIBS $LIB_$1"
|
||||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Same as AC _REPLACE_FUNCS, just define HAVE_func if found in normal
|
||||
dnl libraries
|
||||
|
||||
AC_DEFUN(AC_BROKEN,
|
||||
[for ac_func in $1
|
||||
do
|
||||
AC_CHECK_FUNC($ac_func, [
|
||||
changequote(, )dnl
|
||||
ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'`
|
||||
changequote([, ])dnl
|
||||
AC_DEFINE_UNQUOTED($ac_tr_func)],[LIBOBJS="$LIBOBJS ${ac_func}.o"])
|
||||
# autoheader tricks *sigh*
|
||||
: << END
|
||||
@@@funcs="$funcs $1"@@@
|
||||
END
|
||||
done
|
||||
AC_SUBST(LIBOBJS)dnl
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Mix between AC_FIND_FUNC and AC_BROKEN
|
||||
dnl
|
||||
|
||||
AC_DEFUN(AC_FIND_IF_NOT_BROKEN,
|
||||
[AC_FIND_FUNC($1, $2)
|
||||
if eval "test \"$ac_cv_func_$1\" != yes"; then
|
||||
LIBOBJS="$LIBOBJS $1.o"
|
||||
fi
|
||||
AC_SUBST(LIBOBJS)dnl
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Build S/Key support into the login program.
|
||||
dnl
|
||||
AC_DEFUN(AC_TEST_SKEY,
|
||||
[AC_ARG_WITH(skeylib,
|
||||
[ --with-skeylib=dir use the skeylib.a in dir],
|
||||
)
|
||||
test -n "$with_skeylib" &&
|
||||
SKEYLIB="-L$with_skeylib -lskey" &&
|
||||
SKEYINCLUDE="-I$with_skeylib" &&
|
||||
AC_MSG_RESULT(Using skeylib in $with_skeylib)
|
||||
AC_SUBST(SKEYLIB)
|
||||
AC_SUBST(SKEYINCLUDE)
|
||||
test -n "$with_skeylib" &&
|
||||
AC_DEFINE(SKEY)])
|
||||
|
||||
dnl
|
||||
dnl Check if we need the declaration of a variable
|
||||
dnl
|
||||
|
||||
AC_DEFUN(AC_NEED_DECLARATION, [
|
||||
AC_MSG_CHECKING([if $3 needs a declaration])
|
||||
AC_CACHE_VAL(ac_cv_var_$3_declaration, [
|
||||
AC_TRY_COMPILE([$1],
|
||||
[$2 foo = ($2)$3; ],
|
||||
eval "ac_cv_var_$3_declaration=no",
|
||||
eval "ac_cv_var_$3_declaration=yes")
|
||||
])
|
||||
|
||||
changequote(, )dnl
|
||||
eval "ac_tr_var=NEED_`echo $3 | tr '[a-z]' '[A-Z]'`_DECLARATION"
|
||||
changequote([, ])dnl
|
||||
|
||||
define([foo], [NEED_]translit($3, [a-z], [A-Z])[_DECLARATION])
|
||||
: << END
|
||||
@@@syms="$syms foo"@@@
|
||||
END
|
||||
undefine([foo])
|
||||
|
||||
AC_MSG_RESULT($ac_cv_var_$3_declaration)
|
||||
if eval "test \"\$ac_cv_var_$3_declaration\" = yes"; then
|
||||
AC_DEFINE_UNQUOTED($ac_tr_var)
|
||||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Check if we need the prototype for a function
|
||||
dnl
|
||||
|
||||
AC_DEFUN(AC_NEED_PROTO, [
|
||||
AC_MSG_CHECKING([if $3 needs a proto])
|
||||
AC_CACHE_VAL(ac_cv_func_$3_proto, [
|
||||
AC_TRY_COMPILE([$1],
|
||||
[$2],
|
||||
eval "ac_cv_func_$3_proto=no",
|
||||
eval "ac_cv_func_$3_proto=yes")
|
||||
])
|
||||
changequote(, )dnl
|
||||
eval "ac_tr_func=NEED_`echo $3 | tr '[a-z]' '[A-Z]'`_PROTO"
|
||||
changequote([, ])dnl
|
||||
|
||||
define([foo], [NEED_]translit($3, [a-z], [A-Z])[_PROTO])
|
||||
: << END
|
||||
@@@syms="$syms foo"@@@
|
||||
END
|
||||
undefine([foo])
|
||||
|
||||
AC_MSG_RESULT($ac_cv_func_$3_proto)
|
||||
if eval "test \"\$ac_cv_func_$3_proto\" = yes"; then
|
||||
AC_DEFINE_UNQUOTED($ac_tr_func)
|
||||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl Specific tests
|
||||
dnl
|
||||
|
||||
dnl
|
||||
dnl We prefer byacc or yacc because they do not use `alloca'
|
||||
dnl
|
||||
|
||||
AC_DEFUN(AC_KRB_PROG_YACC,
|
||||
[AC_CHECK_PROGS(YACC, byacc yacc 'bison -y')])
|
||||
|
||||
dnl
|
||||
dnl NEXTSTEP is not posix compliant by default,
|
||||
dnl you need a switch -posix to the compiler
|
||||
dnl
|
||||
|
||||
AC_DEFUN(AC_KRB_SYS_NEXTSTEP, [
|
||||
AC_MSG_CHECKING(for NEXTSTEP)
|
||||
AC_CACHE_VAL(krb_cv_sys_nextstep,
|
||||
AC_EGREP_CPP(yes,
|
||||
[#ifdef NeXT
|
||||
yes
|
||||
#endif
|
||||
], krb_cv_sys_nextstep=yes, krb_cv_sys_nextstep=no) )
|
||||
if test "$krb_cv_sys_nextstep" = "yes"; then
|
||||
CFLAGS="$CFLAGS -posix"
|
||||
LIBS="$LIBS -posix"
|
||||
fi
|
||||
AC_MSG_RESULT($krb_cv_sys_nextstep)
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl AIX have a very different syscall convention
|
||||
dnl
|
||||
AC_DEFUN(AC_KRB_SYS_AIX, [
|
||||
AC_MSG_CHECKING(for AIX)
|
||||
AC_CACHE_VAL(krb_cv_sys_aix,
|
||||
AC_EGREP_CPP(yes,
|
||||
[#ifdef _AIX
|
||||
yes
|
||||
#endif
|
||||
], krb_cv_sys_aix=yes, krb_cv_sys_aix=no) )
|
||||
AC_MSG_RESULT($krb_cv_sys_aix)
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl test for broken getcwd in (SunOS braindamage)
|
||||
dnl
|
||||
|
||||
AC_DEFUN(AC_KRB_FUNC_GETCWD_BROKEN, [
|
||||
if test "$ac_cv_func_getcwd" = yes; then
|
||||
AC_MSG_CHECKING(if getcwd is broken)
|
||||
AC_CACHE_VAL(ac_cv_func_getcwd_broken, [
|
||||
ac_cv_func_getcwd_broken=no
|
||||
|
||||
AC_TRY_RUN([
|
||||
#include <errno.h>
|
||||
char *getcwd(char*, int);
|
||||
|
||||
void *popen(char *cmd, char *mode)
|
||||
{
|
||||
errno = ENOTTY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char *ret;
|
||||
ret = getcwd(0, 1024);
|
||||
if(ret == 0 && errno == ENOTTY)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
], ac_cv_func_getcwd_broken=yes,:,:)
|
||||
])
|
||||
if test "$ac_cv_func_getcwd_broken" = yes; then
|
||||
AC_DEFINE(BROKEN_GETCWD, 1)dnl
|
||||
LIBOBJS="$LIBOBJS getcwd.o"
|
||||
AC_SUBST(LIBOBJS)dnl
|
||||
AC_MSG_RESULT($ac_cv_func_getcwd_broken)
|
||||
else
|
||||
AC_MSG_RESULT([seems ok])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN(AC_HAVE_PRAGMA_WEAK, [
|
||||
if test "${with_shared}" = "yes"; then
|
||||
AC_MSG_CHECKING(for pragma weak)
|
||||
AC_CACHE_VAL(ac_have_pragma_weak, [
|
||||
ac_have_pragma_weak=no
|
||||
cat > conftest_foo.$ac_ext <<'EOF'
|
||||
[#]line __oline__ "configure"
|
||||
#include "confdefs.h"
|
||||
#pragma weak foo = _foo
|
||||
int _foo = 17;
|
||||
EOF
|
||||
cat > conftest_bar.$ac_ext <<'EOF'
|
||||
[#]line __oline__ "configure"
|
||||
#include "confdefs.h"
|
||||
extern int foo;
|
||||
|
||||
int t() {
|
||||
return foo;
|
||||
}
|
||||
|
||||
int main() {
|
||||
return t();
|
||||
}
|
||||
EOF
|
||||
if AC_TRY_EVAL('CC $CFLAGS $CPPFLAGS $LDFLAGS conftest_foo.$ac_ext conftest_bar.$ac_ext -o conftest'); then
|
||||
ac_have_pragma_weak=yes
|
||||
fi
|
||||
rm -rf conftest*
|
||||
if test "$ac_have_pragma_weak" = "yes"; then
|
||||
AC_DEFINE(HAVE_PRAGMA_WEAK, 1)dnl
|
||||
fi
|
||||
AC_MSG_RESULT($ac_have_pragma_weak)
|
||||
fi
|
||||
])
|
||||
])
|
65
asn1/Makefile.in
Normal file
65
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
asn1/der.h
Normal file
41
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
asn1/der_get.c
Normal file
239
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
asn1/der_put.c
Normal file
213
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
asn1/gen.c
Normal file
535
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
asn1/gen.h
Normal file
11
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
asn1/hash.c
Normal file
181
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
asn1/hash.h
Normal file
54
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
asn1/k5.asn1
Normal file
328
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
asn1/lex.h
Normal file
3
asn1/lex.h
Normal file
@@ -0,0 +1,3 @@
|
||||
/* $Id$ */
|
||||
|
||||
void error_message (char *, ...);
|
56
asn1/lex.l
Normal file
56
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
asn1/main.c
Normal file
31
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
asn1/parse.y
Normal file
179
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
asn1/symbol.c
Normal file
64
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
asn1/symbol.h
Normal file
49
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
|
31
configure.in
Normal file
31
configure.in
Normal file
@@ -0,0 +1,31 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_REVISION($Revision$)
|
||||
AC_INIT(send_to_kdc.c)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
dnl AC_KRB_PROG_YACC
|
||||
AC_PROG_YACC
|
||||
AC_PROG_LEX
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h sys/time.h unistd.h)
|
||||
AC_CHECK_HEADERS(sys/bitypes.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS(gethostname mktime select socket strdup strstr)
|
||||
|
||||
AC_OUTPUT(Makefile asn1/Makefile)
|
1855
doc/layman.asc
Normal file
1855
doc/layman.asc
Normal file
File diff suppressed because it is too large
Load Diff
6275
doc/rfc1510.txt
Normal file
6275
doc/rfc1510.txt
Normal file
File diff suppressed because it is too large
Load Diff
6275
doc/standardisation/rfc1510.txt
Normal file
6275
doc/standardisation/rfc1510.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
205
get_in_tkt.c
205
get_in_tkt.c
@@ -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;
|
||||
|
238
install-sh
Executable file
238
install-sh
Executable file
@@ -0,0 +1,238 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
#
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
tranformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
13
krb5.h
13
krb5.h
@@ -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);
|
||||
|
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