From 5bc0d218f5ee1488301c641734fad636fb282bee Mon Sep 17 00:00:00 2001 From: =?utf8?q?Love=20H=C3=B6rnquist-=C3=85strand?= Date: Sun, 8 Aug 2004 20:21:33 +0000 Subject: [PATCH] rxgk-import-20040808 not actually hooked in yet, but getting it in so we can work with it. --- src/rxgk/Makefile.am | 80 ++++ src/rxgk/Makefile.in | 933 +++++++++++++++++++++++++++++++++++++++++ src/rxgk/README | 225 ++++++++++ src/rxgk/rxgk.h | 91 ++++ src/rxgk/rxgk_clnt.c | 417 ++++++++++++++++++ src/rxgk/rxgk_common.c | 392 +++++++++++++++++ src/rxgk/rxgk_crkrb.c | 255 +++++++++++ src/rxgk/rxgk_crlha.c | 447 ++++++++++++++++++++ src/rxgk/rxgk_crpc.c | 61 +++ src/rxgk/rxgk_info.c | 59 +++ src/rxgk/rxgk_locl.h | 164 ++++++++ src/rxgk/rxgk_proto.xg | 202 +++++++++ src/rxgk/rxgk_serv.c | 498 ++++++++++++++++++++++ src/rxgk/rxgk_srpc.c | 388 +++++++++++++++++ src/rxgk/test.xg | 21 + src/rxgk/test_client.c | 202 +++++++++ src/rxgk/test_server.c | 76 ++++ 17 files changed, 4511 insertions(+) create mode 100644 src/rxgk/Makefile.am create mode 100644 src/rxgk/Makefile.in create mode 100644 src/rxgk/README create mode 100644 src/rxgk/rxgk.h create mode 100644 src/rxgk/rxgk_clnt.c create mode 100644 src/rxgk/rxgk_common.c create mode 100644 src/rxgk/rxgk_crkrb.c create mode 100644 src/rxgk/rxgk_crlha.c create mode 100644 src/rxgk/rxgk_crpc.c create mode 100644 src/rxgk/rxgk_info.c create mode 100644 src/rxgk/rxgk_locl.h create mode 100644 src/rxgk/rxgk_proto.xg create mode 100644 src/rxgk/rxgk_serv.c create mode 100644 src/rxgk/rxgk_srpc.c create mode 100644 src/rxgk/test.xg create mode 100644 src/rxgk/test_client.c create mode 100644 src/rxgk/test_server.c diff --git a/src/rxgk/Makefile.am b/src/rxgk/Makefile.am new file mode 100644 index 000000000..f37753c88 --- /dev/null +++ b/src/rxgk/Makefile.am @@ -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 index 000000000..f2169d447 --- /dev/null +++ b/src/rxgk/Makefile.in @@ -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 index 000000000..e075edb80 --- /dev/null +++ b/src/rxgk/README @@ -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 index 000000000..8b398636f --- /dev/null +++ b/src/rxgk/rxgk.h @@ -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 index 000000000..5bcb2cea5 --- /dev/null +++ b/src/rxgk/rxgk_clnt.c @@ -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 index 000000000..7b4b6fd58 --- /dev/null +++ b/src/rxgk/rxgk_common.c @@ -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 + +#include +#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 index 000000000..805c240f3 --- /dev/null +++ b/src/rxgk/rxgk_crkrb.c @@ -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 + +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 index 000000000..d03453089 --- /dev/null +++ b/src/rxgk/rxgk_crlha.c @@ -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 +#include + +#include + +/* + * 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 index 000000000..09a660810 --- /dev/null +++ b/src/rxgk/rxgk_crpc.c @@ -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 +#include "rxgk_proto.h" +#include "rxgk_proto.cs.h" + +#include + +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 index 000000000..22f516413 --- /dev/null +++ b/src/rxgk/rxgk_info.c @@ -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 index 000000000..a85ffaef4 --- /dev/null +++ b/src/rxgk/rxgk_locl.h @@ -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 +#endif + +#include +#include +#include + +#include +#include + +#include +#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 +#include +#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 index 000000000..a02559f14 --- /dev/null +++ b/src/rxgk/rxgk_proto.xg @@ -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; + +/* + * + */ + +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; /* 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; +}; + +/* + * Rx auth cred equivalent + */ + +struct RXGK_AUTH_CRED { + afs_int32 ac_version; /* version of format of RXGK_AUTH_CRED */ + string ac_principal; /* prefixed with mech */ + afs_int32 ac_starttime; + afs_int32 ac_endtime; + afs_int32 ac_enctype; + opaque ac_key; +}; + +/* + * 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; + opaque rr_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; +}; + +struct RXGK_ReKey_Crypt { + afs_int32 rkc_version; + afs_int32 rkc_max_seq_num; + afs_int32 rkc_kvno; /* 16 bit number */ + opaque rkc_keycontribution; +}; + +/* rx transport key */ + +struct RXGK_rxtransport_key { + opaque client_keycontribution; + opaque server_keycontribution; +}; + +#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 index 000000000..0f70214a3 --- /dev/null +++ b/src/rxgk/rxgk_serv.c @@ -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 + +#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 index 000000000..c0090fbb3 --- /dev/null +++ b/src/rxgk/rxgk_srpc.c @@ -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 + +#include +#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 index 000000000..e1731f321 --- /dev/null +++ b/src/rxgk/test.xg @@ -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 index 000000000..d0e4da9e0 --- /dev/null +++ b/src/rxgk/test_client.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2002 - 2004, Stockholms universitet + * (Stockholm University, Stockholm Sweden) + * All rights reserved. + * + * Redistribution is not permitted + */ + +#include +#include +#include + +#include +#include +#include + +#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 index 000000000..8b169290f --- /dev/null +++ b/src/rxgk/test_server.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2002 - 2004, Stockholms universitet + * (Stockholm University, Stockholm Sweden) + * All rights reserved. + * + * Redistribution is not permitted + */ + +#include +#include +#include + +#include +#include + +#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; +} -- 2.39.5