rxgk-import-20040808
authorLove Hörnquist-Åstrand <lha@stacken.kth.se>
Sun, 8 Aug 2004 20:21:33 +0000 (20:21 +0000)
committerDerrick Brashear <shadow@dementia.org>
Sun, 8 Aug 2004 20:21:33 +0000 (20:21 +0000)
not actually hooked in yet, but getting it in so we can work with it.

17 files changed:
src/rxgk/Makefile.am [new file with mode: 0644]
src/rxgk/Makefile.in [new file with mode: 0644]
src/rxgk/README [new file with mode: 0644]
src/rxgk/rxgk.h [new file with mode: 0644]
src/rxgk/rxgk_clnt.c [new file with mode: 0644]
src/rxgk/rxgk_common.c [new file with mode: 0644]
src/rxgk/rxgk_crkrb.c [new file with mode: 0644]
src/rxgk/rxgk_crlha.c [new file with mode: 0644]
src/rxgk/rxgk_crpc.c [new file with mode: 0644]
src/rxgk/rxgk_info.c [new file with mode: 0644]
src/rxgk/rxgk_locl.h [new file with mode: 0644]
src/rxgk/rxgk_proto.xg [new file with mode: 0644]
src/rxgk/rxgk_serv.c [new file with mode: 0644]
src/rxgk/rxgk_srpc.c [new file with mode: 0644]
src/rxgk/test.xg [new file with mode: 0644]
src/rxgk/test_client.c [new file with mode: 0644]
src/rxgk/test_server.c [new file with mode: 0644]

diff --git a/src/rxgk/Makefile.am b/src/rxgk/Makefile.am
new file mode 100644 (file)
index 0000000..f37753c
--- /dev/null
@@ -0,0 +1,80 @@
+#
+# $Id$
+#
+
+include $(top_srcdir)/Makefile.am.common
+
+noinst_LTLIBRARIES = librxgkclient.la librxgkserver.la
+
+noinst_PROGRAMS = test_client test_server
+
+INCLUDES += -I.                        \
+       -I$(srcdir)                     \
+       -I../include                    \
+       -I$(srcdir)/../include          \
+       -I.. -I$(srcdir)/..             \
+       $(INC_roken)                    \
+       $(KRB5_INC_FLAGS)
+
+librxgkclient_la_SOURCES =             \
+       rxgk_locl.h                     \
+       rxgk_proto.h                    \
+       rxgk_clnt.c                     \
+       rxgk_info.c                     \
+       rxgk_crpc.c                     \
+       rxgk_crkrb.c                    \
+       rxgk_common.c                   \
+       rxgk_proto.ydr.c                \
+       rxgk_proto.cs.c
+
+librxgkserver_la_SOURCES =             \
+       rxgk_locl.h                     \
+       rxgk_proto.h                    \
+       rxgk_serv.c                     \
+       rxgk_info.c                     \
+       rxgk_srpc.c                     \
+       rxgk_crkrb.c                    \
+       rxgk_common.c                   \
+       rxgk_proto.ydr.c                \
+       rxgk_proto.ss.c
+
+LIBYDR =                               \
+       rxgk_proto.cs.c                 \
+       rxgk_proto.ss.c                 \
+       rxgk_proto.ydr.c                \
+       rxgk_proto.h                    \
+       rxgk_proto.cs.h                 \
+       rxgk_proto.ss.h
+
+LIBTYDR =                              \
+       test.cs.h                       \
+       test.ss.h                       \
+       test.ss.c                       \
+       test.cs.c                       \
+       test.ydr.c                      \
+       test.h
+
+common_LDADD = \
+       ../rx/librx.la \
+       -L../lwp -llwp $(PLWP_LIB_FLAGS) \
+       $(KRB5_LIB_FLAGS)
+
+test_client_SOURCES = test_client.c test.cs.c
+test_server_SOURCES = test_server.c test.ss.c
+
+test_client_LDADD = librxgkclient.la $(common_LDADD)
+test_server_LDADD = librxgkserver.la $(common_LDADD)
+
+$(librxgkclient_la_OBJECTS) $(librxgkserver_la_OBJECTS): $(LIBYDR)
+
+$(test_server_OBJECTS) $(test_client_OBJECTS): $(LIBTYDR)
+
+$(LIBYDR): rxgk_proto.xg
+       ../ydr/ydr $(srcdir)/rxgk_proto.xg
+
+$(LIBTYDR): test.xg
+       ../ydr/ydr $(srcdir)/test.xg
+
+CLEANFILES = $(LIBYDR) $(LIBTYDR)
+
+LDADD = $(KRB5_LIB_FLAGS)
diff --git a/src/rxgk/Makefile.in b/src/rxgk/Makefile.in
new file mode 100644 (file)
index 0000000..f2169d4
--- /dev/null
@@ -0,0 +1,933 @@
+# Makefile.in generated by automake 1.8.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# $Id$
+#
+
+# $Id$
+
+# $Id$
+
+
+SOURCES = $(librxgkclient_la_SOURCES) $(librxgkserver_la_SOURCES) $(test_client_SOURCES) $(test_server_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+       $(top_srcdir)/Makefile.am.common \
+       $(top_srcdir)/cf/Makefile.am.common
+noinst_PROGRAMS = test_client$(EXEEXT) test_server$(EXEEXT)
+subdir = rxgk
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/cf/__extentions__.m4 \
+       $(top_srcdir)/cf/arla-canonical.m4 \
+       $(top_srcdir)/cf/arla-openssl-compat.m4 \
+       $(top_srcdir)/cf/broken-getaddrinfo.m4 \
+       $(top_srcdir)/cf/broken-getnameinfo.m4 \
+       $(top_srcdir)/cf/broken-glob.m4 \
+       $(top_srcdir)/cf/broken-realloc.m4 \
+       $(top_srcdir)/cf/broken-snprintf.m4 $(top_srcdir)/cf/broken.m4 \
+       $(top_srcdir)/cf/broken2.m4 \
+       $(top_srcdir)/cf/bsd-func-lockmgr.m4 \
+       $(top_srcdir)/cf/bsd-func-lockstatus.m4 \
+       $(top_srcdir)/cf/bsd-func-selrecord.m4 \
+       $(top_srcdir)/cf/bsd-func-suser.m4 \
+       $(top_srcdir)/cf/bsd-func-vfs-getnewfsid.m4 \
+       $(top_srcdir)/cf/bsd-header-vnode-if-h.m4 \
+       $(top_srcdir)/cf/bsd-uvm-only.m4 \
+       $(top_srcdir)/cf/bsd-vfs-busy.m4 \
+       $(top_srcdir)/cf/bsd-vfs-object-create.m4 \
+       $(top_srcdir)/cf/bsd-vget.m4 $(top_srcdir)/cf/bsd-vop-lock.m4 \
+       $(top_srcdir)/cf/c-attribute.m4 $(top_srcdir)/cf/c-function.m4 \
+       $(top_srcdir)/cf/check-declaration.m4 \
+       $(top_srcdir)/cf/check-dirsiz.m4 \
+       $(top_srcdir)/cf/check-glibc.m4 $(top_srcdir)/cf/check-kafs.m4 \
+       $(top_srcdir)/cf/check-kerberos.m4 \
+       $(top_srcdir)/cf/check-kernel-func.m4 \
+       $(top_srcdir)/cf/check-kernel-funcs.m4 \
+       $(top_srcdir)/cf/check-kernel-var.m4 \
+       $(top_srcdir)/cf/check-kernel-vop-t.m4 \
+       $(top_srcdir)/cf/check-kernel.m4 $(top_srcdir)/cf/check-lfs.m4 \
+       $(top_srcdir)/cf/check-man.m4 \
+       $(top_srcdir)/cf/check-netinet-ip-and-tcp.m4 \
+       $(top_srcdir)/cf/check-roken.m4 $(top_srcdir)/cf/check-sl.m4 \
+       $(top_srcdir)/cf/check-var.m4 $(top_srcdir)/cf/check-x.m4 \
+       $(top_srcdir)/cf/db.m4 $(top_srcdir)/cf/elf-object-format.m4 \
+       $(top_srcdir)/cf/find-func-no-libs.m4 \
+       $(top_srcdir)/cf/find-func-no-libs2.m4 \
+       $(top_srcdir)/cf/find-func.m4 \
+       $(top_srcdir)/cf/find-if-not-broken.m4 \
+       $(top_srcdir)/cf/func-ntohl.m4 \
+       $(top_srcdir)/cf/have-kernel-struct-field.m4 \
+       $(top_srcdir)/cf/have-linux-kernel-type.m4 \
+       $(top_srcdir)/cf/have-linux-kernel-types.m4 \
+       $(top_srcdir)/cf/have-struct-field.m4 \
+       $(top_srcdir)/cf/have-type.m4 $(top_srcdir)/cf/have-types.m4 \
+       $(top_srcdir)/cf/header-dirent-dir-h.m4 \
+       $(top_srcdir)/cf/kafs-settoken-rxkad.m4 \
+       $(top_srcdir)/cf/kernel-have-def.m4 \
+       $(top_srcdir)/cf/kernel-need-proto.m4 \
+       $(top_srcdir)/cf/kernel.m4 $(top_srcdir)/cf/krb-bigendian.m4 \
+       $(top_srcdir)/cf/krb-func-getlogin.m4 \
+       $(top_srcdir)/cf/krb-ipv6.m4 \
+       $(top_srcdir)/cf/krb-struct-spwd.m4 \
+       $(top_srcdir)/cf/krb-struct-winsize.m4 \
+       $(top_srcdir)/cf/krb-sys-aix.m4 \
+       $(top_srcdir)/cf/krb-version.m4 \
+       $(top_srcdir)/cf/linux-func-init-mutex.m4 \
+       $(top_srcdir)/cf/linux-getattr-three-args.m4 \
+       $(top_srcdir)/cf/mips-abi.m4 $(top_srcdir)/cf/misc.m4 \
+       $(top_srcdir)/cf/need-proto.m4 \
+       $(top_srcdir)/cf/osf-func-ubc-lookup.m4 \
+       $(top_srcdir)/cf/osf-func-vfs-name-hash.m4 \
+       $(top_srcdir)/cf/prog-cc-flags.m4 \
+       $(top_srcdir)/cf/proto-compat.m4 \
+       $(top_srcdir)/cf/retsigtype.m4 $(top_srcdir)/cf/roken-frag.m4 \
+       $(top_srcdir)/cf/subst-val.m4 $(top_srcdir)/cf/test-package.m4 \
+       $(top_srcdir)/cf/try-compile-kernel.m4 \
+       $(top_srcdir)/cf/try-cpp-kernel.m4 \
+       $(top_srcdir)/cf/type-iovec.m4 $(top_srcdir)/cf/type-msghdr.m4 \
+       $(top_srcdir)/cf/werror.m4 $(top_srcdir)/cf/wflags.m4 \
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+librxgkclient_la_LIBADD =
+am_librxgkclient_la_OBJECTS = rxgk_clnt.lo rxgk_info.lo rxgk_crpc.lo \
+       rxgk_crkrb.lo rxgk_common.lo rxgk_proto.ydr.lo \
+       rxgk_proto.cs.lo
+librxgkclient_la_OBJECTS = $(am_librxgkclient_la_OBJECTS)
+librxgkserver_la_LIBADD =
+am_librxgkserver_la_OBJECTS = rxgk_serv.lo rxgk_info.lo rxgk_srpc.lo \
+       rxgk_crkrb.lo rxgk_common.lo rxgk_proto.ydr.lo \
+       rxgk_proto.ss.lo
+librxgkserver_la_OBJECTS = $(am_librxgkserver_la_OBJECTS)
+PROGRAMS = $(noinst_PROGRAMS)
+am_test_client_OBJECTS = test_client.$(OBJEXT) test.cs.$(OBJEXT)
+test_client_OBJECTS = $(am_test_client_OBJECTS)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = ../rx/librx.la $(am__DEPENDENCIES_1) \
+       $(am__DEPENDENCIES_1)
+test_client_DEPENDENCIES = librxgkclient.la $(am__DEPENDENCIES_2)
+am_test_server_OBJECTS = test_server.$(OBJEXT) test.ss.$(OBJEXT)
+test_server_OBJECTS = $(am_test_server_OBJECTS)
+test_server_DEPENDENCIES = librxgkserver.la $(am__DEPENDENCIES_2)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include
+depcomp =
+am__depfiles_maybe =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(librxgkclient_la_SOURCES) $(librxgkserver_la_SOURCES) \
+       $(test_client_SOURCES) $(test_server_SOURCES)
+DIST_SOURCES = $(librxgkclient_la_SOURCES) $(librxgkserver_la_SOURCES) \
+       $(test_client_SOURCES) $(test_server_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AFS_EXTRA_DEFS = @AFS_EXTRA_DEFS@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AFS_EXTRA_LIBS = @AFS_EXTRA_LIBS@
+AFS_EXTRA_OBJS = @AFS_EXTRA_OBJS@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AMTAR = @AMTAR@
+AR = @AR@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+ARLA_CONF_HIGHBYTES = @ARLA_CONF_HIGHBYTES@
+ARLA_CONF_HIGHVNODES = @ARLA_CONF_HIGHVNODES@
+ARLA_CONF_LOWBYTES = @ARLA_CONF_LOWBYTES@
+ARLA_CONF_LOWVNODES = @ARLA_CONF_LOWVNODES@
+ARLA_KNFS = @ARLA_KNFS@
+ARLA_LOCAL_ROKEN_FALSE = @ARLA_LOCAL_ROKEN_FALSE@
+ARLA_LOCAL_ROKEN_TRUE = @ARLA_LOCAL_ROKEN_TRUE@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BSDMAKE = @BSDMAKE@
+BSD_WERROR = @BSD_WERROR@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CATMAN_FALSE = @CATMAN_FALSE@
+CATMAN_TRUE = @CATMAN_TRUE@
+CC = @CC@
+CFLAGS = @CFLAGS@
+COMERR_CPPFLAGS = @COMERR_CPPFLAGS@
+COM_APPLE_KERNEL_BSD = @COM_APPLE_KERNEL_BSD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBLIB = @DBLIB@
+DCE_FALSE = @DCE_FALSE@
+DCE_TRUE = @DCE_TRUE@
+DEFS = @DEFS@
+DEPEND_sl = @DEPEND_sl@
+DIR_roken = @DIR_roken@
+DIR_sl = @DIR_sl@
+DVI2PS = @DVI2PS@
+DVIPS = @DVIPS@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FBSD5_FALSE = @FBSD5_FALSE@
+FBSD5_TRUE = @FBSD5_TRUE@
+FFLAGS = @FFLAGS@
+FREEBSD_GENSETDEFS = @FREEBSD_GENSETDEFS@
+GCC = @GCC@
+GROFF = @GROFF@
+GUILE_GTK = @GUILE_GTK@
+HAVE_DB1_FALSE = @HAVE_DB1_FALSE@
+HAVE_DB1_TRUE = @HAVE_DB1_TRUE@
+HAVE_DB3_FALSE = @HAVE_DB3_FALSE@
+HAVE_DB3_TRUE = @HAVE_DB3_TRUE@
+HAVE_NDBM_FALSE = @HAVE_NDBM_FALSE@
+HAVE_NDBM_TRUE = @HAVE_NDBM_TRUE@
+INCLUDES_roken = @INCLUDES_roken@
+INCLUDE_readline = @INCLUDE_readline@
+INC_roken = @INC_roken@
+INC_sl = @INC_sl@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KAFS_CPPFLAGS = @KAFS_CPPFLAGS@
+KAFS_LIBS = @KAFS_LIBS@
+KERNEL_CC = @KERNEL_CC@
+KERNEL_CFLAGS = @KERNEL_CFLAGS@
+KERNEL_CPPFLAGS = @KERNEL_CPPFLAGS@
+KERNEL_HDRS = @KERNEL_HDRS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+KERNEL_LD = @KERNEL_LD@
+KERNEL_LD_FLAGS = @KERNEL_LD_FLAGS@
+KERNEL_SRCS = @KERNEL_SRCS@
+KRB4_FALSE = @KRB4_FALSE@
+KRB4_INC_DIR = @KRB4_INC_DIR@
+KRB4_INC_FLAGS = @KRB4_INC_FLAGS@
+KRB4_LIB_DIR = @KRB4_LIB_DIR@
+KRB4_LIB_FLAGS = @KRB4_LIB_FLAGS@
+KRB4_LIB_LIBS = @KRB4_LIB_LIBS@
+KRB4_TRUE = @KRB4_TRUE@
+KRB5_FALSE = @KRB5_FALSE@
+KRB5_INC_DIR = @KRB5_INC_DIR@
+KRB5_INC_FLAGS = @KRB5_INC_FLAGS@
+KRB5_LIB_DIR = @KRB5_LIB_DIR@
+KRB5_LIB_FLAGS = @KRB5_LIB_FLAGS@
+KRB5_LIB_LIBS = @KRB5_LIB_LIBS@
+KRB5_TRUE = @KRB5_TRUE@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_NDBM = @LIB_NDBM@
+LIB_bswap16 = @LIB_bswap16@
+LIB_bswap32 = @LIB_bswap32@
+LIB_crypt = @LIB_crypt@
+LIB_db_create = @LIB_db_create@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_freeaddrinfo = @LIB_freeaddrinfo@
+LIB_gai_strerror = @LIB_gai_strerror@
+LIB_getaddrinfo = @LIB_getaddrinfo@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_gethostbyname2 = @LIB_gethostbyname2@
+LIB_getnameinfo = @LIB_getnameinfo@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_hstrerror = @LIB_hstrerror@
+LIB_pidfile = @LIB_pidfile@
+LIB_pthread_create = @LIB_pthread_create@
+LIB_readline = @LIB_readline@
+LIB_res_init = @LIB_res_init@
+LIB_res_nsearch = @LIB_res_nsearch@
+LIB_res_search = @LIB_res_search@
+LIB_roken = @LIB_roken@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_sl = @LIB_sl@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+LINUX_IA64_FALSE = @LINUX_IA64_FALSE@
+LINUX_IA64_TRUE = @LINUX_IA64_TRUE@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWP_C = @LWP_C@
+LWP_H = @LWP_H@
+LWP_O = @LWP_O@
+LWP_PROCESS = @LWP_PROCESS@
+LWP_REDZONE_FALSE = @LWP_REDZONE_FALSE@
+LWP_REDZONE_TRUE = @LWP_REDZONE_TRUE@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN = @MAKE_X_PROGS_BIN@
+MILKO_ROOT = @MILKO_ROOT@
+MODLOAD = @MODLOAD@
+MODULE = @MODULE@
+MODUNLOAD = @MODUNLOAD@
+NNPFS_AFS_READDIR_FALSE = @NNPFS_AFS_READDIR_FALSE@
+NNPFS_AFS_READDIR_TRUE = @NNPFS_AFS_READDIR_TRUE@
+NNPFS_SRCS = @NNPFS_SRCS@
+NNPFS_SUBDIR = @NNPFS_SUBDIR@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+OSF1_FALSE = @OSF1_FALSE@
+OSF1_TRUE = @OSF1_TRUE@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLWP_INC_FLAGS = @PLWP_INC_FLAGS@
+PLWP_LIB_FLAGS = @PLWP_LIB_FLAGS@
+RANLIB = @RANLIB@
+ROKEN_H = @ROKEN_H@
+RXKAD_FALSE = @RXKAD_FALSE@
+RXKAD_LIBS = @RXKAD_LIBS@
+RXKAD_TRUE = @RXKAD_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SL_H = @SL_H@
+STRIP = @STRIP@
+SYMORDER = @SYMORDER@
+SYS = @SYS@
+TEXI2DVI = @TEXI2DVI@
+TEXI2HTML = @TEXI2HTML@
+TEXI2PDF = @TEXI2PDF@
+VERSION = @VERSION@
+VNODE_IF_H = @VNODE_IF_H@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+YACC = @YACC@
+YDR_CPPFLAGS = @YDR_CPPFLAGS@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_cv_prog_getconf = @ac_cv_prog_getconf@
+am__leading_dot = @am__leading_dot@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+chmod = @chmod@
+datadir = @datadir@
+do_roken_rename_FALSE = @do_roken_rename_FALSE@
+do_roken_rename_TRUE = @do_roken_rename_TRUE@
+editline_OBJS = @editline_OBJS@
+editline_dir = @editline_dir@
+exec_prefix = @exec_prefix@
+have_err_h_FALSE = @have_err_h_FALSE@
+have_err_h_TRUE = @have_err_h_TRUE@
+have_fnmatch_h_FALSE = @have_fnmatch_h_FALSE@
+have_fnmatch_h_TRUE = @have_fnmatch_h_TRUE@
+have_glob_h_FALSE = @have_glob_h_FALSE@
+have_glob_h_TRUE = @have_glob_h_TRUE@
+have_ifaddrs_h_FALSE = @have_ifaddrs_h_FALSE@
+have_ifaddrs_h_TRUE = @have_ifaddrs_h_TRUE@
+have_vis_h_FALSE = @have_vis_h_FALSE@
+have_vis_h_TRUE = @have_vis_h_TRUE@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+SUFFIXES = .et .h .x .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+INCLUDES = -I$(top_builddir)/include $(INCLUDES_roken) $(INC_roken) -I.                        \
+       -I$(srcdir)                     \
+       -I../include                    \
+       -I$(srcdir)/../include          \
+       -I.. -I$(srcdir)/..             \
+       $(INC_roken)                    \
+       $(KRB5_INC_FLAGS)
+
+@do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME
+AM_CFLAGS = $(WFLAGS)
+CP = cp
+buildinclude = $(top_builddir)/include
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_dlopen = @LIB_dlopen@
+LIB_getattr = @LIB_getattr@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_openpty = @LIB_openpty@
+LIB_setpcred = @LIB_setpcred@
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+INCLUDE_openldap = @INCLUDE_openldap@
+LIB_openldap = @LIB_openldap@
+NROFF_MAN = groff -mandoc -Tascii
+CHECK_LOCAL = $(PROGRAMS)
+noinst_LTLIBRARIES = librxgkclient.la librxgkserver.la
+librxgkclient_la_SOURCES = \
+       rxgk_locl.h                     \
+       rxgk_proto.h                    \
+       rxgk_clnt.c                     \
+       rxgk_info.c                     \
+       rxgk_crpc.c                     \
+       rxgk_crkrb.c                    \
+       rxgk_common.c                   \
+       rxgk_proto.ydr.c                \
+       rxgk_proto.cs.c
+
+librxgkserver_la_SOURCES = \
+       rxgk_locl.h                     \
+       rxgk_proto.h                    \
+       rxgk_serv.c                     \
+       rxgk_info.c                     \
+       rxgk_srpc.c                     \
+       rxgk_crkrb.c                    \
+       rxgk_common.c                   \
+       rxgk_proto.ydr.c                \
+       rxgk_proto.ss.c
+
+LIBYDR = \
+       rxgk_proto.cs.c                 \
+       rxgk_proto.ss.c                 \
+       rxgk_proto.ydr.c                \
+       rxgk_proto.h                    \
+       rxgk_proto.cs.h                 \
+       rxgk_proto.ss.h
+
+LIBTYDR = \
+       test.cs.h                       \
+       test.ss.h                       \
+       test.ss.c                       \
+       test.cs.c                       \
+       test.ydr.c                      \
+       test.h
+
+common_LDADD = \
+       ../rx/librx.la \
+       -L../lwp -llwp $(PLWP_LIB_FLAGS) \
+       $(KRB5_LIB_FLAGS)
+
+test_client_SOURCES = test_client.c test.cs.c
+test_server_SOURCES = test_server.c test.ss.c
+test_client_LDADD = librxgkclient.la $(common_LDADD)
+test_server_LDADD = librxgkserver.la $(common_LDADD)
+CLEANFILES = $(LIBYDR) $(LIBTYDR)
+LDADD = $(KRB5_LIB_FLAGS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .et .h .x .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  --ignore-deps rxgk/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --foreign  --ignore-deps rxgk/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test "$$dir" = "$$p" && dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
+librxgkclient.la: $(librxgkclient_la_OBJECTS) $(librxgkclient_la_DEPENDENCIES) 
+       $(LINK)  $(librxgkclient_la_LDFLAGS) $(librxgkclient_la_OBJECTS) $(librxgkclient_la_LIBADD) $(LIBS)
+librxgkserver.la: $(librxgkserver_la_OBJECTS) $(librxgkserver_la_DEPENDENCIES) 
+       $(LINK)  $(librxgkserver_la_LDFLAGS) $(librxgkserver_la_OBJECTS) $(librxgkserver_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+       @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+test_client$(EXEEXT): $(test_client_OBJECTS) $(test_client_DEPENDENCIES) 
+       @rm -f test_client$(EXEEXT)
+       $(LINK) $(test_client_LDFLAGS) $(test_client_OBJECTS) $(test_client_LDADD) $(LIBS)
+test_server$(EXEEXT): $(test_server_OBJECTS) $(test_server_DEPENDENCIES) 
+       @rm -f test_server$(EXEEXT)
+       $(LINK) $(test_server_LDFLAGS) $(test_server_OBJECTS) $(test_server_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+.c.o:
+       $(COMPILE) -c $<
+
+.c.obj:
+       $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+       $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       $(mkdir_p) $(distdir)/.. $(distdir)/../cf
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       $(MAKE) $(AM_MAKEFLAGS) \
+         top_distdir="$(top_distdir)" distdir="$(distdir)" \
+         dist-hook
+check-am: all-am
+       $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) all-local
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+       clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local
+
+install-exec-am:
+       @$(NORMAL_INSTALL)
+       $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \
+       clean clean-generic clean-libtool clean-noinstLTLIBRARIES \
+       clean-noinstPROGRAMS ctags distclean distclean-compile \
+       distclean-generic distclean-libtool distclean-tags distdir dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-data-local install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags uninstall uninstall-am \
+       uninstall-info-am
+
+
+install-suid-programs:
+       @foo='$(bin_SUIDS)'; \
+       for file in $$foo; do \
+       x=$(DESTDIR)$(bindir)/$$file; \
+       if chown 0:0 $$x && chmod u+s $$x; then :; else \
+       echo "*"; \
+       echo "* Failed to install $$x setuid root"; \
+       echo "*"; \
+       fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+       @foo='$(include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ)'; \
+       for f in $$foo; do \
+               f=`basename $$f`; \
+               if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+               else file="$$f"; fi; \
+               if cmp -s  $$file $(buildinclude)/$$f 2> /dev/null ; then \
+               : ; else \
+                       echo " $(CP) $$file $(buildinclude)/$$f"; \
+                       $(CP) $$file $(buildinclude)/$$f; \
+               fi ; \
+       done
+
+all-local: install-build-headers
+
+check-local::
+       @if test '$(CHECK_LOCAL)'; then \
+         foo='$(CHECK_LOCAL)'; else \
+         foo='$(PROGRAMS)'; fi; \
+         if test "$$foo"; then \
+         failed=0; all=0; \
+         for i in $$foo; do \
+           all=`expr $$all + 1`; \
+           if ./$$i --version > /dev/null 2>&1; then \
+             echo "PASS: $$i"; \
+           else \
+             echo "FAIL: $$i"; \
+             failed=`expr $$failed + 1`; \
+           fi; \
+         done; \
+         if test "$$failed" -eq 0; then \
+           banner="All $$all tests passed"; \
+         else \
+           banner="$$failed of $$all tests failed"; \
+         fi; \
+         dashes=`echo "$$banner" | sed s/./=/g`; \
+         echo "$$dashes"; \
+         echo "$$banner"; \
+         echo "$$dashes"; \
+         test "$$failed" -eq 0; \
+       fi
+
+.x.c:
+       @cmp -s $< $@ 2> /dev/null || cp $< $@
+#NROFF_MAN = nroff -man
+.1.cat1:
+       $(NROFF_MAN) $< > $@
+.3.cat3:
+       $(NROFF_MAN) $< > $@
+.5.cat5:
+       $(NROFF_MAN) $< > $@
+.8.cat8:
+       $(NROFF_MAN) $< > $@
+
+dist-cat1-mans:
+       @foo='$(man1_MANS)'; \
+       bar='$(man_MANS)'; \
+       for i in $$bar; do \
+       case $$i in \
+       *.1) foo="$$foo $$i";; \
+       esac; done ;\
+       for i in $$foo; do \
+               x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
+               echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+               $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+       done
+
+dist-cat3-mans:
+       @foo='$(man3_MANS)'; \
+       bar='$(man_MANS)'; \
+       for i in $$bar; do \
+       case $$i in \
+       *.3) foo="$$foo $$i";; \
+       esac; done ;\
+       for i in $$foo; do \
+               x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
+               echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+               $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+       done
+
+dist-cat5-mans:
+       @foo='$(man5_MANS)'; \
+       bar='$(man_MANS)'; \
+       for i in $$bar; do \
+       case $$i in \
+       *.5) foo="$$foo $$i";; \
+       esac; done ;\
+       for i in $$foo; do \
+               x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
+               echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+               $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+       done
+
+dist-cat8-mans:
+       @foo='$(man8_MANS)'; \
+       bar='$(man_MANS)'; \
+       for i in $$bar; do \
+       case $$i in \
+       *.8) foo="$$foo $$i";; \
+       esac; done ;\
+       for i in $$foo; do \
+               x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
+               echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
+               $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
+       done
+
+dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
+
+install-cat-mans: install-man
+       $(SHELL) $(top_srcdir)/cf/install-catman.sh "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS)
+
+install-data-local: install-cat-mans
+
+.et.h:
+       $(COMPILE_ET) $<
+.et.c:
+       $(COMPILE_ET) $<
+
+.x.c:
+       @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+       @foo='$(CHECK_LOCAL)'; \
+         if test "$$foo"; then \
+         failed=0; all=0; \
+         for i in $$foo; do \
+           all=`expr $$all + 1`; \
+           if ./$$i --version > /dev/null 2>&1; then \
+             echo "PASS: $$i"; \
+           else \
+             echo "FAIL: $$i"; \
+             failed=`expr $$failed + 1`; \
+           fi; \
+         done; \
+         if test "$$failed" -eq 0; then \
+           banner="All $$all tests passed"; \
+         else \
+           banner="$$failed of $$all tests failed"; \
+         fi; \
+         dashes=`echo "$$banner" | sed s/./=/g`; \
+         echo "$$dashes"; \
+         echo "$$banner"; \
+         echo "$$dashes"; \
+         test "$$failed" -eq 0; \
+       fi
+
+$(librxgkclient_la_OBJECTS) $(librxgkserver_la_OBJECTS): $(LIBYDR)
+
+$(test_server_OBJECTS) $(test_client_OBJECTS): $(LIBTYDR)
+
+$(LIBYDR): rxgk_proto.xg
+       ../ydr/ydr $(srcdir)/rxgk_proto.xg
+
+$(LIBTYDR): test.xg
+       ../ydr/ydr $(srcdir)/test.xg
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/rxgk/README b/src/rxgk/README
new file mode 100644 (file)
index 0000000..e075edb
--- /dev/null
@@ -0,0 +1,225 @@
+$Id$
+
+Overview
+========
+
+- RX crypto class
+
+       rxgk is a new crypto class, mostly since the interface need to
+       be changed in the ktc for openafs anyway (at least binary
+       interface).
+
+       rxgk (krb5) can be used when the kdc returns a non des enctype.
+
+- Layers
+
+       There are two layer, the transport layer that is authentiation
+       mechamism independent, and the authentiation layer.
+
+       The glue between the authentiation layer and the transport
+       layer is the RXGK authenticator.
+
+- RXGK authenticator
+
+       The only reson for the RXGK authenticator exists is that there
+       are not fragmentation in the Challange/Response protocol in
+       Rx. This limits the authentization in Rx to MTU sized packages.
+
+- RXGK authenticator lifetime
+
+       The server has a local key that is used to encrypt the gk
+       authenticators. The local key is semi stateful, the
+       server need to remember the old keys al long as there are
+       valid RXGK authenticators held by any client. New RXGK
+       authenticators can be fetched at any time but might require
+       user input.
+
+- Getting RXGK authenticator
+
+       the authenticator is fetched using a service rx_null on the
+       same port as the server the client wants to talk too.
+
+transport layer
+===============
+
+- Key derivation
+
+       Each connection get separate key for each connection/epoch.
+       Each direction get a separate key for each direction.
+
+       S = Session key
+       CN = connection key
+       counter = key generation (nonce)
+       K{server} = Key from server direction
+       K{client} = Key from client direction
+
+       X{cn} = epoch{32} | cid{32} | key_counter{64}
+       
+       CN = random-to-key(pseudo-random(S, X{cn})
+
+       K{server} = KD(CN, 0)   { key used on data from server }
+       K{client} = KD(CN, 1)   { key used on data from client }
+
+       Checksum field in the header (spare1) is always set to the
+       lower 4 bits of the key_counter field. Ie server may not
+       request rekeying faster the (4 * rc_max_seq_skew) packets.
+
+       K depends on {S,epoch,cid,key_counter}
+
+- Rekeying 
+
+       Rekeing is needed since kcrypt assumes that data isn't
+       encrypted for the 2**48 messages with the same key.
+
+- Challenge/Response
+
+       When the client is unknown to the server it sends a challenge
+       with opcode RXKG_OPCODE_CHALLENGE (nonce).
+
+       The client the send back a rxgk authenticator and the
+       encrypted nounce.
+
+- Wire protocol
+
+       crypt mode
+
+       Each packet are encrypted as [KCRYPTO] specifies. The data is
+       prefixed with parts of the rx header that matter.
+
+       auth mode
+
+       Each packet are checksumed as [KCRYPTO] specifies. The data is
+       prefixed with parts of the rx header that matter [4]. In auth
+       mode the rx header subsitute is not sent over write to save
+       space.
+
+       The part of the header that is checksumed are these fields:
+
+               uint32_t callid
+               uint32_t seqno
+               uint32_t serialno
+               uint8_t  userstatus
+               uint8_t  someflags (RX_PRESET_FLAGS)
+               uint8_t  serviceid
+
+Authentication RPCs
+===================
+
+- Information RPCs
+
+       To be later specified.
+
+       There is an information API to, with a RXGK authenticator, the
+       client can verify what authentiation mechamisms is supported,
+       both insecure and authenticated.
+
+- Kerberos 5 to rxgk authenticator RPCs
+
+       key{KerbS} - kerberos session subkey key
+
+       The mutual auth data in the RXGK_EstablishKrb5Context is
+       encrypted with the key{KerbS} key.
+
+       Client sends acceptable enctypes and nonce to the server in
+       challenge.
+
+       Server sends back key(auth-cred-key) and nonce + 1 to the 
+       client together with a RXGK authenticator cred encrypted with
+       key{KerbS}.
+
+       auth-cred is protected by key{gkkey}
+
+       key{S} = key{auth-cred-key}
+
+- GSS-API to rxgk authenticator RPCs
+
+       To be later specified.
+
+========
+
+Code assumptions:
+
+       L.NXS.SE realm
+
+       gkkey@L.NXS.SE and afs@L.NXS.SE key exists in default keytab
+
+========
+implementation/higher level issues
+
+
+- RXGK_AUTH_CRED needs checking
+       
+       [ 2. should we use the session key or the a random octet
+       string generatated by the server, the key(auth-cred-key) below ]
+
+       [ 3. ac_principal: gss exported name ? this to make it idependant
+       of kerberos 5. Problem with gss name only specifed gss-mechs
+       can be used. Server local so it can really be anything the
+       server wants it to be. Need to be kept short so it will fit on
+       one MTU. Also see {{10}}. ]
+
+       The RXGK authenticator is fetch by doing either the RXGK
+       GSSAPI rpc's or the RXGK_EstablishKrb5Context rpc to the RXGK
+       service on the same port as the service that rxgk
+       secures. Doing the RPC call gives you a gk authenticator and a
+       key(S) that is valid for one server. The input to GSSAPI rpc
+       and EstablishKrb5Context are mech specific.
+
+       GSS-API
+       [ 11. see rxgss how this should me implemented ... ]
+
+exported auth name
+
+       all mech's need to have a rxgk name to krb4 name function
+       until pts is changed to support rxgk names.
+
+       [ 10. Proposal: the protection interface have GKNAME to
+       AFS/PTS named RPCs.
+
+       In this proposal all names are mapped to one AFS username.
+
+       For example, gss exported named KRB5:lha@SU.SE, krb5 native
+       lha@SU.SE and krb5 native krb5 lha@KTH.SE all map to the same
+       afs username `lha'.
+
+
+       Also see {{3}}. ]
+
+
+TODO:
+
+- Auth mode
+
+- Pass length since krb encryption doesn't preserve length (some enctypes does)
+
+       [ 8. Is this really needed, packets are always send full ]
+
+- More tests
+
+       More the MTU since rpcs
+       Stored packets packets, compare generate packages
+       Check other checksum
+
+
+DEPRICATED IDEAS
+
+- Diffrent keys for fileservers
+
+       I think we should ignore this for rxgk/kerberos 5 or do
+       "fileserver groups" as discuss on Pittsburgh so this will
+       happen. For "fileserver groups" a get groups rpc should be
+       added to the vlserver (this will make non rx afslogs harder 
+       to implement) and in the first version we just insert a rpc
+       stub that return one name only, "default", or something
+       equally silly.
+
+       The reson you want to have diffrent keys for fileservers are
+
+       - increased security (more keys, less data encrypted with the
+         same key, one server compromised doesn't compromise all servers)
+
+       - give a fileserver to someone else that you not trust
+         to have the master key
+
+  Depricated since we can get consensus, rxgk/gssapi will/must solve
+  the problem.
diff --git a/src/rxgk/rxgk.h b/src/rxgk/rxgk.h
new file mode 100644 (file)
index 0000000..8b39863
--- /dev/null
@@ -0,0 +1,91 @@
+/* -*- C -*- */
+
+/*
+ * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef __RXGK_H
+#define __RXGK_H
+
+/* Is this really large enough for a krb5 ticket? */
+#define MAXKRB5TICKETLEN       1024
+
+typedef char rxgk_level;
+#define rxgk_auth 0            /* rxgk_clear + protected packet length */
+#define rxgk_crypt 1           /* rxgk_crypt + encrypt packet payload */
+
+int32_t
+rxgk_GetServerInfo(struct rx_connection *, rxgk_level *,
+                  uint32_t *, char *, size_t, char *, size_t, int32_t *);
+
+struct rx_securityClass *
+rxgk_NewServerSecurityObject (/*rxgk_level*/ int min_level,
+                             const char *princ,
+                             void *appl_data,
+                             int (*get_key)(void *data, const char *principal,
+                                            int enctype, int kvno, 
+                                            krb5_keyblock *key),
+                             int (*user_ok)(const char *name,
+                                            const char *realm,
+                                            int kvno),
+                             uint32_t serviceId);
+
+struct rx_securityClass *
+rxgk_k5_NewClientSecurityObject (/*rxgk_level*/ int level,
+                                krb5_keyblock *sessionkey,
+                                int32_t kvno,
+                                int ticketLen,
+                                void *ticket,
+                                uint32_t serviceId,
+                                krb5_context context);
+
+int
+rxgk_default_get_key(void *, const char *, int, int, krb5_keyblock *);
+
+/* XXX these are not com_err error, MAKE THIS com_err's */
+#define RXGKINCONSISTENCY      (19270400L)
+#define RXGKPACKETSHORT                (19270401L)
+#define RXGKLEVELFAIL          (19270402L)
+#define RXGKTICKETLEN          (19270403L)
+#define RXGKOUTOFSEQUENCE      (19270404L)
+#define RXGKNOAUTH             (19270405L)
+#define RXGKBADKEY             (19270406L)
+#define RXGKBADTICKET          (19270407L)
+#define RXGKUNKNOWNKEY         (19270408L)
+#define RXGKEXPIRED            (19270409L)
+#define RXGKSEALEDINCON                (19270410L)
+#define RXGKDATALEN            (19270411L)
+#define RXGKILLEGALLEVEL       (19270412L)
+
+#endif /* __RXGK_H */
diff --git a/src/rxgk/rxgk_clnt.c b/src/rxgk/rxgk_clnt.c
new file mode 100644 (file)
index 0000000..5bcb2ce
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "rxgk_locl.h"
+
+RCSID("$Id$");
+
+/* Security object specific client data */
+typedef struct rxgk_clnt_class {
+    struct rx_securityClass klass;
+    krb5_context context;
+    rxgk_level level;
+    krb5_keyblock krb_key;
+    key_stuff k;
+    int32_t kvno;
+    RXGK_Token ticket;
+    uint32_t serviceId;
+#if 0
+    RXGK_rxtransport_key contrib;
+#endif
+} rxgk_clnt_class;
+
+/* Per connection specific client data */
+typedef struct clnt_con_data {
+    RXGK_Token auth_token;
+    int32_t auth_token_kvno;
+    end_stuff e;
+} clnt_con_data;
+
+static
+int
+client_NewConnection(struct rx_securityClass *obj_, struct rx_connection *con)
+{
+    rxgk_clnt_class *obj = (rxgk_clnt_class *) obj_;
+    clnt_con_data *cdat;
+    int ret;
+    
+    assert(con->securityData == 0);
+    obj->klass.refCount++;
+    cdat = (clnt_con_data *) osi_Alloc(sizeof(clnt_con_data));
+    cdat->e.bytesReceived = cdat->e.packetsReceived = 0;
+    cdat->e.bytesSent = cdat->e.packetsSent = 0;
+    
+    con->securityData = (char *) cdat;
+    rx_nextCid += RX_MAXCALLS;
+    con->epoch = rx_epoch;
+    con->cid = rx_nextCid;
+    cdat->auth_token.len = 0;
+    cdat->auth_token.val = NULL;
+
+    ret = rxgk5_get_auth_token(obj->context,
+                              rx_HostOf(con->peer), rx_PortOf(con->peer),
+                              obj->serviceId,
+                              &obj->ticket, &cdat->auth_token, 
+                              &obj->krb_key, 
+                              &obj->k.ks_key,
+                              &cdat->auth_token_kvno);
+    if (ret) {
+       osi_Free(cdat, sizeof(clnt_con_data));
+       return ret;
+    }
+
+    /* XXX derive crypto key */
+
+    ret = krb5_crypto_init(obj->k.ks_context,
+                          &obj->k.ks_key, obj->k.ks_key.keytype,
+                          &obj->k.ks_crypto);
+    if (ret)
+       goto out;
+
+#if 0
+    obj->contrib.server_keycontribution.val = "";
+    obj->contrib.server_keycontribution.len = 0;
+
+    obj->contrib.client_keycontribution.len = rxgk_key_contrib_size;
+    obj->contrib.client_keycontribution.val = malloc(rxgk_key_contrib_size);
+    if (obj->contrib.client_keycontribution.val == NULL)
+       goto out;
+
+    {
+       int i;
+
+       for (i = 0; i < rxgk_key_contrib_size; i++)
+           obj->contrib.client_keycontribution.val[i] = arc4random(); /*XXX*/
+    }
+
+    ret = rxgk_derive_transport_key(obj->k.ks_context,
+                                   &obj->k.ks_key,
+                                   &obj->contrib,
+                                   &obj->k.ks_skey);
+    if (ret)
+       return ret;
+#endif
+
+    ret = krb5_crypto_init (obj->context, &obj->k.ks_skey,
+                           obj->k.ks_skey.keytype,
+                           &obj->k.ks_scrypto);
+    if (ret)
+       return ret;
+
+    ret = rxgk_set_conn(con, obj->k.ks_key.keytype, 
+                       obj->level == rxgk_crypt ? 1 : 0);
+
+ out:
+    if (ret) {
+       if (obj->k.ks_crypto)
+           krb5_crypto_destroy(obj->k.ks_context, obj->k.ks_crypto);
+       obj->k.ks_crypto = NULL;
+       krb5_free_keyblock_contents(obj->k.ks_context, &obj->k.ks_skey);
+       memset(&obj->k.ks_skey, 0, sizeof(obj->k.ks_skey));
+       osi_Free(cdat->auth_token.val, cdat->auth_token.len);
+       osi_Free(cdat, sizeof(clnt_con_data));
+       return ret;
+    }
+    
+    return 0;
+}
+
+static
+int
+client_Close(struct rx_securityClass *obj_)
+{
+    rxgk_clnt_class *obj = (rxgk_clnt_class *) obj_;
+    obj->klass.refCount--;
+    if (obj->klass.refCount <= 0)
+    {
+       osi_Free(obj->ticket.val, obj->ticket.len);
+       osi_Free(obj, sizeof(rxgk_clnt_class));
+    }
+    return 0;
+}
+
+static
+int
+client_DestroyConnection(struct rx_securityClass *obj,
+                        struct rx_connection *con)
+{
+    clnt_con_data *cdat = (clnt_con_data *)con->securityData;
+  
+    if (cdat)
+      osi_Free(cdat, sizeof(clnt_con_data));
+    return client_Close(obj);
+}
+
+/*
+ * Receive a challange and respond.
+ */
+static
+int
+client_GetResponse(const struct rx_securityClass *obj_,
+                  const struct rx_connection *con,
+                  struct rx_packet *pkt)
+{
+    rxgk_clnt_class *obj = (rxgk_clnt_class *) obj_;
+    clnt_con_data *cdat = (clnt_con_data *)con->securityData;
+    key_stuff *k = &obj->k;
+    struct RXGK_Challenge c;
+    struct RXGK_Response r;
+    struct RXGK_Response_Crypt rc;
+    char bufrc[RXGK_RESPONSE_CRYPT_SIZE];
+    char bufr[RXGK_RESPONSE_MAX_SIZE];
+    krb5_data data;
+    size_t len;
+    int ret;
+    char *p;
+    
+    memset(&r, 0, sizeof(r));
+    memset(&rc, 0, sizeof(rc));
+    
+    /* Get challenge */
+    if (rx_SlowReadPacket(pkt, 0, sizeof(c), &c) != sizeof(c))
+       return RXGKPACKETSHORT;
+    
+    if (ntohl(c.rc_version) != RXGK_VERSION)
+       return RXGKINCONSISTENCY;
+    
+    if (ntohl(c.rc_min_level) > obj->level)
+       return RXGKLEVELFAIL;
+    
+    if (c.rc_opcode == htonl(RXKG_OPCODE_CHALLENGE)) {
+       ;
+    } else if (c.rc_opcode == htonl(RXKG_OPCODE_REKEY)) {
+       /* XXX decode ydr_encode_RXGK_ReKey_Crypt info */
+       return RXGKINCONSISTENCY;
+#if 0
+       ret = rxgk_derive_transport_key(obj->k.ks_context,
+                                       &obj->k.ks_key,
+                                       &obj->contrib,
+                                       &obj->k.ks_skey);
+       if (ret)
+           return ret;
+       
+       ret = krb5_crypto_init (obj->context, &obj->k.ks_skey,
+                               obj->k.ks_skey.keytype,
+                               &obj->k.ks_scrypto);
+       if (ret)
+           return ret;
+#endif
+    } else
+       return RXGKINCONSISTENCY;
+    
+    rc.nonce = ntohl(c.rc_nonce) + 1;
+    rc.epoch = con->epoch;
+    rc.cid = con->cid & RX_CIDMASK;
+    rxi_GetCallNumberVector(con, rc.call_numbers);
+#if 0
+    rc.security_index = con->securityIndex;
+#endif
+    rc.level = obj->level;
+#if 0
+    rc.last_seq = 0; /* XXX */
+#endif
+    rc.key_version = 0;
+#if 0
+    rc.contrib = obj->contrib; /* XXX copy_RXGK_rxtransport_key */
+#endif
+    
+    {
+       int i;
+       for (i = 0; i < RX_MAXCALLS; i++) {
+           if (rc.call_numbers[i] < 0)
+               return RXGKINCONSISTENCY;
+       }
+    }
+    len = sizeof(bufrc);
+    p = ydr_encode_RXGK_Response_Crypt(&rc, bufrc, &len);
+    if (p == NULL)
+       return RXGKINCONSISTENCY;
+    len = sizeof(bufrc) - len;
+
+    ret = krb5_encrypt(obj->context, k->ks_crypto, 
+                      RXGK_CLIENT_ENC_CHALLENGE, bufrc, len, &data);
+    if (ret)
+       return ret;
+
+    r.rr_version = RXGK_VERSION;
+    r.rr_auth_token_kvno = cdat->auth_token_kvno;
+    r.rr_auth_token.val = cdat->auth_token.val;
+    r.rr_auth_token.len = cdat->auth_token.len;
+    r.rr_ctext.val = data.data;
+    r.rr_ctext.len = data.length;
+
+    len = sizeof(bufr);
+    p = ydr_encode_RXGK_Response(&r, bufr, &len);
+    len = sizeof(bufr) - len;
+    krb5_data_free(&data);
+
+    if (p == NULL)
+       return RXGKINCONSISTENCY;
+
+    if (rx_SlowWritePacket(pkt, 0, len, bufr) != len)
+       return RXGKPACKETSHORT;
+    rx_SetDataSize(pkt, len);
+
+    return 0;
+}
+
+/*
+ * Checksum and/or encrypt packet.
+ */
+static
+int
+client_PreparePacket(struct rx_securityClass *obj_,
+                    struct rx_call *call,
+                    struct rx_packet *pkt)
+{
+    rxgk_clnt_class *obj = (rxgk_clnt_class *) obj_;
+    key_stuff *k = &obj->k;
+    struct rx_connection *con = rx_ConnectionOf(call);
+    end_stuff *e = &((clnt_con_data *) con->securityData)->e;
+    
+    return rxgk_prepare_packet(pkt, con, obj->level, k, e);
+}
+
+/*
+ * Verify checksums and/or decrypt packet.
+ */
+static
+int
+client_CheckPacket(struct rx_securityClass *obj_,
+                  struct rx_call *call,
+                  struct rx_packet *pkt)
+{
+    rxgk_clnt_class *obj = (rxgk_clnt_class *) obj_;
+    key_stuff *k = &obj->k;
+    struct rx_connection *con = rx_ConnectionOf(call);
+    end_stuff *e = &((clnt_con_data *) con->securityData)->e;
+    
+    return rxgk_check_packet(pkt, con, obj->level, k, e);
+}
+
+static
+int
+client_GetStats(const struct rx_securityClass *obj,
+               const struct rx_connection *con,
+               struct rx_securityObjectStats *st)
+{
+    clnt_con_data *cdat = (clnt_con_data *) con->securityData;
+    
+    st->type = rxgk_disipline;
+    st->level = ((rxgk_clnt_class *)obj)->level;
+    st->flags = rxgk_checksummed;
+    if (cdat == 0)
+       st->flags |= rxgk_unallocated;
+    {
+       st->bytesReceived = cdat->e.bytesReceived;
+       st->packetsReceived = cdat->e.packetsReceived;
+       st->bytesSent = cdat->e.bytesSent;
+       st->packetsSent = cdat->e.packetsSent;
+    }
+    return 0;
+}
+
+static
+struct rx_securityOps client_ops = {
+    client_Close,
+    client_NewConnection,
+    client_PreparePacket,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    client_GetResponse,
+    NULL,
+    client_CheckPacket,
+    client_DestroyConnection,
+    client_GetStats,
+    NULL,
+    NULL,
+    NULL,
+};
+
+int rxgk_EpochWasSet = 0;
+
+int rxgk_min_level = rxgk_crypt; /* rxgk_{auth,crypt} */ /* XXX */
+
+struct rx_securityClass *
+rxgk_k5_NewClientSecurityObject(/*rxgk_level*/ int level,
+                               krb5_keyblock *key,
+                               int32_t kvno,
+                               int ticket_len,
+                               void *ticket,
+                               uint32_t serviceId,
+                               krb5_context context)
+{
+    rxgk_clnt_class *obj;
+    static int inited = 0;
+    int ret;
+    
+    if (level < rxgk_min_level)
+       level = rxgk_min_level; /* Boost security level */
+    
+    if (!inited) {
+       rx_SetEpoch(arc4random());
+       inited = 1;
+    }
+    
+    obj = (rxgk_clnt_class *) osi_Alloc(sizeof(rxgk_clnt_class));
+    obj->klass.refCount = 1;
+    obj->klass.ops = &client_ops;
+    
+    obj->klass.privateData = (char *) obj;
+    
+    obj->context = context;
+    obj->level = level;
+    obj->kvno = kvno;
+    obj->serviceId = serviceId;
+    
+    ret = krb5_copy_keyblock_contents(context, key, &obj->krb_key);
+    if (ret) {
+       osi_Free(obj, sizeof(rxgk_clnt_class));
+       return NULL;
+    }
+
+    memset(&obj->k.ks_key, 0, sizeof(obj->k.ks_key));
+    obj->k.ks_crypto = NULL;
+
+    memset(&obj->k.ks_skey, 0, sizeof(obj->k.ks_skey));
+    obj->k.ks_scrypto = NULL;
+    obj->k.ks_context = context;
+
+    obj->ticket.len = ticket_len;
+    obj->ticket.val = osi_Alloc(ticket_len);
+    memcpy(obj->ticket.val, ticket, obj->ticket.len);
+    
+    return &obj->klass;
+}
diff --git a/src/rxgk/rxgk_common.c b/src/rxgk/rxgk_common.c
new file mode 100644 (file)
index 0000000..7b4b6fd
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2002 - 2004, Stockholms universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ * 
+ * Redistribution is not permitted
+ */
+
+#include "rxgk_locl.h"
+
+RCSID("$Id$");
+
+#include <errno.h>
+
+#include <rx/rx.h>
+#include "rxgk_proto.h"
+
+/*
+ *
+ */
+
+int rxgk_key_contrib_size = 16;
+
+/*
+ *
+ */
+
+int
+rxk5_mutual_auth_client_generate(krb5_context context, krb5_keyblock *key,
+                                uint32_t number,
+                                RXGK_Token *challage_token)
+{
+    krb5_crypto crypto;
+    krb5_data data;
+    RXGK_CHALLENGE_TOKEN ct;
+    char buf[RXGK_CHALLENGE_TOKEN_MAX_SIZE];
+    size_t sz;
+    int ret;
+
+    data.data = NULL;
+
+    ret = krb5_crypto_init (context, key, key->keytype, &crypto);
+    if (ret)
+       return ret;
+    
+    ct.ct_version = RXGK_CR_TOKEN_VERSION;
+    ct.ct_nonce = number;
+    ct.ct_enctype.val = malloc(sizeof(ct.ct_enctype.val[0]));
+    ct.ct_enctype.len = 1;
+    if (ct.ct_enctype.val == NULL) {
+       ret = ENOMEM;
+       goto out;
+    }
+    ct.ct_enctype.val[0] = RXGK_CRYPTO_DES_CBC_CRC;
+    
+    sz = RXGK_CHALLENGE_TOKEN_MAX_SIZE;
+    if (ydr_encode_RXGK_CHALLENGE_TOKEN(&ct, buf, &sz) == NULL) {
+       ret = ENOMEM;
+       goto out;
+    }
+    sz = RXGK_CHALLENGE_TOKEN_MAX_SIZE - sz;
+
+    ret = krb5_encrypt(context, crypto, 0, buf, sz, &data);
+    if (ret)
+       goto out;
+    
+    challage_token->val = malloc(data.length);
+    if (challage_token->val == NULL) {
+       ret = ENOMEM;
+       goto out;
+    }
+
+    challage_token->len = data.length;
+    memcpy(challage_token->val, data.data, data.length);
+
+ out:
+    ydr_free_RXGK_CHALLENGE_TOKEN(&ct);
+    if (data.data)
+       krb5_data_free(&data);
+    krb5_crypto_destroy(context, crypto);
+    return ret;
+}
+
+/*
+ *
+ */
+
+int
+rxk5_mutual_auth_client_check(krb5_context context, krb5_keyblock *key,
+                             uint32_t number,
+                             const RXGK_Token *challage_token,
+                             krb5_keyblock *rxsession_key)
+{
+    krb5_crypto crypto;
+    krb5_data data;
+    RXGK_REPLY_TOKEN rt;
+    size_t sz;
+    int ret;
+
+    memset(&rt, 0, sizeof(rt));
+    memset(rxsession_key, 0, sizeof(*rxsession_key));
+
+    ret = krb5_crypto_init (context, key, key->keytype, &crypto);
+    if (ret)
+       return ret;
+    
+    /* Decrypt ticket */
+    data.data = NULL;
+    ret = krb5_decrypt(context, crypto, 0,
+                      challage_token->val, challage_token->len,
+                      &data);
+    if (ret)
+       goto out;
+
+    sz = data.length;
+    if (ydr_decode_RXGK_REPLY_TOKEN(&rt, data.data, &sz) == NULL) {
+       ret = RXGKSEALEDINCON;
+       goto out;
+    }
+
+    if (rt.rt_nonce != number + 1) {
+       ret = RXGKSEALEDINCON;
+       goto out2;
+    }
+
+    if (rt.rt_error != 0) {
+       ret = rt.rt_error;
+       goto out2;
+    }
+
+#if 1
+    /* XXX check rt_enctype */
+    ret = rxgk_random_to_key(rt.rt_enctype, 
+                            rt.rt_key.val, rt.rt_key.len,
+                            rxsession_key);
+#else
+    ret = krb5_copy_keyblock_contents(context, key, rxsession_key);
+#endif
+
+ out2:
+    ydr_free_RXGK_REPLY_TOKEN(&rt);
+ out:
+    if (data.data)
+       krb5_data_free(&data);
+    krb5_crypto_destroy(context, crypto);
+
+    return ret;
+}
+
+/*
+ *
+ */
+
+int
+rxk5_mutual_auth_server(krb5_context context, krb5_keyblock *key,
+                       const RXGK_Token *challage_token,
+                       int *session_enctype, 
+                       void **session_key, size_t *session_key_size,
+                       RXGK_Token *reply_token)
+{
+    krb5_crypto crypto;
+    krb5_data data;
+    krb5_keyblock keyblock;
+    RXGK_CHALLENGE_TOKEN ct;
+    RXGK_REPLY_TOKEN rt;
+    char buf[RXGK_REPLY_TOKEN_MAX_SIZE];
+    size_t sz;
+    int ret;
+
+    memset(&rt, 0, sizeof(rt));
+    memset(&ct, 0, sizeof(ct));
+
+    *session_enctype = 0;
+    *session_key = NULL;
+    *session_key_size = 0;
+
+    keyblock.keyvalue.data = NULL;
+
+    sz = RXGK_CHALLENGE_TOKEN_MAX_SIZE - sz;
+
+    ret = krb5_crypto_init (context, key, key->keytype, &crypto);
+    if (ret)
+       return ret;
+    
+    /* Decrypt ticket */
+    data.data = NULL;
+    ret = krb5_decrypt(context, crypto, 0,
+                      challage_token->val, challage_token->len,
+                      &data);
+    if (ret)
+       goto out;
+
+    sz = data.length;
+    if (ydr_decode_RXGK_CHALLENGE_TOKEN(&ct, data.data, &sz) == NULL) {
+       memset(&ct, 0, sizeof(ct));
+       ret = ENOMEM;
+       goto out;
+    }
+    sz = data.length - sz;
+
+    krb5_data_free(&data);
+    data.data = NULL;
+
+    if (ct.ct_version < RXGK_CR_TOKEN_VERSION) {
+       ret = RXGKSEALEDINCON;
+       goto out;
+    } else
+       ret = 0;
+
+    /* XXX choose best enctype, not just the one we use now */
+    { 
+       int i;
+
+       for (i = 0; i < ct.ct_enctype.len ; i++) {
+           if (ct.ct_enctype.val[i] == key->keytype)
+               break;
+       }
+
+       if (i == ct.ct_enctype.len)
+           ret = RXGKSEALEDINCON;
+    }
+
+    rt.rt_version = RXGK_CR_TOKEN_VERSION;
+    rt.rt_nonce = ct.ct_nonce + 1;
+
+    rt.rt_key.len = 0;
+    rt.rt_key.val = NULL;
+    rt.rt_error = ret;
+
+    if (ret == 0) {
+       ret = krb5_generate_random_keyblock(context, 
+                                           key->keytype,
+                                           &keyblock);
+       if (ret == 0) {
+           rt.rt_enctype = keyblock.keytype;
+           rt.rt_key.len = keyblock.keyvalue.length;
+           rt.rt_key.val = keyblock.keyvalue.data;
+
+           *session_enctype = keyblock.keytype;
+           *session_key_size = keyblock.keyvalue.length;
+           *session_key = malloc(keyblock.keyvalue.length);
+           if (*session_key == NULL)
+               abort();
+           memcpy(*session_key, keyblock.keyvalue.data, 
+                  keyblock.keyvalue.length);
+       } else {
+           rt.rt_error = ret;
+       }
+    }
+
+    sz = RXGK_REPLY_TOKEN_MAX_SIZE;
+    if (ydr_encode_RXGK_REPLY_TOKEN(&rt, buf, &sz) == 0) {
+       ret = ENOMEM;
+       goto out;
+    }
+    sz = RXGK_REPLY_TOKEN_MAX_SIZE - sz;
+
+    memset(rt.rt_key.val, 0, rt.rt_key.len);
+
+    data.data = NULL;
+    ret = krb5_encrypt(context, crypto, 0, buf, sz, &data);
+    if (ret)
+       goto out;
+    
+    reply_token->val = malloc(data.length);
+    if (reply_token->val == NULL) {
+       ret = ENOMEM;
+       goto out;
+    }
+
+    reply_token->len = data.length;
+    memcpy(reply_token->val, data.data, data.length);
+
+ out:
+    ydr_free_RXGK_CHALLENGE_TOKEN(&ct);
+    /* ydr_free_RXGK_REPLY_TOKEN(&rt); */
+
+    if (data.data)
+       krb5_data_free(&data);
+    if (keyblock.keyvalue.data)
+       krb5_free_keyblock_contents(context, &keyblock);
+    krb5_crypto_destroy(context, crypto);
+    return ret;
+}
+
+/*
+ *
+ */
+
+void
+rxgk_getheader(struct rx_packet *pkt, struct rxgk_header_data *h)
+{
+  uint32_t t;
+
+  /* Collect selected packet fields */
+  h->call_number = htonl(pkt->header.callNumber);
+  t = ((pkt->header.cid & RX_CHANNELMASK) << (32 - RX_CIDSHIFT))
+    | ((pkt->header.seq & 0x3fffffff));
+  h->channel_and_seq = htonl(t);
+}
+
+/*
+ *
+ */
+
+#if 0
+int
+rxgk_derive_transport_key(krb5_context context,
+                         krb5_keyblock *rx_conn_key,
+                         RXGK_rxtransport_key *keycontrib,
+                         krb5_keyblock *rkey)
+{
+    krb5_error_code ret;
+
+    /* XXX heimdal broken doesn't implement derive key for des encrypes */
+
+    switch (rx_conn_key->keytype) {
+    case RXGK_CRYPTO_DES_CBC_CRC:
+    case RXGK_CRYPTO_DES_CBC_MD4:
+    case RXGK_CRYPTO_DES_CBC_MD5:
+       ret = krb5_copy_keyblock_contents(context, rx_conn_key, rkey);
+       if (ret)
+           abort();
+
+       break;
+    default: {
+       char rxk_enc[RXGK_RXTRANSPORT_KEY_MAX_SIZE];
+       size_t sz;
+       krb5_keyblock *key;
+       
+       sz = RXGK_RXTRANSPORT_KEY_MAX_SIZE;
+       if (ydr_encode_RXGK_rxtransport_key(keycontrib, rxk_enc, &sz) == NULL)
+           return EINVAL;
+       
+       sz = RXGK_RXTRANSPORT_KEY_MAX_SIZE - sz;
+
+       ret = krb5_derive_key (context,
+                              rx_conn_key,
+                              rx_conn_key->keytype,
+                              rxk_enc,
+                              sz,
+                              &key);
+       if (ret)
+           abort();
+       
+       ret = krb5_copy_keyblock_contents(context, key, rkey);
+       if (ret)
+           abort();
+       
+       krb5_free_keyblock(context, key);
+       break;
+    }
+    }
+
+    return ret;
+}
+#endif
+
+/*
+ *
+ */
+
+
+/* XXX replace me */
+
+int
+rxgk_random_to_key(int enctype, 
+                  void *random_data, int random_sz,
+                  krb5_keyblock *key)
+{
+    memset(key, 0, sizeof(*key));
+
+    switch (enctype) {
+    case RXGK_CRYPTO_DES_CBC_CRC:
+    case RXGK_CRYPTO_DES_CBC_MD4:
+    case RXGK_CRYPTO_DES_CBC_MD5:
+       if (random_sz != 8)
+           return RXGKINCONSISTENCY;
+       break;
+    default:
+           return RXGKINCONSISTENCY;
+    }
+
+    key->keyvalue.data = malloc(random_sz);
+    if (key->keyvalue.data == NULL)
+       return ENOMEM;
+    memcpy(key->keyvalue.data, random_data, random_sz);
+    key->keyvalue.length = random_sz;
+    key->keytype = enctype;
+
+    return 0;
+}
diff --git a/src/rxgk/rxgk_crkrb.c b/src/rxgk/rxgk_crkrb.c
new file mode 100644 (file)
index 0000000..805c240
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2002 - 2004, Stockholms universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the university nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Heimdal implementation of the rxgk wire encryption
+ */
+
+#include "rxgk_locl.h"
+#include <errno.h>
+
+RCSID("$Id$");
+
+struct _rxg_key_type {
+    char *name;
+    int enctype;
+    int blocklen;
+    int checksumlen;
+    int confounderlen;
+};
+
+static struct _rxg_key_type ktypes[] = {
+    { "des-cbc-crc", RXGK_CRYPTO_DES_CBC_CRC,
+      8, 4, 8,
+    },
+    { "des-cbc-md5", RXGK_CRYPTO_DES_CBC_MD5,
+      8, 24, 8,
+    }
+};
+
+static struct _rxg_key_type *
+_rxg_find_enctype(int enctype)
+{
+    struct _rxg_key_type *key;
+
+    for (key = ktypes; key->name != NULL; key++)
+       if (key->enctype == enctype)
+           return key;
+    return NULL;
+}
+
+int
+rxgk_set_conn(struct rx_connection *con, int enctype, int enc)
+{
+    struct _rxg_key_type *key;
+
+    key = _rxg_find_enctype(enctype);
+    if (key == NULL)
+       return ENOENT;
+
+    if (enc) {
+       rx_SetSecurityHeaderSize(con, key->checksumlen + key->confounderlen +
+                                RXGK_HEADER_DATA_SIZE);
+
+       rx_SetSecurityMaxTrailerSize(con, key->blocklen);
+    } else {
+       rx_SetSecurityHeaderSize(con, 
+                                key->checksumlen + RXGK_HEADER_DATA_SIZE);
+       rx_SetSecurityMaxTrailerSize(con, 0);
+    }
+    return 0;
+}
+
+/*
+ *
+ */
+
+static int
+uiomove_to(struct rx_packet *pkt, u_int pre, u_int off, void **p, u_int *rlen)
+{
+    u_int len;
+    void *ptr;
+
+    len = rx_GetDataSize(pkt);
+    *rlen = len + pre;
+
+    ptr = malloc(*rlen);
+    if (ptr == NULL)
+       return ENOMEM;
+
+    *p = ptr;
+
+    ptr = (char *)ptr + pre;
+
+    if (rx_SlowReadPacket(pkt, off, len, ptr) != len) {
+       free(p);
+       *p = NULL;
+       return RXGKPACKETSHORT;
+    }
+    
+    return 0;
+}
+
+/*
+ *
+ */
+
+static int
+uiomove_from(struct rx_packet *pkt, u_int off, void *ptr, u_int len)
+{
+    if (rx_SlowWritePacket(pkt, off, len, ptr) != len)
+       return RXGKPACKETSHORT;
+    rx_SetDataSize(pkt, len + off);
+
+    return 0;
+}
+
+/*
+ *
+ */
+int
+rxgk_prepare_packet(struct rx_packet *pkt, struct rx_connection *con,
+                   int level, key_stuff *k, end_stuff *e)
+{
+    int ret, keyusage;
+    
+    
+
+    if (k->ks_scrypto == NULL)
+       return RXGKSEALEDINCON;
+
+    if (level == rxgk_crypt) {
+       krb5_data data;
+       struct rxgk_header_data hdr;
+       u_int len;
+       void *p;
+
+       if (rx_IsClientConn(con))
+           keyusage = RXGK_CLIENT_ENC_PACKETS;
+       else
+           keyusage = RXGK_SERVER_ENC_PACKETS;
+
+       ret = uiomove_to(pkt, RXGK_HEADER_DATA_SIZE, 
+                        rx_GetSecurityHeaderSize(con),
+                        &p, &len);
+       if (ret)
+           return ret;
+
+       rxgk_getheader(pkt, &hdr);
+       memcpy(p, &hdr, sizeof(hdr));
+
+       ret = krb5_encrypt(k->ks_context, k->ks_scrypto, 
+                          keyusage, p, len, &data);
+       if (ret) {
+           free(p);
+           return ret;
+       }
+
+       ret = uiomove_from(pkt, 0, data.data, data.length);
+
+       krb5_data_free(&data);
+       free(p);
+
+    } else if (level == rxgk_auth) {
+       if (rx_IsClientConn(con))
+           keyusage = RXGK_CLIENT_CKSUM_PACKETS;
+       else
+           keyusage = RXGK_SERVER_CKSUM_PACKETS;
+
+       abort();
+    } else
+       abort();
+
+    return ret;
+}
+
+/*
+ *
+ */
+int
+rxgk_check_packet(struct rx_packet *pkt, struct rx_connection *con,
+                 int level, key_stuff *k, end_stuff *e)
+{
+    int ret, keyusage;
+    
+    if (k->ks_scrypto == NULL)
+       return RXGKSEALEDINCON;
+
+    ret = 0;
+
+    if (level == rxgk_crypt) {
+       krb5_data data;
+       struct rxgk_header_data hdr;
+       u_int len;
+       void *p;
+
+       if (rx_IsClientConn(con))
+           keyusage = RXGK_SERVER_ENC_PACKETS;
+       else
+           keyusage = RXGK_CLIENT_ENC_PACKETS;
+
+       ret = uiomove_to(pkt, 0, 0, &p, &len);
+       if (ret)
+           return ret;
+
+       ret = krb5_decrypt(k->ks_context, k->ks_scrypto, 
+                          keyusage, p, len, &data);
+       if (ret) {
+           free(p);
+           return ret;
+       }
+
+       ret = uiomove_from(pkt, rx_GetSecurityHeaderSize(con) - 
+                          RXGK_HEADER_DATA_SIZE,
+                          data.data, data.length);
+       if (ret == 0) {
+           rxgk_getheader(pkt, &hdr);
+           if (memcmp(&hdr, data.data, sizeof(hdr)) != 0)
+               ret = RXGKSEALEDINCON;
+       }
+
+       krb5_data_free(&data);
+       free(p);
+    } else if (level == rxgk_auth) {
+       if (rx_IsClientConn(con))
+           keyusage = RXGK_SERVER_CKSUM_PACKETS;
+       else
+           keyusage = RXGK_CLIENT_CKSUM_PACKETS;
+
+
+       abort();
+    } else
+       abort();
+
+    return ret;
+}
diff --git a/src/rxgk/rxgk_crlha.c b/src/rxgk/rxgk_crlha.c
new file mode 100644 (file)
index 0000000..d034530
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2002 - 2004, Stockholms universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the university nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "rxgk_locl.h"
+
+RCSID("$Id$");
+
+#include <openssl/md5.h>
+#include <openssl/des.h>
+
+#include <errno.h>
+
+/*
+ *     krb5 non-des encrypting:
+ *
+ *     +------------+----------+-------+---------+-----+
+ *     | confounder | checksum | rxhdr | msg-seq | pad |
+ *     +------------+----------+-------+---------+-----+
+ *
+ *     krb5 non-des checksuming only:
+ *
+ *     +----------+-------+---------+
+ *     | checksum | rxhdr | msg-seq |
+ *     +----------+-------+---------+
+ *
+ *     XXX THIS SHOULD BE FIXED
+ *     so, the checksuming only case includes unnessery data right
+ *     now but I don't care since that makes it easier for me to
+ *     share code between the two cases.
+ *
+ */
+
+struct rxg_key_type;
+
+struct rxg_des_keystuff {
+    des_cblock key;
+    des_key_schedule sched;
+    des_key_schedule chksum;
+    des_cblock iv[RX_MAXCALLS];
+};
+
+struct rxg_key {
+    struct rxg_key_type *type;
+    rxgk_level level;
+    union {
+       struct rxg_des_keystuff des;
+    } key;
+};
+
+#define RXG_MAX_CHECKSUM_SIZE  128
+
+struct rxg_con {
+    struct rxg_key key;
+    struct rxg_key_type *type;
+};
+
+int
+rxg_PacketCheckSum(struct rxg_key_type *, struct rx_packet *, 
+                  struct rxg_key *, void *, size_t, int);
+int
+rxg_check_packet(struct rx_packet *pkt,
+                struct rx_connection *con,
+                int clear,
+                struct rxg_con *kc);
+int
+rxg_prepare_packet(struct rx_packet *pkt,
+                  struct rx_connection *con,
+                  int clear,
+                  struct rxg_con *kc);
+
+static void rxg_des_enc(void *, size_t, struct rxg_key *, void *, int);
+static void des_setup_iv(struct rx_packet *, struct rxg_key *, void *);
+static void des_prepare_key(struct rxg_key *, void *);
+static int checksum_pkt_md5_des(struct rx_packet *, struct rxg_key *, 
+                               void *, size_t, int);
+struct rxg_key_type * rxg_find_enctype(int);
+
+struct rxg_key_type {
+    char *name;
+    int enctype;
+    int keylen;
+    int blocklen;
+    int checksumlen;
+    int confounderlen;
+    int ivsize;
+    void (*prepare_key)(struct rxg_key *, void *key);
+    void (*setup_iv)(struct rx_packet *, struct rxg_key *, void *iv);
+    void (*encrypt)(void *, size_t, struct rxg_key *, void *, int);
+    int (*cksum_pkt)(struct rx_packet *, struct rxg_key *,void *,size_t,int);
+};
+
+static struct rxg_key_type ktypes[] = {
+    { "des-cbc-crc", RXGK_CRYPTO_DES_CBC_MD5,
+      8, 8, 24, 8, 8,
+      des_prepare_key, des_setup_iv, rxg_des_enc, checksum_pkt_md5_des
+    }
+};
+
+struct rxg_key_type *
+rxg_find_enctype(int enctype)
+{
+    struct rxg_key_type *key;
+
+    for (key = ktypes; key->name != NULL; key++)
+       if (key->enctype == enctype)
+           return key;
+    return NULL;
+}
+
+static void
+rxg_des_enc(void *io, size_t sz, struct rxg_key *key, void *iv, int enc)
+{
+    struct rxg_des_keystuff *ks = &key->key.des;
+
+    assert((sz % 8) == 0);
+    des_cbc_encrypt(io, io, sz, ks->sched, iv, enc);
+}
+
+static void
+des_prepare_key(struct rxg_key *key, void *keym)
+{
+    struct rxg_des_keystuff *ks;
+    des_cblock cksumkey;
+    int i;
+
+    ks = &key->key.des;
+
+    memset(ks, 0, sizeof(*ks));
+
+    memcpy(ks->key, keym, sizeof(des_cblock));
+    des_set_key(&ks->key, ks->sched);
+    memset(ks->iv, 0, sizeof(ks->iv));
+
+    for (i = 0; i < 8; i++)
+       cksumkey[i] = ((char *)keym)[i] ^ 0xF0;
+
+    des_set_key(&cksumkey, ks->chksum);
+}
+
+static void
+des_setup_iv(struct rx_packet *pkt, struct rxg_key *key, void *iv)
+{
+    memset(iv, 0, sizeof(des_cblock));
+}
+
+static void
+rxg_random_data(void *ptr, size_t sz)
+{
+    memset(ptr, 0, sz);
+    abort();
+}
+
+
+static int
+encrypt_pkt(struct rxg_key_type *kt, struct rx_packet *pkt, 
+           struct rxg_key *key, int encrypt)
+{
+    u_int len = rx_GetDataSize(pkt);
+    struct iovec *frag;
+    void *iv;
+
+    if ((iv = malloc(kt->ivsize)) == NULL)
+       return ENOMEM;
+
+    (kt->setup_iv)(pkt, key, iv);
+
+    assert((len % kt->blocklen) == 0);
+
+    for (frag = &pkt->wirevec[1]; len; frag++)
+    {
+       int      iov_len = frag->iov_len;
+       uint32_t *iov_bas = (uint32_t *) frag->iov_base;
+       if (iov_len == 0) {
+           memset(iv, 0, kt->ivsize);
+           free(iv);
+           return RXGKPACKETSHORT;     /* Length mismatch */
+       }
+       if (len < iov_len)
+           iov_len = len;              /* Don't process to much data */
+
+       assert((iov_len % kt->blocklen) == 0);
+
+       (*kt->encrypt)(iov_bas, iov_len, key, iv, encrypt);
+       len -= iov_len;
+    }
+    memset(iv, 0, kt->ivsize);
+    free(iv);
+    return 0;
+}
+
+#define MAXCONFOUNDER          50
+
+struct variable_header_data {
+    /* Data that changes per packet */
+    uint32_t call_number;
+    uint32_t channel_and_seq;
+};
+
+static void
+getheader(struct rx_packet *pkt, struct variable_header_data *h)
+{
+  uint32_t t;
+
+  /* Collect selected packet fields */
+  h->call_number = htonl(pkt->header.callNumber);
+  t = ((pkt->header.cid & RX_CHANNELMASK) << (32 - RX_CIDSHIFT))
+    | ((pkt->header.seq & 0x3fffffff));
+  h->channel_and_seq = htonl(t);
+}
+
+
+/* des-cbc(key XOR 0xF0F0F0F0F0F0F0F0, conf | rsa-md5(conf | msg)) */
+
+static int
+checksum_pkt_md5_des(struct rx_packet *pkt, struct rxg_key *key, 
+                    void *checksum, size_t checksumlen, int encrypt)
+{
+    struct rxg_des_keystuff *ks;
+    u_int len = rx_GetDataSize(pkt);
+    struct iovec *frag;
+    des_cblock iv;
+    MD5_CTX c;
+    int cksumsz;
+
+    ks = &key->key.des;
+    cksumsz = key->type->checksumlen;
+
+    assert(cksumsz == 24);
+
+    memset(&iv, 0, sizeof(iv));
+
+    MD5_Init(&c);
+
+    for (frag = &pkt->wirevec[1]; len; frag++)
+    {
+       int   iov_len = frag->iov_len;
+       char *iov_bas = (char *) frag->iov_base;
+
+       if (iov_len == 0)
+           return RXGKPACKETSHORT;             /* Length mismatch */
+       if (len < iov_len)
+           iov_len = len;              /* Don't process to much data */
+
+       MD5_Update(&c, iov_bas, iov_len);
+       len -= iov_len;
+    }
+    MD5_Final(checksum, &c);
+
+    des_cbc_encrypt(checksum, checksum, cksumsz, ks->chksum, &iv, 1);
+
+    return 0;
+}
+
+
+int
+rxg_PacketCheckSum(struct rxg_key_type *kt, struct rx_packet *pkt, 
+                  struct rxg_key *key, void *cksum, size_t cksumsz,
+                  int encrypt)
+{
+    (*kt->cksum_pkt)(pkt, key, cksum, cksumsz, encrypt);
+    return 0;
+}
+
+int
+rxg_check_packet(struct rx_packet *pkt,
+                struct rx_connection *con,
+                int encrypt,
+                struct rxg_con *kc)
+{
+    struct variable_header_data hd;
+    char sum[RXG_MAX_CHECKSUM_SIZE];
+    char sum2[RXG_MAX_CHECKSUM_SIZE];
+    char *base;
+    int ret;
+
+    if (rx_GetPacketCksum(pkt) != 0)
+       return RXGKSEALEDINCON;
+
+    if (encrypt) {
+       ret = encrypt_pkt(kc->type, pkt, &kc->key, 0);
+       if (ret)
+           return ret;
+    }
+    
+    base = pkt->wirevec[1].iov_base;
+    if (encrypt)
+       base += kc->type->confounderlen;
+    memcpy(sum, base, kc->type->checksumlen);
+    memset(base, 0, kc->type->checksumlen);
+
+    ret = rxg_PacketCheckSum(kc->type, pkt, &kc->key, sum2, 
+                             kc->type->checksumlen, 0);
+    if (ret)
+       return ret;
+
+    if (memcmp(sum2, sum, kc->type->checksumlen) != 0)
+       return RXGKSEALEDINCON;
+
+    getheader(pkt, &hd);
+    
+    if (memcmp(base + kc->type->checksumlen, &hd, sizeof(hd)) != 0)
+       return RXGKSEALEDINCON;
+
+    return 0;
+}
+
+int
+rxg_prepare_packet(struct rx_packet *pkt,
+                  struct rx_connection *con,
+                  int encrypt,
+                  struct rxg_con *kc)
+{
+    char sum[RXG_MAX_CHECKSUM_SIZE];
+    u_int len = rx_GetDataSize(pkt);
+    int diff, ret;
+    struct variable_header_data hd;
+    char *base;
+
+    /* checksum in rx header is defined to 0 in rxgss */
+    rx_SetPacketCksum(pkt, 0);
+    
+    /* 
+     * First we fixup the packet size, its assumed that the checksum
+     * need to to the operation on blocklen too
+     */
+
+    len += rx_GetSecurityHeaderSize(con); /* Extended pkt len */
+       
+    if (encrypt) {
+       if ((diff = (len % kc->type->blocklen)) != 0) {
+           rxi_RoundUpPacket(pkt, diff);
+           len += diff;
+       }
+    }
+    rx_SetDataSize(pkt, len); /* Set extended packet length */
+
+    diff = kc->type->checksumlen + RXGK_HEADER_DATA_SIZE;
+    if (encrypt)
+       diff += kc->type->confounderlen;
+
+    if (pkt->wirevec[1].iov_len < diff)
+       return RXGKPACKETSHORT;
+
+    base = pkt->wirevec[1].iov_base;
+    if (encrypt) {
+       rxg_random_data(base, kc->type->confounderlen);
+       base += kc->type->confounderlen;
+    }
+    memset(base, 0, kc->type->checksumlen);
+    base += kc->type->checksumlen;
+    getheader(pkt, &hd);
+    memcpy(base, &hd, sizeof(hd));
+
+    /* computer and store checksum of packet */
+    ret = rxg_PacketCheckSum(kc->type, pkt, &kc->key, 
+                            sum, kc->type->checksumlen, 1);
+    if (ret)
+       return ret;
+
+    base = pkt->wirevec[1].iov_base;
+    if (encrypt)
+       base += kc->type->confounderlen;
+    memcpy(base, sum, kc->type->checksumlen);
+
+    if (!encrypt)
+       return 0;
+
+    return encrypt_pkt(kc->type, pkt, &kc->key, 1);
+}
+
+int
+rxgk_set_conn(struct rx_connection *con, int enctype, int enc)
+{
+    struct rxg_key_type *key;
+
+    key = rxg_find_enctype(enctype);
+    if (key)
+       return ENOENT;
+
+    if (enc) {
+       rx_SetSecurityHeaderSize(con, key->checksumlen + key->confounderlen +
+                                RXGK_HEADER_DATA_SIZE);
+       rx_SetSecurityMaxTrailerSize(con, key->blocklen);
+    } else {
+       rx_SetSecurityHeaderSize(con, 
+                                key->checksumlen + RXGK_HEADER_DATA_SIZE);
+       rx_SetSecurityMaxTrailerSize(con, 0);
+    }
+    return 0;
+}
+
+
+int
+rxgk_prepare_packet(struct rx_packet *pkt, struct rx_connection *con,
+                    int level, key_stuff *k, end_stuff *e)
+{
+    return 0;
+}
+
+int
+rxgk_check_packet(struct rx_packet *pkt, struct rx_connection *con,
+                  int level, key_stuff *k, end_stuff *e)
+{
+    return 0;
+}
+
+
+#if 0
+
+int
+main(int argc, char **argv)
+{
+    krb5_encrypt();
+    return 0;
+}
+
+#endif
diff --git a/src/rxgk/rxgk_crpc.c b/src/rxgk/rxgk_crpc.c
new file mode 100644 (file)
index 0000000..09a6608
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2002 - 2004, Stockholms universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ * 
+ * Redistribution is not permitted
+ */
+
+#include "rxgk_locl.h"
+
+RCSID("$Id$");
+
+#include <rx/rx.h>
+#include "rxgk_proto.h"
+#include "rxgk_proto.cs.h"
+
+#include <errno.h>
+
+int
+rxgk5_get_auth_token(krb5_context context, uint32_t addr, int port, 
+                    uint32_t serviceId,
+                    RXGK_Token *token,
+                    RXGK_Token *auth_token, krb5_keyblock *key,
+                    krb5_keyblock *skey,
+                    int32_t *kvno)
+{
+    struct rx_securityClass *secobj;
+    struct rx_connection *conn;
+    RXGK_Token challange, reply_token;
+    uint32_t num;
+    int ret;
+
+    memset(skey, 0, sizeof(*skey));
+
+    secobj = rxnull_NewClientSecurityObject();
+
+    conn = rx_NewConnection(addr, port, serviceId, secobj, 0);
+    if (conn == NULL)
+       return ENETDOWN;
+
+    num = arc4random();
+
+    ret = rxk5_mutual_auth_client_generate(context, key, num, &challange);
+    if (ret) {
+       rx_DestroyConnection(conn);
+       return ret;
+    }
+
+    ret = RXGK_EstablishKrb5Context(conn, token, &challange,
+                                   &reply_token, kvno, auth_token);
+    if (ret) {
+       rx_DestroyConnection(conn);
+       return ret;
+    }
+
+    ret = rxk5_mutual_auth_client_check(context, key, num, &reply_token, skey);
+
+    rx_DestroyConnection(conn);
+
+    return ret;
+}
diff --git a/src/rxgk/rxgk_info.c b/src/rxgk/rxgk_info.c
new file mode 100644 (file)
index 0000000..22f5164
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1995 - 1998, 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "rxgk_locl.h"
+
+RCSID("$Id$");
+
+int32_t
+rxgk_GetServerInfo(struct rx_connection *con,
+                  rxgk_level *level,
+                  uint32_t *expiration,
+                  char *name, size_t name_size,
+                  char *cell, size_t cell_size,
+                  int32_t *kvno)
+{
+    serv_con_data *cdat = (serv_con_data *) con->securityData;
+
+    if (cdat && cdat->authenticated
+       && (time(0) < cdat->expires))
+    {
+       if (level)
+           *level = cdat->cur_level;
+       if (expiration)
+           *expiration = cdat->expires;
+       return 0;
+    }
+  else
+    return RXGKNOAUTH;
+}
diff --git a/src/rxgk/rxgk_locl.h b/src/rxgk/rxgk_locl.h
new file mode 100644 (file)
index 0000000..a85ffae
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 1995 - 1998, 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef __RXGK_LOCL_H
+#define __RXGK_LOCL_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include <krb5.h>
+#include "rxgk_proto.h"
+
+#ifdef NDEBUG
+#ifndef assert
+#define assert(e) ((void)0)
+#endif
+#else
+#ifndef assert
+#define assert(e) ((e) ? (void)0 : (void)osi_Panic("assert(%s) failed: file %s, line %d\n", #e, __FILE__, __LINE__, #e))
+#endif
+#endif
+
+#undef RCSID
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+#undef RCSID
+#define RCSID(msg) \
+static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
+
+extern int rx_epoch, rx_nextCid;
+
+#include "rxgk.h"
+
+#define rxgk_disipline 3
+
+#define rxgk_unallocated 1
+#define rxgk_authenticated 2
+#define rxgk_expired 4
+#define rxgk_checksummed 8
+
+typedef struct key_stuff {
+    krb5_context       ks_context;
+    krb5_keyblock      ks_key;
+    uint32_t           ks_recv_seqnum;
+    krb5_keyblock      ks_skey;
+    krb5_crypto                ks_crypto;      /* rx session key */
+    krb5_crypto                ks_scrypto;     /* rx stream key */
+} key_stuff;
+
+typedef struct end_stuff {
+    /* need 64 bit counters */
+    uint32_t bytesReceived, packetsReceived, bytesSent, packetsSent;
+} end_stuff;
+
+extern int rxgk_key_contrib_size;
+
+int
+rxgk_prepare_packet(struct rx_packet *pkt, struct rx_connection *con,
+                    int level, key_stuff *k, end_stuff *e);
+
+int
+rxgk_check_packet(struct rx_packet *pkt, struct rx_connection *con,
+                  int level, key_stuff *k, end_stuff *e);
+
+/* Per connection specific server data */
+typedef struct serv_con_data {
+  end_stuff e;
+  key_stuff k;
+  uint32_t expires;
+  uint32_t nonce;
+  rxgk_level cur_level;        /* Starts at min_level and can only increase */
+  char authenticated;
+} serv_con_data;
+
+/* rxgk */
+
+int
+rxgk5_get_auth_token(krb5_context context, uint32_t addr, int port, 
+                    uint32_t serviceId,
+                    RXGK_Token *token,
+                    RXGK_Token *auth_token, krb5_keyblock *key,
+                    krb5_keyblock *skey,
+                    int32_t *kvno);
+
+int
+rxk5_mutual_auth_client_generate(krb5_context context, krb5_keyblock *key,
+                                uint32_t number,
+                                RXGK_Token *challage_token);
+int
+rxk5_mutual_auth_client_check(krb5_context context, krb5_keyblock *key,
+                             uint32_t number,
+                             const RXGK_Token *reply_token,
+                             krb5_keyblock *rxsession_key);
+int
+rxk5_mutual_auth_server(krb5_context context, krb5_keyblock *key,
+                       const RXGK_Token *challage_token,
+                       int *enctype, 
+                       void **session_key, size_t *session_key_size,
+                       RXGK_Token *reply_token);
+
+int
+rxgk_set_conn(struct rx_connection *, int, int);
+
+int
+rxgk_decode_auth_token(void *data, size_t len, struct RXGK_AUTH_CRED *c);
+
+void
+rxgk_getheader(struct rx_packet *pkt, struct rxgk_header_data *h);
+
+int
+rxgk_server_init(void);
+
+#if 0
+int
+rxgk_derive_transport_key(krb5_context context,
+                         krb5_keyblock *rx_conn_key,
+                         RXGK_rxtransport_key *keycontrib,
+                         krb5_keyblock *rkey);
+#endif
+
+int
+rxgk_random_to_key(int, void *, int, krb5_keyblock *);
+
+#endif /* __RXGK_LOCL_H */
diff --git a/src/rxgk/rxgk_proto.xg b/src/rxgk/rxgk_proto.xg
new file mode 100644 (file)
index 0000000..a02559f
--- /dev/null
@@ -0,0 +1,202 @@
+/* hej emacs det h{r {r en -*- c -*- fil */
+
+/*
+ * Copyright (c) 2002 - 2004, Stockholms Universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ * 
+ * Redistribution is not permitted
+ */
+
+/* $Id$ */
+
+package RXGK_
+
+const RXGK_MAX_TOKEN_LEN = 65536;
+const RXGK_MAX_AUTHTOKEN = 256;
+
+/* ctext is limited by mtu since its part of responce */
+const RXGK_MAX_CTEXT    = 768; 
+
+const RXGK_SERVICE_ID   = 34567;
+
+#define RXGK_ESTABLISH_KRB5_CONTEXT    1
+#define RXGK_ESTABLISH_GSS_CONTEXT     2
+#define RXGK_EXCHANGE_GSS_KEYS         3
+
+typedef opaque RXGK_Token<RXGK_MAX_TOKEN_LEN>;
+
+/*
+ *
+ */
+
+const RXGK_KEY_VERSION         = 1;
+const RXGK_KEY_MAXSIZE         = 256;
+const RXGK_KEY_MAXPRINCIPAL    = 640;
+const RXGK_KEY_ENCTYPES                = 32;
+
+/*
+ * Challange token in the 
+ */
+
+const RXGK_CR_TOKEN_VERSION    = 1;
+
+struct RXGK_CHALLENGE_TOKEN {
+    afs_int32  ct_version;
+    afs_uint32 ct_nonce;
+    afs_uint32 ct_enctype<RXGK_KEY_ENCTYPES>;  /* listed in order of pref */
+};
+
+/*
+ * Reply token in the EstablishKrb5Context
+ */
+
+struct RXGK_REPLY_TOKEN {
+    afs_int32  rt_version;
+    afs_int32  rt_flags;       /* other support ops */
+    afs_int32  rt_error;
+    afs_uint32 rt_nonce;
+    afs_uint32 rt_enctype;
+    opaque     rt_key<RXGK_KEY_MAXSIZE>;
+};
+
+/*
+ * Rx auth cred equivalent
+ */
+
+struct RXGK_AUTH_CRED {
+    afs_int32  ac_version;     /* version of format of RXGK_AUTH_CRED */
+    string     ac_principal<RXGK_KEY_MAXPRINCIPAL>; /* prefixed with mech */
+    afs_int32  ac_starttime;
+    afs_int32  ac_endtime;
+    afs_int32  ac_enctype;
+    opaque     ac_key<RXGK_KEY_MAXSIZE>;
+};
+
+/*
+ * This is part of the rxs challange/response exchange.  Its somewhat
+ * complicated since it support rekeying of a data stream.
+ */
+
+const RXGK_VERSION = 3;
+
+const RXKG_OPCODE_CHALLENGE    = 1;
+const RXKG_OPCODE_REKEY                = 2;
+
+struct RXGK_Challenge {
+    afs_uint32 rc_version;
+    afs_uint32 rc_nonce;
+    afs_uint32 rc_opcode;
+    afs_uint32 rc_max_seq_skew;        /* packets accepted when rekey */
+    afs_uint32 rc_min_level;
+};
+
+/* is the auth_token EstablishKrb5Context returned */
+struct RXGK_Response {
+    afs_uint32 rr_version;
+    afs_uint32 rr_auth_token_kvno;
+    opaque     rr_auth_token<RXGK_MAX_AUTHTOKEN>;
+    opaque     rr_ctext<RXGK_MAX_CTEXT>;
+};
+
+struct RXGK_Response_Crypt {
+    afs_uint32 nonce;
+    afs_uint32  epoch;
+    afs_uint32  cid;
+    afs_uint32 call_numbers[4];
+    afs_uint32 level;
+    afs_uint32 key_version;
+    afs_uint32 key_counter_hi;
+    afs_uint32 key_counter_lo;
+};
+
+/*
+ * Kerberos crypto framework enctypes 
+ */
+
+const RXGK_CRYPTO_NULL                 = 0;
+const RXGK_CRYPTO_DES_CBC_CRC          = 1;
+const RXGK_CRYPTO_DES_CBC_MD4          = 2;
+const RXGK_CRYPTO_DES_CBC_MD5          = 4;
+const RXGK_CRYPTO_DES3_SHA1_KD         = 16;
+
+const RXGK_CRYPTO_CKSUM_RSA_DES_MD5    = 8;
+
+const RXGK_CLIENT_TO_SERVER            = 0;
+const RXGK_SERVER_TO_CLIENT            = 1;
+
+const RXGK_CLIENT_ENC_CHALLENGE                = 1026;
+const RXGK_SERVER_ENC_REKEY            = 1026;
+const RXGK_CLIENT_ENC_PACKETS          = 1027;
+const RXGK_CLIENT_CKSUM_PACKETS                = 1028;
+const RXGK_SERVER_ENC_PACKETS          = 1029;
+const RXGK_SERVER_CKSUM_PACKETS                = 1030;
+
+/*
+ * In packet protection since header isn't checksum-ed
+ */
+
+struct rxgk_header_data {
+    uint32_t call_number;
+    uint32_t channel_and_seq;
+};
+
+/*
+ * rx connection key
+ */
+
+struct RXGK_rxconn_key {
+    afs_uint32 rxk_cid;
+    afs_uint32 rxk_epoch;
+};
+
+#if 0
+
+const RXGK_MAX_KEYCONTRIB= 256; /* MUST only be used from server->client */
+
+struct RXGK_ReKey {
+    opaque     rk_ctext<RXGK_MAX_CTEXT>;
+};
+
+struct RXGK_ReKey_Crypt {
+    afs_int32  rkc_version;
+    afs_int32  rkc_max_seq_num;
+    afs_int32  rkc_kvno;               /* 16 bit number */
+    opaque     rkc_keycontribution<RXGK_MAX_KEYCONTRIB>;
+};
+
+/* rx transport key */
+
+struct RXGK_rxtransport_key {
+    opaque     client_keycontribution<RXGK_MAX_KEYCONTRIB>;
+    opaque     server_keycontribution<RXGK_MAX_KEYCONTRIB>;
+};
+
+#endif
+
+/*
+ * kerberos auth_token
+ */
+
+EstablishKrb5Context(IN RXGK_Token *token, 
+                    IN RXGK_Token *challenge_token,
+                    OUT RXGK_Token *reply_token,
+                    OUT int32_t *auth_token_kvno,
+                    OUT RXGK_Token *auth_token) = RXGK_ESTABLISH_KRB5_CONTEXT;
+
+/*
+ * Add gss stuff here
+ */
+
+#if 0
+
+EstablishGssContext(IN RXGK_Token *in_token,
+                   OUT RXGK_Token *out_token) = RXGK_ESTABLISH_GSS_CONTEXT;
+
+ExchangeGSSKeys(IN RXGK_Token *challenge_token,
+               OUT RXGK_Token *reply_token,
+               OUT int32_t *auth_token_kvno,
+               OUT RXGK_Token *auth_token) = RXGK_EXCHANGE_GSS_KEYS;
+
+#endif
+
diff --git a/src/rxgk/rxgk_serv.c b/src/rxgk/rxgk_serv.c
new file mode 100644 (file)
index 0000000..0f70214
--- /dev/null
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 1995 - 1998, 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "rxgk_locl.h"
+
+RCSID("$Id$");
+
+#include <errno.h>
+
+#include "rxgk_proto.ss.h"
+
+/* Security object specific server data */
+typedef struct rxgk_serv_class {
+    struct rx_securityClass klass;
+    rxgk_level min_level;
+    char *principal;
+    char *service_principal;
+    void *appl_data;
+    int (*get_key)(void *, const char *, int, int, krb5_keyblock *);
+    int (*user_ok)(const char *name, const char *realm, int kvno);
+    uint32_t serviceId;
+} rxgk_serv_class;
+
+extern krb5_context gk_context;
+extern krb5_crypto gk_crypto;
+
+static int
+server_NewConnection(struct rx_securityClass *obj, struct rx_connection *con)
+{
+    serv_con_data *cdat;
+    assert(con->securityData == 0);
+    assert(gk_context != NULL);
+    obj->refCount++;
+    con->securityData = (char *) osi_Alloc(sizeof(serv_con_data));
+    memset(con->securityData, 0x0, sizeof(serv_con_data));
+    cdat = (serv_con_data *)con->securityData;
+    cdat->k.ks_context = gk_context;
+    return 0;
+}
+
+static int
+server_Close(struct rx_securityClass *obj)
+{
+    obj->refCount--;
+    if (obj->refCount <= 0)
+       osi_Free(obj, sizeof(rxgk_serv_class));
+    return 0;
+}
+
+static
+int
+server_DestroyConnection(struct rx_securityClass *obj,
+                        struct rx_connection *con)
+{
+  serv_con_data *cdat = (serv_con_data *)con->securityData;
+
+  if (cdat)
+      osi_Free(cdat, sizeof(serv_con_data));
+  return server_Close(obj);
+}
+
+/*
+ * Check whether a connection authenticated properly.
+ * Zero is good (authentication succeeded).
+ */
+static int
+server_CheckAuthentication(struct rx_securityClass *obj,
+                          struct rx_connection *con)
+{
+    serv_con_data *cdat = (serv_con_data *) con->securityData;
+
+    if (cdat)
+       return !cdat->authenticated;
+    else
+       return RXGKNOAUTH;
+}
+
+/*
+ * Select a nonce for later use.
+ */
+static
+int
+server_CreateChallenge(struct rx_securityClass *obj_,
+                      struct rx_connection *con)
+{
+    serv_con_data *cdat = (serv_con_data *) con->securityData;
+
+    cdat->nonce = arc4random();
+    cdat->authenticated = 0;
+    return 0;
+}
+
+/*
+ * Wrap the nonce in a challenge packet.
+ */
+static int
+server_GetChallenge(const struct rx_securityClass *obj_,
+                   const struct rx_connection *con,
+                   struct rx_packet *pkt)
+{
+    rxgk_serv_class *obj = (rxgk_serv_class *) obj_;
+    serv_con_data *cdat = (serv_con_data *) con->securityData;
+    struct RXGK_Challenge c;
+    int initial_challage = 1;
+
+    c.rc_version = htonl(RXGK_VERSION);
+    c.rc_nonce = htonl(cdat->nonce);
+    c.rc_max_seq_skew = htonl(200); /* XXX */
+    c.rc_min_level = htonl(obj->min_level);
+
+    if (initial_challage) {
+       /* Make challenge */
+       c.rc_opcode = htonl(RXKG_OPCODE_CHALLENGE);
+    
+       /* Stuff into packet */
+       if (rx_SlowWritePacket(pkt, 0, sizeof(c), &c) != sizeof(c))
+           return RXGKPACKETSHORT;
+       rx_SetDataSize(pkt, sizeof(c));
+#if 0
+    } else {
+       RXGK_ReKey rk;
+       RXGK_ReKey_Crypt rkc;
+       char bufrk[RXGK_REKEY_MAX_SIZE];
+       char bufrkc[RXGK_REKEY_CRYPT_MAX_SIZE];
+       krb5_data data;
+       size_t sz;
+       int ret;
+       key_stuff *k = &cdat->k;
+
+       memset(&rk, 0, sizeof(rk));
+       memset(&rkc, 0, sizeof(rkc));
+
+       c.rc_opcode = htonl(RXKG_OPCODE_REKEY);
+
+       if (rx_SlowWritePacket(pkt, 0, sizeof(c), &c) != sizeof(c))
+           return RXGKPACKETSHORT;
+       
+       rkc.rkc_version = RXGK_VERSION;
+       rkc.rkc_max_seq_num = 200; /* XXX */
+       rkc.rkc_kvno = /* current_key + 1 */ 1;
+       rkc.rkc_keycontribution.len = 0; /* XXX */
+       rkc.rkc_keycontribution.val = NULL;
+
+       sz = RXGK_REKEY_CRYPT_MAX_SIZE;
+       if (ydr_encode_RXGK_ReKey_Crypt(&rkc, bufrkc, &sz) == NULL)
+           return RXGKPACKETSHORT;
+       sz = RXGK_REKEY_CRYPT_MAX_SIZE - sz;
+       
+       ret = krb5_encrypt(k->ks_context, k->ks_crypto, 
+                          RXGK_SERVER_ENC_REKEY, bufrkc, sz, &data);
+       if (ret)
+           return ret;
+
+       rk.rk_ctext.val = data.data;
+       rk.rk_ctext.len = data.length;
+
+       sz = RXGK_REKEY_MAX_SIZE;
+       if (ydr_encode_RXGK_ReKey(&rk, bufrk, &sz) == NULL) {
+           krb5_data_free(&data);
+           return RXGKPACKETSHORT;
+       }
+       sz = RXGK_REKEY_MAX_SIZE - sz;
+
+       krb5_data_free(&data);
+       
+       if (rx_SlowWritePacket(pkt, sizeof(c), sz, bufrk) != sz)
+           return RXGKPACKETSHORT;
+
+       rx_SetDataSize(pkt, sizeof(c) + sz);
+#endif
+    }
+    return 0;
+}
+
+/*
+ * Process a response to a challange.
+ */
+static int
+server_CheckResponse(struct rx_securityClass *obj_,
+                    struct rx_connection *con,
+                    struct rx_packet *pkt)
+{
+    serv_con_data *cdat = (serv_con_data *) con->securityData;
+    
+    struct RXGK_Response r;
+    struct RXGK_Response_Crypt rc;
+    struct RXGK_AUTH_CRED c;
+    char response[RXGK_RESPONSE_MAX_SIZE];
+    size_t len, len2;
+    int ret;
+    krb5_context context = cdat->k.ks_context;
+    krb5_data data;
+    
+    memset(&r, 0, sizeof(r));
+    memset(&c, 0, sizeof(r));
+    
+    len = rx_SlowReadPacket(pkt, 0, sizeof(response), response);
+    if (len <= 0)
+       return RXGKPACKETSHORT;
+    
+    len2 = len;
+    if (ydr_decode_RXGK_Response(&r, response, &len2) == NULL) {
+       ret = RXGKPACKETSHORT;
+       goto out;
+    }
+    
+    ret = rxgk_decode_auth_token(r.rr_auth_token.val, r.rr_auth_token.len, &c);
+    if (ret)
+       goto out;
+    
+    ret = rxgk_random_to_key(c.ac_enctype, c.ac_key.val, c.ac_key.len,
+                            &cdat->k.ks_key);
+    if (ret)
+       goto out;
+
+    cdat->k.ks_crypto = NULL; /* XXX */
+    ret = krb5_crypto_init(context, &cdat->k.ks_key, cdat->k.ks_key.keytype, 
+                          &cdat->k.ks_crypto);
+    if (ret)
+       goto out2;
+
+
+    ret = krb5_decrypt(context, cdat->k.ks_crypto, RXGK_CLIENT_ENC_CHALLENGE, 
+                      r.rr_ctext.val, r.rr_ctext.len, &data);
+    if (ret)
+       goto out2;
+
+    len = data.length;
+    if (ydr_decode_RXGK_Response_Crypt(&rc, data.data, &len) == NULL) {
+       krb5_data_free(&data);
+       goto out2;
+    }
+
+    krb5_data_free(&data);
+
+    if (rc.epoch != con->epoch
+       || rc.cid != (con->cid & RX_CIDMASK)
+#if 0
+       || rc.security_index != con->securityIndex
+#endif
+       ) {
+       ret = RXGKSEALEDINCON;
+       goto out2;
+    }
+
+    {
+       int i;
+       for (i = 0; i < RX_MAXCALLS; i++)
+       {
+           if (rc.call_numbers[i] < 0) {
+               ret = RXGKSEALEDINCON;
+               goto out2;
+           }
+       }
+
+    }
+
+    if (rc.nonce != cdat->nonce + 1) {
+       ret = RXGKOUTOFSEQUENCE;
+       goto out2;
+    }
+
+    /* XXX */
+    if (rc.level != rxgk_crypt) {
+       ret = RXGKLEVELFAIL;
+       goto out2;
+    }
+
+    if ((rc.level != rxgk_auth && rc.level != rxgk_crypt) ||
+       rc.level < cdat->cur_level) 
+    {
+       ret = RXGKLEVELFAIL;
+       goto out2;
+    }
+
+#if 0
+    ret = rxgk_derive_transport_key(context, &cdat->k.ks_key,
+                                   &rc.contrib, &cdat->k.ks_skey);
+    if (ret)
+       goto out2;
+#endif
+
+    ret = krb5_crypto_init (context, &cdat->k.ks_skey,
+                           cdat->k.ks_skey.keytype,
+                           &cdat->k.ks_scrypto);
+    if (ret)
+       goto out2;
+
+    rxi_SetCallNumberVector(con, rc.call_numbers);
+
+    cdat->authenticated = 1;
+    cdat->expires = c.ac_endtime;
+    cdat->cur_level = rc.level;
+
+    rxgk_set_conn(con, cdat->k.ks_key.keytype,
+                 rc.level == rxgk_crypt ? 1 : 0);
+
+ out2:
+    if (ret) {
+       krb5_free_keyblock_contents(context, &cdat->k.ks_key);
+       if (cdat->k.ks_crypto)
+           krb5_crypto_destroy(context, cdat->k.ks_crypto);
+       cdat->k.ks_crypto = NULL;
+    }
+
+ out:  
+
+    ydr_free_RXGK_AUTH_CRED(&c);
+    ydr_free_RXGK_Response(&r);
+    
+    return ret;
+}
+
+/*
+ * Checksum and/or encrypt packet
+ */
+static int
+server_PreparePacket(struct rx_securityClass *obj_,
+                    struct rx_call *call,
+                    struct rx_packet *pkt)
+{
+    struct rx_connection *con = rx_ConnectionOf(call);
+    serv_con_data *cdat = (serv_con_data *) con->securityData;
+    key_stuff *k = &cdat->k;
+    end_stuff *e = &cdat->e;
+    
+    return rxgk_prepare_packet(pkt, con, cdat->cur_level, k, e);
+}
+
+/*
+ * Verify checksum and/or decrypt packet.
+ */
+static int
+server_CheckPacket(struct rx_securityClass *obj_,
+                  struct rx_call *call,
+                  struct rx_packet *pkt)
+{
+    struct rx_connection *con = rx_ConnectionOf(call);
+    serv_con_data *cdat = (serv_con_data *) con->securityData;
+    key_stuff *k = &cdat->k;
+    end_stuff *e = &cdat->e;
+
+    if (time(0) > cdat->expires)       /* Use fast time package instead??? */
+       return RXGKEXPIRED;
+
+    return rxgk_check_packet(pkt, con, cdat->cur_level, k, e);
+}
+
+static int
+server_GetStats(const struct rx_securityClass *obj_,
+               const struct rx_connection *con,
+               struct rx_securityObjectStats *st)
+{
+    rxgk_serv_class *obj = (rxgk_serv_class *) obj_;
+    serv_con_data *cdat = (serv_con_data *) con->securityData;
+    
+    st->type = rxgk_disipline;
+    st->level = obj->min_level;
+    st->flags = rxgk_checksummed;
+    if (cdat == 0)
+       st->flags |= rxgk_unallocated;
+    {
+       st->bytesReceived = cdat->e.bytesReceived;
+       st->packetsReceived = cdat->e.packetsReceived;
+       st->bytesSent = cdat->e.bytesSent;
+       st->packetsSent = cdat->e.packetsSent;
+       st->expires = cdat->expires;
+       st->level = cdat->cur_level;
+       if (cdat->authenticated)
+           st->flags |= rxgk_authenticated;
+    }
+    return 0;
+}
+
+static
+void
+free_context(void)
+{
+    return;
+}
+
+static
+int
+server_NewService(const struct rx_securityClass *obj_,
+                 struct rx_service *service,
+                 int reuse)
+{
+    rxgk_serv_class *obj = (rxgk_serv_class *) obj_;
+
+    if (service->serviceId == obj->serviceId)
+       return 0;
+    
+    if (!reuse) {
+       struct rx_securityClass *sec[2];
+       struct rx_service *secservice;
+       
+       sec[0] = rxnull_NewServerSecurityObject();
+       sec[1] = NULL;
+       
+       secservice = rx_NewService (service->servicePort,
+                                   obj->serviceId,
+                                   "rxgk", 
+                                   sec, 1, 
+                                   RXGK_ExecuteRequest);
+       
+       secservice->destroyConnProc = free_context;
+       rx_setServiceRock(secservice, obj->principal);
+    }
+    return 0;
+}
+
+
+static struct rx_securityOps server_ops = {
+    server_Close,
+    server_NewConnection,
+    server_PreparePacket,
+    NULL,
+    server_CheckAuthentication,
+    server_CreateChallenge,
+    server_GetChallenge,
+    NULL,
+    server_CheckResponse,
+    server_CheckPacket,
+    server_DestroyConnection,
+    server_GetStats,
+    server_NewService,
+};
+
+struct rx_securityClass *
+rxgk_NewServerSecurityObject(/*rxgk_level*/ int min_level,
+                            const char *principal,
+                            void *appl_data,
+                            int (*get_key)(void *data, const char *principal,
+                                           int enctype, int kvno,
+                                           krb5_keyblock *key),
+                            int (*user_ok)(const char *name,
+                                           const char *realm,
+                                           int kvno),
+                            uint32_t serviceId)
+{
+    rxgk_serv_class *obj;
+    int ret;
+
+    if (get_key == NULL || principal == NULL)
+       return NULL;
+
+    ret = rxgk_server_init();
+    if (ret)
+       return NULL;
+
+    obj = (rxgk_serv_class *) osi_Alloc(sizeof(rxgk_serv_class));
+    obj->klass.refCount = 1;
+    obj->klass.ops = &server_ops;
+    obj->klass.privateData = (char *) obj;
+    
+    obj->min_level = min_level;
+    obj->appl_data = appl_data;
+    obj->get_key = get_key;
+    obj->user_ok = user_ok;
+    obj->principal = strdup(principal);
+    if (obj->principal == NULL) {
+       osi_Free(obj, sizeof(rxgk_serv_class));
+       return NULL;
+    }
+    obj->serviceId = serviceId;
+    
+    return &obj->klass;
+}
diff --git a/src/rxgk/rxgk_srpc.c b/src/rxgk/rxgk_srpc.c
new file mode 100644 (file)
index 0000000..c0090fb
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2002 - 2004, Stockholms universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ * 
+ * Redistribution is not permitted
+ */
+
+#include "rxgk_locl.h"
+
+RCSID("$Id$");
+
+#include <errno.h>
+
+#include <rx/rx.h>
+#include "rxgk_proto.h"
+#include "rxgk_proto.ss.h"
+
+/* XXX need to pthread lock these */
+krb5_context gk_context;
+static krb5_keyblock gk_key;
+krb5_crypto gk_crypto;
+static int gk_kvno;
+
+static int
+get_key(const char *keytab_string, const char *p, int enctype, int kvno,
+       krb5_keyblock *key)
+{
+    krb5_error_code ret;
+    krb5_keytab keytab;
+    krb5_principal princ;
+    char keytab_buf[256];
+    krb5_keytab_entry ktentry;
+
+    ret = krb5_parse_name(gk_context, p, &princ);
+    if (ret)
+       return ret;
+
+    if (keytab_string == NULL) {
+       ret = krb5_kt_default_name (gk_context, keytab_buf,sizeof(keytab_buf));
+       if (ret)
+           krb5_err(gk_context, 1, ret, "resolving keytab %s", keytab_string);
+       keytab_string = keytab_buf;
+    }
+    ret = krb5_kt_resolve(gk_context, keytab_string, &keytab);
+    if (ret)
+       krb5_err(gk_context, 1, ret, "resolving keytab %s", keytab_string);
+
+    ret = krb5_kt_get_entry (gk_context, keytab, princ, kvno,
+                            enctype, &ktentry);
+    if (ret)
+       krb5_err(gk_context, 1, ret, "krb5_kt_get_entry %s", p);
+
+    krb5_copy_keyblock_contents(gk_context, &ktentry.keyblock, key);
+    /* ktentry.vno */
+
+    krb5_kt_free_entry(gk_context, &ktentry);
+       
+    krb5_kt_close(gk_context, keytab);
+
+    krb5_free_principal(gk_context, princ);
+
+    return ret;
+}
+
+int
+rxgk_default_get_key(void *data, const char *p, int enctype, int kvno, 
+                    krb5_keyblock *key)
+{
+    int ret;
+
+    ret = rxgk_server_init();
+    if (ret)
+       return ret;
+
+    return get_key(NULL, p, enctype, kvno, key);
+}
+
+
+int
+rxgk_server_init(void)
+{
+    static int inited = 0;
+    int ret;
+
+    if (inited)
+       return 0;
+
+    if (krb5_init_context(&gk_context))
+       return EINVAL;
+
+    ret = get_key(NULL, "gkkey@L.NXS.SE", 0, 0, &gk_key); /* XXX */
+    if (ret) {
+       krb5_free_context(gk_context);
+       gk_context = NULL;
+       return ret;
+    }
+
+    ret = krb5_crypto_init(gk_context, &gk_key, gk_key.keytype,
+                          &gk_crypto);
+    if (ret) {
+       krb5_free_keyblock_contents(gk_context, &gk_key);
+       krb5_free_context(gk_context);
+       gk_context = NULL;
+       return ret;
+    }
+
+
+    inited = 1;
+
+    return 0;
+}
+
+static int
+build_auth_token(krb5_context context, const char *princ, 
+                int32_t start, int32_t end,
+                krb5_keyblock *key,
+                int session_enctype, 
+                void *session_key, size_t session_key_size,
+                int32_t *auth_token_kvno, RXGK_Token *auth_token)
+{
+    struct RXGK_AUTH_CRED cred;
+    krb5_data data;
+    void *ptr;
+    int sz, ret;
+
+    sz = RXGK_AUTH_CRED_MAX_SIZE;
+    ptr = malloc(sz);
+    if (ptr == NULL)
+       return ENOMEM;
+
+    cred.ac_version = RXGK_KEY_VERSION;
+    strlcpy(cred.ac_principal, princ, sizeof(cred.ac_principal));
+    cred.ac_starttime = start;
+    cred.ac_endtime = end;
+    cred.ac_enctype = session_enctype;
+    cred.ac_key.len = session_key_size;
+    cred.ac_key.val = session_key;
+
+    if (ydr_encode_RXGK_AUTH_CRED(&cred, ptr, &sz) == NULL) {
+       free(ptr);
+       return EINVAL;
+    }
+    sz = RXGK_AUTH_CRED_MAX_SIZE - sz;
+
+    ret = krb5_encrypt(context, gk_crypto, 0, ptr, sz, &data);
+    if (ret) {
+       free(ptr);
+       return ret;
+    }
+    
+    if (data.length > RXGK_AUTH_CRED_MAX_SIZE) {
+       free(ptr);
+       return EINVAL;
+    }
+    
+    memcpy(ptr, data.data, data.length);
+
+    auth_token->len = data.length;
+    auth_token->val = ptr;
+    *auth_token_kvno = gk_kvno;
+    
+    krb5_data_free(&data);
+
+    return 0;
+}
+
+int
+rxgk_decode_auth_token(void *val, size_t len, RXGK_AUTH_CRED *c)
+{
+    krb5_data data;
+    size_t sz;
+    int ret;
+
+    memset(c, 0, sizeof(*c));
+
+    ret = krb5_decrypt(gk_context, gk_crypto, 0, val, len, &data);
+    if (ret)
+       return ret;
+
+    sz = data.length;
+    if (ydr_decode_RXGK_AUTH_CRED(c, data.data, &sz) == NULL) {
+       if (c->ac_key.val)
+           free(c->ac_key.val);
+       memset(c, 0, sizeof(*c));
+       ret = RXGKBADTICKET;
+    }
+
+    krb5_data_free(&data);
+
+    return ret;
+}
+
+/* XXX share */
+
+static int
+decode_v5(krb5_context context,
+         int (*get_key)(void *appl_data, const char *p, int enctype,
+                        int kvno, krb5_keyblock *key),
+         void *appl_data,
+         const char *princ,
+         char *ticket,
+         int32_t ticket_len,
+         /* OUT parms */
+         krb5_principal *p,
+         krb5_keyblock *key,
+         int32_t *starts,
+         int32_t *expires)
+{
+    krb5_keyblock serv_key;
+    int code;
+    size_t siz;
+
+    Ticket t5;                 /* Must free */
+    EncTicketPart decr_part;   /* Must free */
+    krb5_data plain;           /* Must free */
+    krb5_crypto crypto;                /* Must free */
+
+    memset(&t5, 0x0, sizeof(t5));
+    memset(&decr_part, 0x0, sizeof(decr_part));
+    krb5_data_zero(&plain);
+    memset(&serv_key, 0, sizeof(serv_key));
+    crypto = NULL;
+
+    code = decode_Ticket(ticket, ticket_len, &t5, &siz);
+    if (code != 0)
+       goto bad_ticket;
+
+    code = (*get_key)(appl_data, princ, 
+                     t5.enc_part.etype, t5.tkt_vno, &serv_key);
+    if (code)
+       goto unknown_key;
+    
+    code = krb5_crypto_init (context, &serv_key, t5.enc_part.etype,
+                            &crypto);
+    krb5_free_keyblock_contents(context, &serv_key);
+    if (code)
+       goto bad_ticket;
+
+    /* Decrypt ticket */
+    code = krb5_decrypt(context,
+                       crypto,
+                       0,
+                       t5.enc_part.cipher.data,
+                       t5.enc_part.cipher.length,
+                       &plain);
+
+    if (code)
+       goto bad_ticket;
+    
+    /* Decode ticket */
+    code = decode_EncTicketPart(plain.data, plain.length, &decr_part, &siz);
+    if (code != 0)
+       goto bad_ticket;
+    
+    /* principal */
+    code = principalname2krb5_principal(p, decr_part.cname, decr_part.crealm);
+    if (code)
+       goto bad_ticket;
+    
+    /* Extract session key */
+    code = krb5_copy_keyblock_contents(context, &decr_part.key, key);
+    if (code)
+       goto bad_ticket;
+
+    /* Check lifetimes and host addresses, flags etc */
+    {
+       time_t now = time(0);   /* Use fast time package instead??? */
+       time_t start = decr_part.authtime;
+       if (decr_part.starttime)
+           start = *decr_part.starttime;
+       if (start - now > context->max_skew || decr_part.flags.invalid)
+           goto no_auth;
+       if (now > decr_part.endtime)
+           goto tkt_expired;
+       *starts = start;
+       *expires = decr_part.endtime;
+    }
+    
+#if 0
+    /* Check host addresses */
+#endif
+    
+ cleanup:
+    free_Ticket(&t5);
+    free_EncTicketPart(&decr_part);
+    krb5_data_free(&plain);
+    if (crypto)
+       krb5_crypto_destroy(context, crypto);
+    if (code) {
+       krb5_free_principal(context, *p);
+       *p = NULL;
+    }
+    return code;
+    
+ unknown_key:
+    code = RXGKUNKNOWNKEY;
+    goto cleanup;
+ no_auth:
+    code = RXGKNOAUTH;
+    goto cleanup;
+ tkt_expired:
+    code = RXGKEXPIRED;
+    goto cleanup;
+ bad_ticket:
+    code = RXGKBADTICKET;
+    goto cleanup;
+}
+
+int
+SRXGK_EstablishKrb5Context(struct rx_call *call,
+                          const RXGK_Token *token,
+                          const RXGK_Token *challage_token,
+                          RXGK_Token *reply_token,
+                          int32_t *auth_token_kvno,
+                          RXGK_Token *auth_token)
+{
+    krb5_principal principal;
+    krb5_keyblock key;
+    int32_t starts, expires;
+    char *cprinc, *sprinc;
+    void *session_key;
+    size_t session_key_size;
+    int session_enctype;
+    int ret;
+
+    ret = rxgk_server_init();
+    if (ret)
+       return ret;
+
+    if ((sprinc = rx_getServiceRock(call->conn->service)) == NULL)
+       return EINVAL;
+
+    session_key = NULL;
+
+    key.keyvalue.data = NULL;
+
+    auth_token->len = reply_token->len = 0;
+    auth_token->val = reply_token->val = NULL;
+
+    ret = decode_v5(gk_context, rxgk_default_get_key, NULL, sprinc, 
+                   token->val, token->len,
+                   &principal, &key, &starts, &expires);
+    if (ret)
+       goto out;
+
+    ret = rxk5_mutual_auth_server(gk_context,
+                                 &key,
+                                 challage_token,
+                                 &session_enctype,
+                                 &session_key, 
+                                 &session_key_size,
+                                 reply_token);
+    if (ret)
+       goto out;
+
+    ret = krb5_unparse_name(gk_context, principal, &cprinc);
+    if (ret)
+       goto out;
+
+    ret = build_auth_token(gk_context, cprinc, starts, expires, &key,
+                          session_enctype, session_key, session_key_size,
+                          auth_token_kvno, auth_token);
+
+    free(cprinc);
+
+ out:
+    if (session_key) {
+       memset(session_key, 0, session_key_size);
+       free(session_key);
+    }
+    if (key.keyvalue.data != NULL)
+       krb5_free_keyblock_contents(gk_context, &key);
+
+    if (ret) {
+       if (reply_token->val)
+           free(reply_token->val);
+       reply_token->len = 0;
+       reply_token->val = NULL;
+
+       if (auth_token->val)
+           free(auth_token->val);
+       auth_token->len = 0;
+       auth_token->val = NULL;
+    }
+
+    return ret;
+}
diff --git a/src/rxgk/test.xg b/src/rxgk/test.xg
new file mode 100644 (file)
index 0000000..e1731f3
--- /dev/null
@@ -0,0 +1,21 @@
+/* hej emacs det h{r {r en -*- c -*- fil */
+
+/*
+ * Copyright (c) 2002, Stockholms Universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ * 
+ * Redistribution is not permitted
+ */
+
+/* $Id$ */
+
+package TEST_
+
+const TEST_DEFAULT_PORT = 7009;
+
+const TEST_RXGK_SERVICE = 64000;
+
+const TEST_SERVICE_ID   = 10;
+
+get_hundraelva(OUT afs_int32 *foo, OUT string bar<100>) = 18;
diff --git a/src/rxgk/test_client.c b/src/rxgk/test_client.c
new file mode 100644 (file)
index 0000000..d0e4da9
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2002 - 2004, Stockholms universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ * 
+ * Redistribution is not permitted
+ */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+
+#include "rxgk_locl.h"
+#include "rxgk_proto.cs.h"
+#include "test.cs.h"
+
+RCSID("$Id$");
+
+/*
+ *
+ */
+
+static u_long
+str2addr (const char *s)
+{
+    struct in_addr server;
+    struct hostent *h;
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+    if (inet_addr(s) != INADDR_NONE)
+        return inet_addr(s);
+    h = gethostbyname (s);
+    if (h != NULL) {
+       memcpy (&server, h->h_addr_list[0], sizeof(server));
+       return server.s_addr;
+    }
+    return 0;
+}
+
+
+static int
+get_krb5_token(krb5_context ctx, krb5_keyblock **key, RXGK_Token *token)
+{
+    krb5_error_code ret;
+    krb5_creds in_creds, *out_creds;
+    krb5_ccache id;
+    char *realm = "L.NXS.SE";
+    int realm_len = strlen(realm);
+
+    memset(token, 0, sizeof(*token));
+
+    ret = krb5_cc_default (ctx, &id);
+    if (ret)
+       return ret;
+
+    memset(&in_creds, 0, sizeof(in_creds));
+    ret = krb5_build_principal(ctx, &in_creds.server,
+                              realm_len, realm, "afs", NULL);
+    if(ret)
+       return ret;
+    ret = krb5_build_principal(ctx, &in_creds.client,
+                              realm_len, realm, "lha", NULL);
+    if(ret){
+       krb5_free_principal(ctx, in_creds.server);
+       return ret;
+    }
+    in_creds.session.keytype = KEYTYPE_DES; /* XXX */
+    ret = krb5_get_credentials(ctx, 0, id, &in_creds, &out_creds);
+    krb5_free_principal(ctx, in_creds.server);
+    krb5_free_principal(ctx, in_creds.client);
+    if(ret) 
+       return ret;
+
+    token->val = malloc(out_creds->ticket.length);
+    if (token->val == NULL) {
+       krb5_free_creds(ctx, out_creds);
+       return ENOMEM;
+    }
+    token->len = out_creds->ticket.length;
+    memcpy(token->val, out_creds->ticket.data, out_creds->ticket.length);
+
+    ret = krb5_copy_keyblock(ctx, &out_creds->session, key);
+
+    krb5_free_creds(ctx, out_creds);
+
+    return ret;
+}
+
+/*
+ *
+ */
+
+static void
+test_est_context(krb5_context context, uint32_t addr, int port, 
+                RXGK_Token *ticket, krb5_keyblock *key)
+{
+    RXGK_Token auth_token;
+    krb5_keyblock skey;
+    int32_t kvno;
+    int ret;
+
+    /* kernel */
+
+    ret = rxgk5_get_auth_token(context, addr, port, 
+                              TEST_RXGK_SERVICE,
+                              ticket, &auth_token, key, &skey, &kvno);
+    if (ret)
+       errx(1, "rxgk5_get_auth_token: %d", ret);
+       
+    printf("EstablishKrb5Context succeeded "
+          "len: %d, version: %d, enctype: %d\n",
+          auth_token.len, kvno, skey.keytype);
+}
+
+static void
+test_rxgk_conn(krb5_context context, uint32_t addr, int port, 
+              RXGK_Token *ticket, krb5_keyblock *key)
+{
+    struct rx_securityClass *secobj;
+    struct rx_connection *conn;
+    int ret;
+    char bar[100];
+    int32_t a111;
+
+    secobj = rxgk_k5_NewClientSecurityObject(rxgk_crypt,
+                                            key,
+                                            0,
+                                            ticket->len,
+                                            ticket->val,
+                                            TEST_RXGK_SERVICE,
+                                            context);
+
+    conn = rx_NewConnection(addr, port, TEST_SERVICE_ID, secobj, 4);
+    if (conn == NULL)
+       errx(1, "NewConnection");
+
+    ret = TEST_get_hundraelva(conn, &a111, bar);
+
+    rx_DestroyConnection(conn);
+
+    if (ret)
+       errx(1, "TEST_get_hundraelva: %d", ret);
+
+    printf("get_hundraelva return %d (should be 111) (bar = \"%s\")\n",
+          (int)a111, bar);
+}
+
+
+/*
+ *
+ */
+
+int
+main(int argc, char **argv)
+{
+    RXGK_Token ticket;
+    krb5_context context;
+    krb5_keyblock *key;
+    int port, ret;
+    uint32_t addr;
+    char *saddr;
+    PROCESS pid;
+
+    setprogname(argv[0]);
+
+    port = htons(TEST_DEFAULT_PORT);
+    saddr = "127.0.0.1";
+
+    krb5_init_context(&context);
+
+    LWP_InitializeProcessSupport (LWP_NORMAL_PRIORITY, &pid);
+    
+    ret = rx_Init (0);
+    if (ret)
+       errx (1, "rx_Init failed");
+
+    addr = str2addr(saddr);
+
+    ret = get_krb5_token(context, &key, &ticket);
+    if (ret)
+       errx(1, "get_krb5_token: %d", ret);
+
+    if (0) {
+       test_est_context(context, addr, port, &ticket, key);
+    } else {
+       test_rxgk_conn(context, addr, port, &ticket, key);
+    }
+
+    rx_Finalize();
+
+    krb5_free_keyblock(context, key);
+    krb5_free_context(context);
+
+    return 0;
+}
+
diff --git a/src/rxgk/test_server.c b/src/rxgk/test_server.c
new file mode 100644 (file)
index 0000000..8b16929
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2002 - 2004, Stockholms universitet
+ * (Stockholm University, Stockholm Sweden)
+ * All rights reserved.
+ * 
+ * Redistribution is not permitted
+ */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <err.h>
+#include <netdb.h>
+
+#include "rxgk_locl.h"
+#include "rxgk_proto.ss.h"
+#include "test.ss.h"
+
+RCSID("$Id$");
+
+/*
+ *
+ */
+
+int
+STEST_get_hundraelva(struct rx_call *call, int32_t *foo, char *bar)
+{
+    *foo = 111;
+    snprintf(bar, 100, "hej");
+    return 0;
+}
+
+/*
+ *
+ */
+
+int
+main(int argc, char **argv)
+{
+    struct rx_securityClass *secureobj[5];
+    struct rx_service *service;
+    int secureindex;
+    PROCESS pid;
+    int port = htons(TEST_DEFAULT_PORT);
+    int ret;
+
+    LWP_InitializeProcessSupport (LWP_NORMAL_PRIORITY, &pid);
+
+    ret = rx_Init (port);
+    if (ret)
+       errx (1, "rx_Init failed");
+
+    secureindex = 5;
+    memset(secureobj, 0, sizeof(secureobj));
+    secureobj[4] = 
+       rxgk_NewServerSecurityObject(rxgk_auth,
+                                    "afs@L.NXS.SE",
+                                    NULL,
+                                    rxgk_default_get_key,
+                                    NULL,
+                                    TEST_RXGK_SERVICE);
+    
+    service = rx_NewService (0,
+                            TEST_SERVICE_ID,
+                            "rxgk-test", 
+                            secureobj, 
+                            secureindex, 
+                            TEST_ExecuteRequest);
+    if (service == NULL) 
+       errx(1, "Cant create server");
+
+    rx_StartServer(1) ;
+
+    return 0;
+}