diff options
Diffstat (limited to 'appl/test')
-rw-r--r-- | appl/test/Makefile.am | 42 | ||||
-rw-r--r-- | appl/test/Makefile.in | 856 | ||||
-rw-r--r-- | appl/test/common.c | 174 | ||||
-rw-r--r-- | appl/test/gss_common.c | 152 | ||||
-rw-r--r-- | appl/test/gss_common.h | 49 | ||||
-rw-r--r-- | appl/test/gssapi_client.c | 248 | ||||
-rw-r--r-- | appl/test/gssapi_server.c | 334 | ||||
-rw-r--r-- | appl/test/http_client.c | 504 | ||||
-rw-r--r-- | appl/test/nt_gss_client.c | 167 | ||||
-rw-r--r-- | appl/test/nt_gss_common.c | 131 | ||||
-rw-r--r-- | appl/test/nt_gss_common.h | 45 | ||||
-rw-r--r-- | appl/test/nt_gss_server.c | 247 | ||||
-rw-r--r-- | appl/test/tcp_client.c | 132 | ||||
-rw-r--r-- | appl/test/tcp_server.c | 168 | ||||
-rw-r--r-- | appl/test/test_locl.h | 88 | ||||
-rw-r--r-- | appl/test/uu_client.c | 193 | ||||
-rw-r--r-- | appl/test/uu_server.c | 210 |
17 files changed, 3740 insertions, 0 deletions
diff --git a/appl/test/Makefile.am b/appl/test/Makefile.am new file mode 100644 index 0000000..21f2013 --- /dev/null +++ b/appl/test/Makefile.am @@ -0,0 +1,42 @@ +# $Id: Makefile.am 20466 2007-04-20 08:29:05Z lha $ + +include $(top_srcdir)/Makefile.am.common + +noinst_PROGRAMS = tcp_client tcp_server gssapi_server gssapi_client \ + uu_server uu_client nt_gss_server nt_gss_client http_client + +tcp_client_SOURCES = tcp_client.c common.c test_locl.h + +tcp_server_SOURCES = tcp_server.c common.c test_locl.h + +gssapi_server_SOURCES = gssapi_server.c gss_common.c common.c \ + gss_common.h test_locl.h + +gssapi_client_SOURCES = gssapi_client.c gss_common.c common.c \ + gss_common.h test_locl.h + +http_client_SOURCES = http_client.c gss_common.c common.c \ + gss_common.h test_locl.h + +uu_server_SOURCES = uu_server.c common.c test_locl.h + +uu_client_SOURCES = uu_client.c common.c test_locl.h + +gssapi_server_LDADD = $(top_builddir)/lib/gssapi/libgssapi.la $(LDADD) + +gssapi_client_LDADD = $(gssapi_server_LDADD) + +http_client_LDADD = $(top_builddir)/lib/gssapi/libgssapi.la $(LDADD) + +nt_gss_client_SOURCES = nt_gss_client.c nt_gss_common.c nt_gss_common.h common.c + +nt_gss_server_SOURCES = nt_gss_server.c nt_gss_common.c nt_gss_common.h + +nt_gss_client_LDADD = $(gssapi_server_LDADD) + +nt_gss_server_LDADD = $(nt_gss_client_LDADD) + +LDADD = $(top_builddir)/lib/krb5/libkrb5.la \ + $(LIB_hcrypto) \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(LIB_roken) diff --git a/appl/test/Makefile.in b/appl/test/Makefile.in new file mode 100644 index 0000000..fb9e3688 --- /dev/null +++ b/appl/test/Makefile.in @@ -0,0 +1,856 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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: Makefile.am 20466 2007-04-20 08:29:05Z lha $ + +# $Id: Makefile.am.common 10998 2002-05-19 18:35:37Z joda $ + +# $Id: Makefile.am.common 22488 2008-01-21 11:47:22Z lha $ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +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 = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.am.common \ + $(top_srcdir)/cf/Makefile.am.common +noinst_PROGRAMS = tcp_client$(EXEEXT) tcp_server$(EXEEXT) \ + gssapi_server$(EXEEXT) gssapi_client$(EXEEXT) \ + uu_server$(EXEEXT) uu_client$(EXEEXT) nt_gss_server$(EXEEXT) \ + nt_gss_client$(EXEEXT) http_client$(EXEEXT) +subdir = appl/test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ + $(top_srcdir)/cf/auth-modules.m4 $(top_srcdir)/cf/autobuild.m4 \ + $(top_srcdir)/cf/broken-getaddrinfo.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/c-attribute.m4 \ + $(top_srcdir)/cf/capabilities.m4 \ + $(top_srcdir)/cf/check-compile-et.m4 \ + $(top_srcdir)/cf/check-getpwnam_r-posix.m4 \ + $(top_srcdir)/cf/check-man.m4 \ + $(top_srcdir)/cf/check-netinet-ip-and-tcp.m4 \ + $(top_srcdir)/cf/check-type-extra.m4 \ + $(top_srcdir)/cf/check-var.m4 $(top_srcdir)/cf/check-x.m4 \ + $(top_srcdir)/cf/check-xau.m4 $(top_srcdir)/cf/crypto.m4 \ + $(top_srcdir)/cf/db.m4 $(top_srcdir)/cf/destdirs.m4 \ + $(top_srcdir)/cf/dlopen.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/framework-security.m4 \ + $(top_srcdir)/cf/have-struct-field.m4 \ + $(top_srcdir)/cf/have-type.m4 $(top_srcdir)/cf/irix.m4 \ + $(top_srcdir)/cf/krb-bigendian.m4 \ + $(top_srcdir)/cf/krb-func-getlogin.m4 \ + $(top_srcdir)/cf/krb-ipv6.m4 $(top_srcdir)/cf/krb-prog-ln-s.m4 \ + $(top_srcdir)/cf/krb-readline.m4 \ + $(top_srcdir)/cf/krb-struct-spwd.m4 \ + $(top_srcdir)/cf/krb-struct-winsize.m4 \ + $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/mips-abi.m4 \ + $(top_srcdir)/cf/misc.m4 $(top_srcdir)/cf/need-proto.m4 \ + $(top_srcdir)/cf/osfc2.m4 $(top_srcdir)/cf/otp.m4 \ + $(top_srcdir)/cf/proto-compat.m4 $(top_srcdir)/cf/pthreads.m4 \ + $(top_srcdir)/cf/resolv.m4 $(top_srcdir)/cf/retsigtype.m4 \ + $(top_srcdir)/cf/roken-frag.m4 \ + $(top_srcdir)/cf/socket-wrapper.m4 $(top_srcdir)/cf/sunos.m4 \ + $(top_srcdir)/cf/telnet.m4 $(top_srcdir)/cf/test-package.m4 \ + $(top_srcdir)/cf/version-script.m4 $(top_srcdir)/cf/wflags.m4 \ + $(top_srcdir)/cf/win32.m4 $(top_srcdir)/cf/with-all.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_gssapi_client_OBJECTS = gssapi_client.$(OBJEXT) \ + gss_common.$(OBJEXT) common.$(OBJEXT) +gssapi_client_OBJECTS = $(am_gssapi_client_OBJECTS) +am__DEPENDENCIES_1 = +am__DEPENDENCIES_2 = $(top_builddir)/lib/krb5/libkrb5.la \ + $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \ + $(am__DEPENDENCIES_1) +am__DEPENDENCIES_3 = $(top_builddir)/lib/gssapi/libgssapi.la \ + $(am__DEPENDENCIES_2) +gssapi_client_DEPENDENCIES = $(am__DEPENDENCIES_3) +am_gssapi_server_OBJECTS = gssapi_server.$(OBJEXT) \ + gss_common.$(OBJEXT) common.$(OBJEXT) +gssapi_server_OBJECTS = $(am_gssapi_server_OBJECTS) +gssapi_server_DEPENDENCIES = $(top_builddir)/lib/gssapi/libgssapi.la \ + $(am__DEPENDENCIES_2) +am_http_client_OBJECTS = http_client.$(OBJEXT) gss_common.$(OBJEXT) \ + common.$(OBJEXT) +http_client_OBJECTS = $(am_http_client_OBJECTS) +http_client_DEPENDENCIES = $(top_builddir)/lib/gssapi/libgssapi.la \ + $(am__DEPENDENCIES_2) +am_nt_gss_client_OBJECTS = nt_gss_client.$(OBJEXT) \ + nt_gss_common.$(OBJEXT) common.$(OBJEXT) +nt_gss_client_OBJECTS = $(am_nt_gss_client_OBJECTS) +nt_gss_client_DEPENDENCIES = $(am__DEPENDENCIES_3) +am_nt_gss_server_OBJECTS = nt_gss_server.$(OBJEXT) \ + nt_gss_common.$(OBJEXT) +nt_gss_server_OBJECTS = $(am_nt_gss_server_OBJECTS) +am__DEPENDENCIES_4 = $(am__DEPENDENCIES_3) +nt_gss_server_DEPENDENCIES = $(am__DEPENDENCIES_4) +am_tcp_client_OBJECTS = tcp_client.$(OBJEXT) common.$(OBJEXT) +tcp_client_OBJECTS = $(am_tcp_client_OBJECTS) +tcp_client_LDADD = $(LDADD) +tcp_client_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \ + $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \ + $(am__DEPENDENCIES_1) +am_tcp_server_OBJECTS = tcp_server.$(OBJEXT) common.$(OBJEXT) +tcp_server_OBJECTS = $(am_tcp_server_OBJECTS) +tcp_server_LDADD = $(LDADD) +tcp_server_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \ + $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \ + $(am__DEPENDENCIES_1) +am_uu_client_OBJECTS = uu_client.$(OBJEXT) common.$(OBJEXT) +uu_client_OBJECTS = $(am_uu_client_OBJECTS) +uu_client_LDADD = $(LDADD) +uu_client_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \ + $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \ + $(am__DEPENDENCIES_1) +am_uu_server_OBJECTS = uu_server.$(OBJEXT) common.$(OBJEXT) +uu_server_OBJECTS = $(am_uu_server_OBJECTS) +uu_server_LDADD = $(LDADD) +uu_server_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \ + $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \ + $(am__DEPENDENCIES_1) +DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(gssapi_client_SOURCES) $(gssapi_server_SOURCES) \ + $(http_client_SOURCES) $(nt_gss_client_SOURCES) \ + $(nt_gss_server_SOURCES) $(tcp_client_SOURCES) \ + $(tcp_server_SOURCES) $(uu_client_SOURCES) \ + $(uu_server_SOURCES) +DIST_SOURCES = $(gssapi_client_SOURCES) $(gssapi_server_SOURCES) \ + $(http_client_SOURCES) $(nt_gss_client_SOURCES) \ + $(nt_gss_server_SOURCES) $(tcp_client_SOURCES) \ + $(tcp_server_SOURCES) $(uu_client_SOURCES) \ + $(uu_server_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CANONICAL_HOST = @CANONICAL_HOST@ +CATMAN = @CATMAN@ +CATMANEXT = @CATMANEXT@ +CC = @CC@ +CFLAGS = @CFLAGS@ +COMPILE_ET = @COMPILE_ET@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DBLIB = @DBLIB@ +DEFS = @DEFS@ +DIR_com_err = @DIR_com_err@ +DIR_hcrypto = @DIR_hcrypto@ +DIR_hdbdir = @DIR_hdbdir@ +DIR_roken = @DIR_roken@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +GROFF = @GROFF@ +INCLUDES_roken = @INCLUDES_roken@ +INCLUDE_hcrypto = @INCLUDE_hcrypto@ +INCLUDE_hesiod = @INCLUDE_hesiod@ +INCLUDE_krb4 = @INCLUDE_krb4@ +INCLUDE_openldap = @INCLUDE_openldap@ +INCLUDE_readline = @INCLUDE_readline@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_VERSION_SCRIPT = @LDFLAGS_VERSION_SCRIPT@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_roken = @LIBADD_roken@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@ +LIB_NDBM = @LIB_NDBM@ +LIB_XauFileName = @LIB_XauFileName@ +LIB_XauReadAuth = @LIB_XauReadAuth@ +LIB_XauWriteAuth = @LIB_XauWriteAuth@ +LIB_bswap16 = @LIB_bswap16@ +LIB_bswap32 = @LIB_bswap32@ +LIB_com_err = @LIB_com_err@ +LIB_com_err_a = @LIB_com_err_a@ +LIB_com_err_so = @LIB_com_err_so@ +LIB_crypt = @LIB_crypt@ +LIB_db_create = @LIB_db_create@ +LIB_dbm_firstkey = @LIB_dbm_firstkey@ +LIB_dbopen = @LIB_dbopen@ +LIB_dlopen = @LIB_dlopen@ +LIB_dn_expand = @LIB_dn_expand@ +LIB_door_create = @LIB_door_create@ +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_getpwnam_r = @LIB_getpwnam_r@ +LIB_getsockopt = @LIB_getsockopt@ +LIB_hcrypto = @LIB_hcrypto@ +LIB_hcrypto_a = @LIB_hcrypto_a@ +LIB_hcrypto_appl = @LIB_hcrypto_appl@ +LIB_hcrypto_so = @LIB_hcrypto_so@ +LIB_hesiod = @LIB_hesiod@ +LIB_hstrerror = @LIB_hstrerror@ +LIB_kdb = @LIB_kdb@ +LIB_krb4 = @LIB_krb4@ +LIB_loadquery = @LIB_loadquery@ +LIB_logout = @LIB_logout@ +LIB_logwtmp = @LIB_logwtmp@ +LIB_openldap = @LIB_openldap@ +LIB_openpty = @LIB_openpty@ +LIB_otp = @LIB_otp@ +LIB_pidfile = @LIB_pidfile@ +LIB_readline = @LIB_readline@ +LIB_res_ndestroy = @LIB_res_ndestroy@ +LIB_res_nsearch = @LIB_res_nsearch@ +LIB_res_search = @LIB_res_search@ +LIB_roken = @LIB_roken@ +LIB_security = @LIB_security@ +LIB_setsockopt = @LIB_setsockopt@ +LIB_socket = @LIB_socket@ +LIB_syslog = @LIB_syslog@ +LIB_tgetent = @LIB_tgetent@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NROFF = @NROFF@ +OBJEXT = @OBJEXT@ +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@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +VERSIONING = @VERSIONING@ +VOID_RETSIGTYPE = @VOID_RETSIGTYPE@ +WFLAGS = @WFLAGS@ +WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@ +WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dpagaix_cflags = @dpagaix_cflags@ +dpagaix_ldadd = @dpagaix_ldadd@ +dpagaix_ldflags = @dpagaix_ldflags@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUFFIXES = .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 +AM_CPPFLAGS = -I$(top_builddir)/include $(INCLUDES_roken) +@do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME +AM_CFLAGS = $(WFLAGS) +CP = cp +buildinclude = $(top_builddir)/include +LIB_getattr = @LIB_getattr@ +LIB_getpwent_r = @LIB_getpwent_r@ +LIB_odm_initialize = @LIB_odm_initialize@ +LIB_setpcred = @LIB_setpcred@ +HESIODLIB = @HESIODLIB@ +HESIODINCLUDE = @HESIODINCLUDE@ +NROFF_MAN = groff -mandoc -Tascii +LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS) +@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la \ +@KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la + +@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la +@KRB5_TRUE@LIB_tsasl = $(top_builddir)/lib/tsasl/libtsasl.la +@DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la +tcp_client_SOURCES = tcp_client.c common.c test_locl.h +tcp_server_SOURCES = tcp_server.c common.c test_locl.h +gssapi_server_SOURCES = gssapi_server.c gss_common.c common.c \ + gss_common.h test_locl.h + +gssapi_client_SOURCES = gssapi_client.c gss_common.c common.c \ + gss_common.h test_locl.h + +http_client_SOURCES = http_client.c gss_common.c common.c \ + gss_common.h test_locl.h + +uu_server_SOURCES = uu_server.c common.c test_locl.h +uu_client_SOURCES = uu_client.c common.c test_locl.h +gssapi_server_LDADD = $(top_builddir)/lib/gssapi/libgssapi.la $(LDADD) +gssapi_client_LDADD = $(gssapi_server_LDADD) +http_client_LDADD = $(top_builddir)/lib/gssapi/libgssapi.la $(LDADD) +nt_gss_client_SOURCES = nt_gss_client.c nt_gss_common.c nt_gss_common.h common.c +nt_gss_server_SOURCES = nt_gss_server.c nt_gss_common.c nt_gss_common.h +nt_gss_client_LDADD = $(gssapi_server_LDADD) +nt_gss_server_LDADD = $(nt_gss_client_LDADD) +LDADD = $(top_builddir)/lib/krb5/libkrb5.la \ + $(LIB_hcrypto) \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(LIB_roken) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .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 appl/test/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign --ignore-deps appl/test/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-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 +gssapi_client$(EXEEXT): $(gssapi_client_OBJECTS) $(gssapi_client_DEPENDENCIES) + @rm -f gssapi_client$(EXEEXT) + $(LINK) $(gssapi_client_OBJECTS) $(gssapi_client_LDADD) $(LIBS) +gssapi_server$(EXEEXT): $(gssapi_server_OBJECTS) $(gssapi_server_DEPENDENCIES) + @rm -f gssapi_server$(EXEEXT) + $(LINK) $(gssapi_server_OBJECTS) $(gssapi_server_LDADD) $(LIBS) +http_client$(EXEEXT): $(http_client_OBJECTS) $(http_client_DEPENDENCIES) + @rm -f http_client$(EXEEXT) + $(LINK) $(http_client_OBJECTS) $(http_client_LDADD) $(LIBS) +nt_gss_client$(EXEEXT): $(nt_gss_client_OBJECTS) $(nt_gss_client_DEPENDENCIES) + @rm -f nt_gss_client$(EXEEXT) + $(LINK) $(nt_gss_client_OBJECTS) $(nt_gss_client_LDADD) $(LIBS) +nt_gss_server$(EXEEXT): $(nt_gss_server_OBJECTS) $(nt_gss_server_DEPENDENCIES) + @rm -f nt_gss_server$(EXEEXT) + $(LINK) $(nt_gss_server_OBJECTS) $(nt_gss_server_LDADD) $(LIBS) +tcp_client$(EXEEXT): $(tcp_client_OBJECTS) $(tcp_client_DEPENDENCIES) + @rm -f tcp_client$(EXEEXT) + $(LINK) $(tcp_client_OBJECTS) $(tcp_client_LDADD) $(LIBS) +tcp_server$(EXEEXT): $(tcp_server_OBJECTS) $(tcp_server_DEPENDENCIES) + @rm -f tcp_server$(EXEEXT) + $(LINK) $(tcp_server_OBJECTS) $(tcp_server_LDADD) $(LIBS) +uu_client$(EXEEXT): $(uu_client_OBJECTS) $(uu_client_DEPENDENCIES) + @rm -f uu_client$(EXEEXT) + $(LINK) $(uu_client_OBJECTS) $(uu_client_LDADD) $(LIBS) +uu_server$(EXEEXT): $(uu_server_OBJECTS) $(uu_server_DEPENDENCIES) + @rm -f uu_server$(EXEEXT) + $(LINK) $(uu_server_OBJECTS) $(uu_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 + +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; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +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) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + 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 $(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: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || 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-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook + +install-dvi: install-dvi-am + +install-exec-am: + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +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: + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook + +.MAKE: install-am install-data-am install-exec-am install-strip \ + uninstall-am + +.PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \ + clean clean-generic clean-libtool clean-noinstPROGRAMS ctags \ + dist-hook 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-hook install-dvi install-dvi-am \ + install-exec install-exec-am install-exec-hook install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + 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-hook + + +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) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ) $(nobase_include_HEADERS) + @foo='$(include_HEADERS) $(dist_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 ; \ + foo='$(nobase_include_HEADERS)'; \ + for f in $$foo; do \ + if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ + else file="$$f"; fi; \ + $(mkdir_p) $(buildinclude)/`dirname $$f` ; \ + 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)' = "no-check-local"; then \ + foo=''; elif 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 && ./$$i --help) > /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 || exit 1; \ + 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: + $(SHELL) $(top_srcdir)/cf/install-catman.sh install "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) + +uninstall-cat-mans: + $(SHELL) $(top_srcdir)/cf/install-catman.sh uninstall "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) + +install-data-hook: install-cat-mans +uninstall-hook: uninstall-cat-mans + +.et.h: + $(COMPILE_ET) $< +.et.c: + $(COMPILE_ET) $< + +# +# Useful target for debugging +# + +check-valgrind: + tobjdir=`cd $(top_builddir) && pwd` ; \ + tsrcdir=`cd $(top_srcdir) && pwd` ; \ + env TESTS_ENVIRONMENT="$${tobjdir}/libtool --mode execute valgrind --leak-check=full --trace-children=yes --quiet -q --num-callers=30 --suppressions=$${tsrcdir}/cf/valgrind-suppressions" make check + +# +# Target to please samba build farm, builds distfiles in-tree. +# Will break when automake changes... +# + +distdir-in-tree: $(DISTFILES) $(INFO_DEPS) + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" != .; then \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) distdir-in-tree) ; \ + fi ; \ + done +# 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/appl/test/common.c b/appl/test/common.c new file mode 100644 index 0000000..595c828 --- /dev/null +++ b/appl/test/common.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1997 - 2000 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 "test_locl.h" + +RCSID("$Id: common.c 12796 2003-09-09 03:38:04Z lha $"); + +static int help_flag; +static int version_flag; +static char *port_str; +static char *keytab_str; +krb5_keytab keytab; +char *service = SERVICE; +char *mech = "krb5"; +int fork_flag; + +static struct getargs args[] = { + { "port", 'p', arg_string, &port_str, "port to listen to", "port" }, + { "service", 's', arg_string, &service, "service to use", "service" }, + { "keytab", 'k', arg_string, &keytab_str, "keytab to use", "keytab" }, + { "mech", 'm', arg_string, &mech, "gssapi mech to use", "mech" }, + { "fork", 'f', arg_flag, &fork_flag, "do fork" }, + { "help", 'h', arg_flag, &help_flag }, + { "version", 0, arg_flag, &version_flag } +}; + +static int num_args = sizeof(args) / sizeof(args[0]); + +static void +server_usage(int code, struct getargs *args, int num_args) +{ + arg_printusage(args, num_args, NULL, ""); + exit(code); +} + +static void +client_usage(int code, struct getargs *args, int num_args) +{ + arg_printusage(args, num_args, NULL, "host"); + exit(code); +} + + +static int +common_setup(krb5_context *context, int *argc, char **argv, + void (*usage)(int, struct getargs*, int)) +{ + int port = 0; + *argc = krb5_program_setup(context, *argc, argv, args, num_args, usage); + + if(help_flag) + (*usage)(0, args, num_args); + if(version_flag) { + print_version(NULL); + exit(0); + } + + if(port_str){ + struct servent *s = roken_getservbyname(port_str, "tcp"); + if(s) + port = s->s_port; + else { + char *ptr; + + port = strtol (port_str, &ptr, 10); + if (port == 0 && ptr == port_str) + errx (1, "Bad port `%s'", port_str); + port = htons(port); + } + } + + if (port == 0) + port = krb5_getportbyname (*context, PORT, "tcp", 4711); + + return port; +} + +int +server_setup(krb5_context *context, int argc, char **argv) +{ + int port = common_setup(context, &argc, argv, server_usage); + krb5_error_code ret; + + if(argv[argc] != NULL) + server_usage(1, args, num_args); + if (keytab_str != NULL) + ret = krb5_kt_resolve (*context, keytab_str, &keytab); + else + ret = krb5_kt_default (*context, &keytab); + if (ret) + krb5_err (*context, 1, ret, "krb5_kt_resolve/default"); + return port; +} + +int +client_setup(krb5_context *context, int *argc, char **argv) +{ + int optind = *argc; + int port = common_setup(context, &optind, argv, client_usage); + if(*argc - optind != 1) + client_usage(1, args, num_args); + *argc = optind; + return port; +} + +int +client_doit (const char *hostname, int port, const char *service, + int (*func)(int, const char *hostname, const char *service)) +{ + struct addrinfo *ai, *a; + struct addrinfo hints; + int error; + char portstr[NI_MAXSERV]; + + memset (&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + snprintf (portstr, sizeof(portstr), "%u", ntohs(port)); + + error = getaddrinfo (hostname, portstr, &hints, &ai); + if (error) { + errx (1, "%s: %s", hostname, gai_strerror(error)); + return -1; + } + + for (a = ai; a != NULL; a = a->ai_next) { + int s; + + s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); + if (s < 0) + continue; + if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { + warn ("connect(%s)", hostname); + close (s); + continue; + } + freeaddrinfo (ai); + return (*func) (s, hostname, service); + } + warnx ("failed to contact %s", hostname); + freeaddrinfo (ai); + return 1; +} diff --git a/appl/test/gss_common.c b/appl/test/gss_common.c new file mode 100644 index 0000000..4c80e54 --- /dev/null +++ b/appl/test/gss_common.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1997 - 2000 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 "test_locl.h" +#include <gssapi.h> +#include "gss_common.h" +RCSID("$Id: gss_common.c 19937 2007-01-16 21:56:01Z lha $"); + +void +write_token (int sock, gss_buffer_t buf) +{ + uint32_t len, net_len; + OM_uint32 min_stat; + + len = buf->length; + + net_len = htonl(len); + + if (net_write (sock, &net_len, 4) != 4) + err (1, "write"); + if (net_write (sock, buf->value, len) != len) + err (1, "write"); + + gss_release_buffer (&min_stat, buf); +} + +static void +enet_read(int fd, void *buf, size_t len) +{ + ssize_t ret; + + ret = net_read (fd, buf, len); + if (ret == 0) + errx (1, "EOF in read"); + else if (ret < 0) + errx (1, "read"); +} + +void +read_token (int sock, gss_buffer_t buf) +{ + uint32_t len, net_len; + + enet_read (sock, &net_len, 4); + len = ntohl(net_len); + buf->length = len; + buf->value = emalloc(len); + enet_read (sock, buf->value, len); +} + +void +gss_print_errors (int min_stat) +{ + OM_uint32 new_stat; + OM_uint32 msg_ctx = 0; + gss_buffer_desc status_string; + OM_uint32 ret; + + do { + ret = gss_display_status (&new_stat, + min_stat, + GSS_C_MECH_CODE, + GSS_C_NO_OID, + &msg_ctx, + &status_string); + fprintf (stderr, "%.*s\n", (int)status_string.length, + (char *)status_string.value); + gss_release_buffer (&new_stat, &status_string); + } while (!GSS_ERROR(ret) && msg_ctx != 0); +} + +void +gss_verr(int exitval, int status, const char *fmt, va_list ap) +{ + vwarnx (fmt, ap); + gss_print_errors (status); + exit (exitval); +} + +void +gss_err(int exitval, int status, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + gss_verr (exitval, status, fmt, args); + va_end(args); +} + +gss_OID +select_mech(const char *mech) +{ + if (strcasecmp(mech, "krb5") == 0) + return GSS_KRB5_MECHANISM; + else if (strcasecmp(mech, "spnego") == 0) + return GSS_SPNEGO_MECHANISM; + else if (strcasecmp(mech, "no-oid") == 0) + return GSS_C_NO_OID; + else + errx (1, "Unknown mechanism '%s' (spnego, krb5, no-oid)", mech); +} + +void +print_gss_name(const char *prefix, gss_name_t name) +{ + OM_uint32 maj_stat, min_stat; + gss_buffer_desc name_token; + + maj_stat = gss_display_name (&min_stat, + name, + &name_token, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_display_name"); + + fprintf (stderr, "%s `%.*s'\n", prefix, + (int)name_token.length, + (char *)name_token.value); + + gss_release_buffer (&min_stat, &name_token); + +} diff --git a/appl/test/gss_common.h b/appl/test/gss_common.h new file mode 100644 index 0000000..598ac8c --- /dev/null +++ b/appl/test/gss_common.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1997, 1998, 1999 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: gss_common.h 14661 2005-03-19 03:13:14Z lha $ */ + +void write_token (int sock, gss_buffer_t buf); +void read_token (int sock, gss_buffer_t buf); + +void gss_print_errors (int min_stat); + +void gss_verr(int exitval, int status, const char *fmt, va_list ap) + __attribute__ ((format (printf, 3, 0))); + +void gss_err(int exitval, int status, const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))); + +gss_OID select_mech(const char *); + +void print_gss_name(const char *, gss_name_t); diff --git a/appl/test/gssapi_client.c b/appl/test/gssapi_client.c new file mode 100644 index 0000000..d10fc57 --- /dev/null +++ b/appl/test/gssapi_client.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1997 - 2000 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 "test_locl.h" +#include <gssapi.h> +#include "gss_common.h" +RCSID("$Id: gssapi_client.c 21521 2007-07-12 13:13:40Z lha $"); + +static int +do_trans (int sock, gss_ctx_id_t context_hdl) +{ + OM_uint32 maj_stat, min_stat; + gss_buffer_desc real_input_token, real_output_token; + gss_buffer_t input_token = &real_input_token, + output_token = &real_output_token; + + /* get_mic */ + + input_token->length = 3; + input_token->value = strdup("hej"); + + maj_stat = gss_get_mic(&min_stat, + context_hdl, + GSS_C_QOP_DEFAULT, + input_token, + output_token); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_get_mic"); + + write_token (sock, input_token); + write_token (sock, output_token); + + /* wrap */ + + input_token->length = 7; + input_token->value = "hemligt"; + + maj_stat = gss_wrap (&min_stat, + context_hdl, + 0, + GSS_C_QOP_DEFAULT, + input_token, + NULL, + output_token); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_wrap"); + + write_token (sock, output_token); + + maj_stat = gss_wrap (&min_stat, + context_hdl, + 1, + GSS_C_QOP_DEFAULT, + input_token, + NULL, + output_token); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_wrap"); + + write_token (sock, output_token); + + return 0; +} + +static int +proto (int sock, const char *hostname, const char *service) +{ + struct sockaddr_in remote, local; + socklen_t addrlen; + + int context_established = 0; + gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; + gss_buffer_desc real_input_token, real_output_token; + gss_buffer_t input_token = &real_input_token, + output_token = &real_output_token; + OM_uint32 maj_stat, min_stat; + gss_name_t server; + gss_buffer_desc name_token; + struct gss_channel_bindings_struct input_chan_bindings; + u_char init_buf[4]; + u_char acct_buf[4]; + gss_OID mech_oid; + char *str; + + mech_oid = select_mech(mech); + + name_token.length = asprintf (&str, + "%s@%s", service, hostname); + if (str == NULL) + errx(1, "malloc - out of memory"); + name_token.value = str; + + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_HOSTBASED_SERVICE, + &server); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, + "Error importing name `%s@%s':\n", service, hostname); + + addrlen = sizeof(local); + if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 + || addrlen != sizeof(local)) + err (1, "getsockname(%s)", hostname); + + addrlen = sizeof(remote); + if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 + || addrlen != sizeof(remote)) + err (1, "getpeername(%s)", hostname); + + input_token->length = 0; + output_token->length = 0; + + input_chan_bindings.initiator_addrtype = GSS_C_AF_INET; + input_chan_bindings.initiator_address.length = 4; + init_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF; + init_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF; + init_buf[2] = (local.sin_addr.s_addr >> 8) & 0xFF; + init_buf[3] = (local.sin_addr.s_addr >> 0) & 0xFF; + input_chan_bindings.initiator_address.value = init_buf; + + input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET; + input_chan_bindings.acceptor_address.length = 4; + acct_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF; + acct_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF; + acct_buf[2] = (remote.sin_addr.s_addr >> 8) & 0xFF; + acct_buf[3] = (remote.sin_addr.s_addr >> 0) & 0xFF; + input_chan_bindings.acceptor_address.value = acct_buf; + +#if 0 + input_chan_bindings.application_data.value = emalloc(4); + * (unsigned short*)input_chan_bindings.application_data.value = local.sin_port; + * ((unsigned short *)input_chan_bindings.application_data.value + 1) = remote.sin_port; + input_chan_bindings.application_data.length = 4; +#else + input_chan_bindings.application_data.length = 0; + input_chan_bindings.application_data.value = NULL; +#endif + + while(!context_established) { + maj_stat = + gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + &context_hdl, + server, + mech_oid, + GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG + | GSS_C_DELEG_FLAG, + 0, + &input_chan_bindings, + input_token, + NULL, + output_token, + NULL, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_init_sec_context"); + if (output_token->length != 0) + write_token (sock, output_token); + if (GSS_ERROR(maj_stat)) { + if (context_hdl != GSS_C_NO_CONTEXT) + gss_delete_sec_context (&min_stat, + &context_hdl, + GSS_C_NO_BUFFER); + break; + } + if (maj_stat & GSS_S_CONTINUE_NEEDED) { + read_token (sock, input_token); + } else { + context_established = 1; + } + + } + if (fork_flag) { + pid_t pid; + int pipefd[2]; + + if (pipe (pipefd) < 0) + err (1, "pipe"); + + pid = fork (); + if (pid < 0) + err (1, "fork"); + if (pid != 0) { + gss_buffer_desc buf; + + maj_stat = gss_export_sec_context (&min_stat, + &context_hdl, + &buf); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_export_sec_context"); + write_token (pipefd[1], &buf); + exit (0); + } else { + gss_ctx_id_t context_hdl; + gss_buffer_desc buf; + + close (pipefd[1]); + read_token (pipefd[0], &buf); + close (pipefd[0]); + maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_import_sec_context"); + gss_release_buffer (&min_stat, &buf); + return do_trans (sock, context_hdl); + } + } else { + return do_trans (sock, context_hdl); + } +} + +int +main(int argc, char **argv) +{ + krb5_context context; /* XXX */ + int port = client_setup(&context, &argc, argv); + return client_doit (argv[argc], port, service, proto); +} diff --git a/appl/test/gssapi_server.c b/appl/test/gssapi_server.c new file mode 100644 index 0000000..e63a2bc --- /dev/null +++ b/appl/test/gssapi_server.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 1997 - 2000 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 "test_locl.h" +#include <gssapi.h> +#include "gss_common.h" +RCSID("$Id: gssapi_server.c 14762 2005-04-10 14:47:41Z lha $"); + +static int +process_it(int sock, + gss_ctx_id_t context_hdl, + gss_name_t client_name + ) +{ + OM_uint32 maj_stat, min_stat; + gss_buffer_desc real_input_token, real_output_token; + gss_buffer_t input_token = &real_input_token, + output_token = &real_output_token; + gss_name_t server_name; + int conf_flag; + + print_gss_name("User is", client_name); + + maj_stat = gss_inquire_context(&min_stat, + context_hdl, + NULL, + &server_name, + NULL, + NULL, + NULL, + NULL, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_inquire_context"); + + print_gss_name("Server is", server_name); + + maj_stat = gss_release_name(&min_stat, &server_name); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_release_name"); + + /* gss_verify_mic */ + + read_token (sock, input_token); + read_token (sock, output_token); + + maj_stat = gss_verify_mic (&min_stat, + context_hdl, + input_token, + output_token, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_verify_mic"); + + fprintf (stderr, "gss_verify_mic: %.*s\n", (int)input_token->length, + (char *)input_token->value); + + gss_release_buffer (&min_stat, input_token); + gss_release_buffer (&min_stat, output_token); + + /* gss_unwrap */ + + read_token (sock, input_token); + + maj_stat = gss_unwrap (&min_stat, + context_hdl, + input_token, + output_token, + &conf_flag, + NULL); + if(GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_unwrap"); + + fprintf (stderr, "gss_unwrap: %.*s %s\n", (int)output_token->length, + (char *)output_token->value, + conf_flag ? "CONF" : "INT"); + + gss_release_buffer (&min_stat, input_token); + gss_release_buffer (&min_stat, output_token); + + read_token (sock, input_token); + + maj_stat = gss_unwrap (&min_stat, + context_hdl, + input_token, + output_token, + &conf_flag, + NULL); + if(GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_unwrap"); + + fprintf (stderr, "gss_unwrap: %.*s %s\n", (int)output_token->length, + (char *)output_token->value, + conf_flag ? "CONF" : "INT"); + + gss_release_buffer (&min_stat, input_token); + gss_release_buffer (&min_stat, output_token); + + return 0; +} + +static int +proto (int sock, const char *service) +{ + struct sockaddr_in remote, local; + socklen_t addrlen; + gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; + gss_buffer_desc real_input_token, real_output_token; + gss_buffer_t input_token = &real_input_token, + output_token = &real_output_token; + OM_uint32 maj_stat, min_stat; + gss_name_t client_name; + struct gss_channel_bindings_struct input_chan_bindings; + gss_cred_id_t delegated_cred_handle = NULL; + krb5_ccache ccache; + u_char init_buf[4]; + u_char acct_buf[4]; + gss_OID mech_oid; + char *mech, *p; + + addrlen = sizeof(local); + if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 + || addrlen != sizeof(local)) + err (1, "getsockname)"); + + addrlen = sizeof(remote); + if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 + || addrlen != sizeof(remote)) + err (1, "getpeername"); + + input_chan_bindings.initiator_addrtype = GSS_C_AF_INET; + input_chan_bindings.initiator_address.length = 4; + init_buf[0] = (remote.sin_addr.s_addr >> 24) & 0xFF; + init_buf[1] = (remote.sin_addr.s_addr >> 16) & 0xFF; + init_buf[2] = (remote.sin_addr.s_addr >> 8) & 0xFF; + init_buf[3] = (remote.sin_addr.s_addr >> 0) & 0xFF; + + input_chan_bindings.initiator_address.value = init_buf; + input_chan_bindings.acceptor_addrtype = GSS_C_AF_INET; + + input_chan_bindings.acceptor_address.length = 4; + acct_buf[0] = (local.sin_addr.s_addr >> 24) & 0xFF; + acct_buf[1] = (local.sin_addr.s_addr >> 16) & 0xFF; + acct_buf[2] = (local.sin_addr.s_addr >> 8) & 0xFF; + acct_buf[3] = (local.sin_addr.s_addr >> 0) & 0xFF; + input_chan_bindings.acceptor_address.value = acct_buf; + input_chan_bindings.application_data.value = emalloc(4); +#if 0 + * (unsigned short *)input_chan_bindings.application_data.value = + remote.sin_port; + * ((unsigned short *)input_chan_bindings.application_data.value + 1) = + local.sin_port; + input_chan_bindings.application_data.length = 4; +#else + input_chan_bindings.application_data.length = 0; + input_chan_bindings.application_data.value = NULL; +#endif + + delegated_cred_handle = GSS_C_NO_CREDENTIAL; + + do { + read_token (sock, input_token); + maj_stat = + gss_accept_sec_context (&min_stat, + &context_hdl, + GSS_C_NO_CREDENTIAL, + input_token, + &input_chan_bindings, + &client_name, + &mech_oid, + output_token, + NULL, + NULL, + &delegated_cred_handle); + if(GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_accept_sec_context"); + if (output_token->length != 0) + write_token (sock, output_token); + if (GSS_ERROR(maj_stat)) { + if (context_hdl != GSS_C_NO_CONTEXT) + gss_delete_sec_context (&min_stat, + &context_hdl, + GSS_C_NO_BUFFER); + break; + } + } while(maj_stat & GSS_S_CONTINUE_NEEDED); + + p = (char *)mech_oid->elements; + if (mech_oid->length == GSS_KRB5_MECHANISM->length + && memcmp(p, GSS_KRB5_MECHANISM->elements, mech_oid->length) == 0) + mech = "Kerberos 5"; + else if (mech_oid->length == GSS_SPNEGO_MECHANISM->length + && memcmp(p, GSS_SPNEGO_MECHANISM->elements, mech_oid->length) == 0) + mech = "SPNEGO"; /* XXX Silly, wont show up */ + else + mech = "Unknown"; + + printf("Using mech: %s\n", mech); + + if (delegated_cred_handle != GSS_C_NO_CREDENTIAL) { + krb5_context context; + + printf("Delegated cred found\n"); + + maj_stat = krb5_init_context(&context); + maj_stat = krb5_cc_resolve(context, "FILE:/tmp/krb5cc_test", &ccache); + maj_stat = gss_krb5_copy_ccache(&min_stat, + delegated_cred_handle, + ccache); + if (maj_stat == 0) { + krb5_principal p; + maj_stat = krb5_cc_get_principal(context, ccache, &p); + if (maj_stat == 0) { + char *name; + maj_stat = krb5_unparse_name(context, p, &name); + if (maj_stat == 0) { + printf("Delegated user is: `%s'\n", name); + free(name); + } + krb5_free_principal(context, p); + } + } + krb5_cc_close(context, ccache); + gss_release_cred(&min_stat, &delegated_cred_handle); + } + + if (fork_flag) { + pid_t pid; + int pipefd[2]; + + if (pipe (pipefd) < 0) + err (1, "pipe"); + + pid = fork (); + if (pid < 0) + err (1, "fork"); + if (pid != 0) { + gss_buffer_desc buf; + + maj_stat = gss_export_sec_context (&min_stat, + &context_hdl, + &buf); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_export_sec_context"); + write_token (pipefd[1], &buf); + exit (0); + } else { + gss_ctx_id_t context_hdl; + gss_buffer_desc buf; + + close (pipefd[1]); + read_token (pipefd[0], &buf); + close (pipefd[0]); + maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_import_sec_context"); + gss_release_buffer (&min_stat, &buf); + return process_it (sock, context_hdl, client_name); + } + } else { + return process_it (sock, context_hdl, client_name); + } +} + +static int +doit (int port, const char *service) +{ + int sock, sock2; + struct sockaddr_in my_addr; + int one = 1; + + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) + err (1, "socket"); + + memset (&my_addr, 0, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_port = port; + my_addr.sin_addr.s_addr = INADDR_ANY; + + if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&one, sizeof(one)) < 0) + warn ("setsockopt SO_REUSEADDR"); + + if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) + err (1, "bind"); + + if (listen (sock, 1) < 0) + err (1, "listen"); + + sock2 = accept (sock, NULL, NULL); + if (sock2 < 0) + err (1, "accept"); + + return proto (sock2, service); +} + +int +main(int argc, char **argv) +{ + krb5_context context = NULL; /* XXX */ + int port = server_setup(&context, argc, argv); + return doit (port, service); +} diff --git a/appl/test/http_client.c b/appl/test/http_client.c new file mode 100644 index 0000000..074ba37 --- /dev/null +++ b/appl/test/http_client.c @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2003 - 2005 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 "test_locl.h" +#include <gssapi.h> +#include "gss_common.h" +#include <base64.h> + +RCSID("$Id: http_client.c 14861 2005-04-20 10:38:37Z lha $"); + +/* + * A simplistic client implementing draft-brezak-spnego-http-04.txt + */ + +static int +do_connect (const char *hostname, const char *port) +{ + struct addrinfo *ai, *a; + struct addrinfo hints; + int error; + int s = -1; + + memset (&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + + error = getaddrinfo (hostname, port, &hints, &ai); + if (error) + errx (1, "getaddrinfo(%s): %s", hostname, gai_strerror(error)); + + for (a = ai; a != NULL; a = a->ai_next) { + s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); + if (s < 0) + continue; + if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { + warn ("connect(%s)", hostname); + close (s); + continue; + } + break; + } + freeaddrinfo (ai); + if (a == NULL) + errx (1, "failed to contact %s", hostname); + + return s; +} + +static void +fdprintf(int s, const char *fmt, ...) +{ + size_t len; + ssize_t ret; + va_list ap; + char *str, *buf; + + va_start(ap, fmt); + vasprintf(&str, fmt, ap); + va_end(ap); + + if (str == NULL) + errx(1, "vasprintf"); + + buf = str; + len = strlen(buf); + while (len) { + ret = write(s, buf, len); + if (ret == 0) + err(1, "connection closed"); + else if (ret < 0) + err(1, "error"); + len -= ret; + buf += ret; + } + free(str); +} + +static int help_flag; +static int version_flag; +static int verbose_flag; +static int mutual_flag = 1; +static int delegate_flag; +static char *port_str = "http"; +static char *gss_service = "HTTP"; + +static struct getargs http_args[] = { + { "verbose", 'v', arg_flag, &verbose_flag, "verbose logging", }, + { "port", 'p', arg_string, &port_str, "port to connect to", "port" }, + { "delegate", 0, arg_flag, &delegate_flag, "gssapi delegate credential" }, + { "gss-service", 's', arg_string, &gss_service, "gssapi service to use", + "service" }, + { "mech", 'm', arg_string, &mech, "gssapi mech to use", "mech" }, + { "mutual", 0, arg_negative_flag, &mutual_flag, "no gssapi mutual auth" }, + { "help", 'h', arg_flag, &help_flag }, + { "version", 0, arg_flag, &version_flag } +}; + +static int num_http_args = sizeof(http_args) / sizeof(http_args[0]); + +static void +usage(int code) +{ + arg_printusage(http_args, num_http_args, NULL, "host [page]"); + exit(code); +} + +/* + * + */ + +struct http_req { + char *response; + char **headers; + int num_headers; + void *body; + size_t body_size; +}; + + +static void +http_req_zero(struct http_req *req) +{ + req->response = NULL; + req->headers = NULL; + req->num_headers = 0; + req->body = NULL; + req->body_size = 0; +} + +static void +http_req_free(struct http_req *req) +{ + int i; + + free(req->response); + for (i = 0; i < req->num_headers; i++) + free(req->headers[i]); + free(req->headers); + free(req->body); + http_req_zero(req); +} + +static const char * +http_find_header(struct http_req *req, const char *header) +{ + int i, len = strlen(header); + + for (i = 0; i < req->num_headers; i++) { + if (strncasecmp(header, req->headers[i], len) == 0) { + return req->headers[i] + len + 1; + } + } + return NULL; +} + + +static int +http_query(const char *host, const char *page, + char **headers, int num_headers, struct http_req *req) +{ + enum { RESPONSE, HEADER, BODY } state; + ssize_t ret; + char in_buf[1024], *in_ptr = in_buf; + size_t in_len = 0; + int s, i; + + http_req_zero(req); + + s = do_connect(host, port_str); + if (s < 0) + errx(1, "connection failed"); + + fdprintf(s, "GET %s HTTP/1.0\r\n", page); + for (i = 0; i < num_headers; i++) + fdprintf(s, "%s\r\n", headers[i]); + fdprintf(s, "Host: %s\r\n\r\n", host); + + state = RESPONSE; + + while (1) { + ret = read (s, in_ptr, sizeof(in_buf) - in_len - 1); + if (ret == 0) + break; + else if (ret < 0) + err (1, "read: %lu", (unsigned long)ret); + + in_buf[ret + in_len] = '\0'; + + if (state == HEADER || state == RESPONSE) { + char *p; + + in_len += ret; + in_ptr += ret; + + while (1) { + p = strstr(in_buf, "\r\n"); + + if (p == NULL) { + break; + } else if (p == in_buf) { + memmove(in_buf, in_buf + 2, sizeof(in_buf) - 2); + state = BODY; + in_len -= 2; + in_ptr -= 2; + break; + } else if (state == RESPONSE) { + req->response = strndup(in_buf, p - in_buf); + state = HEADER; + } else { + req->headers = realloc(req->headers, + (req->num_headers + 1) * sizeof(req->headers[0])); + req->headers[req->num_headers] = strndup(in_buf, p - in_buf); + if (req->headers[req->num_headers] == NULL) + errx(1, "strdup"); + req->num_headers++; + } + memmove(in_buf, p + 2, sizeof(in_buf) - (p - in_buf) - 2); + in_len -= (p - in_buf) + 2; + in_ptr -= (p - in_buf) + 2; + } + } + + if (state == BODY) { + + req->body = erealloc(req->body, req->body_size + ret + 1); + + memcpy((char *)req->body + req->body_size, in_buf, ret); + req->body_size += ret; + ((char *)req->body)[req->body_size] = '\0'; + + in_ptr = in_buf; + in_len = 0; + } else + abort(); + } + + if (verbose_flag) { + int i; + printf("response: %s\n", req->response); + for (i = 0; i < req->num_headers; i++) + printf("header[%d] %s\n", i, req->headers[i]); + printf("body: %.*s\n", (int)req->body_size, (char *)req->body); + } + + close(s); + return 0; +} + + +int +main(int argc, char **argv) +{ + struct http_req req; + const char *host, *page; + int i, done, print_body, gssapi_done, gssapi_started; + char *headers[10]; /* XXX */ + int num_headers; + gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; + gss_name_t server = GSS_C_NO_NAME; + int optind = 0; + gss_OID mech_oid; + OM_uint32 flags; + + setprogname(argv[0]); + + if(getarg(http_args, num_http_args, argc, argv, &optind)) + usage(1); + + if (help_flag) + usage (0); + + if(version_flag) { + print_version(NULL); + exit(0); + } + + argc -= optind; + argv += optind; + + mech_oid = select_mech(mech); + + if (argc != 1 && argc != 2) + errx(1, "usage: %s host [page]", getprogname()); + host = argv[0]; + if (argc == 2) + page = argv[1]; + else + page = "/"; + + flags = 0; + if (delegate_flag) + flags |= GSS_C_DELEG_FLAG; + if (mutual_flag) + flags |= GSS_C_MUTUAL_FLAG; + + done = 0; + num_headers = 0; + gssapi_done = 1; + gssapi_started = 0; + do { + print_body = 0; + + http_query(host, page, headers, num_headers, &req); + for (i = 0 ; i < num_headers; i++) + free(headers[i]); + num_headers = 0; + + if (strstr(req.response, " 200 ") != NULL) { + print_body = 1; + done = 1; + } else if (strstr(req.response, " 401 ") != NULL) { + if (http_find_header(&req, "WWW-Authenticate:") == NULL) + errx(1, "Got %s but missed `WWW-Authenticate'", req.response); + gssapi_done = 0; + } + + if (!gssapi_done) { + const char *h = http_find_header(&req, "WWW-Authenticate:"); + if (h == NULL) + errx(1, "Got %s but missed `WWW-Authenticate'", req.response); + + if (strncasecmp(h, "Negotiate", 9) == 0) { + OM_uint32 maj_stat, min_stat; + gss_buffer_desc input_token, output_token; + + if (verbose_flag) + printf("Negotiate found\n"); + + if (server == GSS_C_NO_NAME) { + char *name; + asprintf(&name, "%s@%s", gss_service, host); + input_token.length = strlen(name); + input_token.value = name; + + maj_stat = gss_import_name(&min_stat, + &input_token, + GSS_C_NT_HOSTBASED_SERVICE, + &server); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_inport_name"); + free(name); + input_token.length = 0; + input_token.value = NULL; + } + + i = 9; + while(h[i] && isspace((unsigned char)h[i])) + i++; + if (h[i] != '\0') { + int len = strlen(&h[i]); + if (len == 0) + errx(1, "invalid Negotiate token"); + input_token.value = emalloc(len); + len = base64_decode(&h[i], input_token.value); + if (len < 0) + errx(1, "invalid base64 Negotiate token %s", &h[i]); + input_token.length = len; + } else { + if (gssapi_started) + errx(1, "Negotiate already started"); + gssapi_started = 1; + + input_token.length = 0; + input_token.value = NULL; + } + + maj_stat = + gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + &context_hdl, + server, + mech_oid, + flags, + 0, + GSS_C_NO_CHANNEL_BINDINGS, + &input_token, + NULL, + &output_token, + NULL, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_init_sec_context"); + else if (maj_stat & GSS_S_CONTINUE_NEEDED) + gssapi_done = 0; + else { + gss_name_t targ_name, src_name; + gss_buffer_desc name_buffer; + gss_OID mech_type; + + gssapi_done = 1; + + printf("Negotiate done: %s\n", mech); + + maj_stat = gss_inquire_context(&min_stat, + context_hdl, + &src_name, + &targ_name, + NULL, + &mech_type, + NULL, + NULL, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_inquire_context"); + + maj_stat = gss_display_name(&min_stat, + src_name, + &name_buffer, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_display_name"); + + printf("Source: %.*s\n", + (int)name_buffer.length, + (char *)name_buffer.value); + + gss_release_buffer(&min_stat, &name_buffer); + + maj_stat = gss_display_name(&min_stat, + targ_name, + &name_buffer, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_display_name"); + + printf("Target: %.*s\n", + (int)name_buffer.length, + (char *)name_buffer.value); + + gss_release_name(&min_stat, &targ_name); + gss_release_buffer(&min_stat, &name_buffer); + } + + if (output_token.length) { + char *neg_token; + + base64_encode(output_token.value, + output_token.length, + &neg_token); + + asprintf(&headers[0], "Authorization: Negotiate %s", + neg_token); + + num_headers = 1; + free(neg_token); + gss_release_buffer(&min_stat, &output_token); + } + if (input_token.length) + free(input_token.value); + + } else + done = 1; + } else + done = 1; + + if (verbose_flag) { + printf("%s\n\n", req.response); + + for (i = 0; i < req.num_headers; i++) + printf("%s\n", req.headers[i]); + printf("\n"); + } + if (print_body || verbose_flag) + printf("%.*s\n", (int)req.body_size, (char *)req.body); + + http_req_free(&req); + } while (!done); + + if (gssapi_done == 0) + errx(1, "gssapi not done but http dance done"); + + return 0; +} diff --git a/appl/test/nt_gss_client.c b/appl/test/nt_gss_client.c new file mode 100644 index 0000000..3527799 --- /dev/null +++ b/appl/test/nt_gss_client.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 1997 - 1999 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 "test_locl.h" +#include <gssapi.h> +#include "nt_gss_common.h" + +RCSID("$Id: nt_gss_client.c 21522 2007-07-12 13:15:04Z lha $"); + +/* + * This program tries to act as a client for the sample in `Sample + * SSPI Code' in Windows 2000 RC1 SDK. + */ + +static int +proto (int sock, const char *hostname, const char *service) +{ + struct sockaddr_in remote, local; + socklen_t addrlen; + + int context_established = 0; + gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; + gss_buffer_t input_token, output_token; + gss_buffer_desc real_input_token, real_output_token; + OM_uint32 maj_stat, min_stat; + gss_name_t server; + gss_buffer_desc name_token; + char *str; + + name_token.length = asprintf (&str, + "%s@%s", service, hostname); + if (str == NULL) + errx(1, "out of memory"); + name_token.value = str; + + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_HOSTBASED_SERVICE, + &server); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, + "Error importing name `%s@%s':\n", service, hostname); + + addrlen = sizeof(local); + if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 + || addrlen != sizeof(local)) + err (1, "getsockname(%s)", hostname); + + addrlen = sizeof(remote); + if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 + || addrlen != sizeof(remote)) + err (1, "getpeername(%s)", hostname); + + input_token = &real_input_token; + output_token = &real_output_token; + + input_token->length = 0; + output_token->length = 0; + + while(!context_established) { + maj_stat = + gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + &context_hdl, + server, + GSS_C_NO_OID, + GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, + 0, + GSS_C_NO_CHANNEL_BINDINGS, + input_token, + NULL, + output_token, + NULL, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_init_sec_context"); + if (output_token->length != 0) + nt_write_token (sock, output_token); + if (GSS_ERROR(maj_stat)) { + if (context_hdl != GSS_C_NO_CONTEXT) + gss_delete_sec_context (&min_stat, + &context_hdl, + GSS_C_NO_BUFFER); + break; + } + if (maj_stat & GSS_S_CONTINUE_NEEDED) { + nt_read_token (sock, input_token); + } else { + context_established = 1; + } + + } + + /* get_mic */ + + input_token->length = 3; + input_token->value = strdup("hej"); + + maj_stat = gss_get_mic(&min_stat, + context_hdl, + GSS_C_QOP_DEFAULT, + input_token, + output_token); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_get_mic"); + + nt_write_token (sock, input_token); + nt_write_token (sock, output_token); + + /* wrap */ + + input_token->length = 7; + input_token->value = "hemligt"; + + + maj_stat = gss_wrap (&min_stat, + context_hdl, + 1, + GSS_C_QOP_DEFAULT, + input_token, + NULL, + output_token); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_wrap"); + + nt_write_token (sock, output_token); + + return 0; +} + +int +main(int argc, char **argv) +{ + krb5_context context; /* XXX */ + int port = client_setup(&context, &argc, argv); + return client_doit (argv[argc], port, service, proto); +} diff --git a/appl/test/nt_gss_common.c b/appl/test/nt_gss_common.c new file mode 100644 index 0000000..ca07917 --- /dev/null +++ b/appl/test/nt_gss_common.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 1997, 1998, 1999 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 "test_locl.h" +#include <gssapi.h> +#include "nt_gss_common.h" + +RCSID("$Id: nt_gss_common.c 17450 2006-05-05 11:11:43Z lha $"); + +/* + * These are functions that are needed to interoperate with the + * `Sample SSPI Code' in Windows 2000 RC1 SDK. + */ + +/* + * Write the `gss_buffer_t' in `buf' onto the fd `sock', but remember that + * the length is written in little-endian-order. + */ + +void +nt_write_token (int sock, gss_buffer_t buf) +{ + unsigned char net_len[4]; + uint32_t len; + OM_uint32 min_stat; + + len = buf->length; + + net_len[0] = (len >> 0) & 0xFF; + net_len[1] = (len >> 8) & 0xFF; + net_len[2] = (len >> 16) & 0xFF; + net_len[3] = (len >> 24) & 0xFF; + + if (write (sock, net_len, 4) != 4) + err (1, "write"); + if (write (sock, buf->value, len) != len) + err (1, "write"); + + gss_release_buffer (&min_stat, buf); +} + +/* + * + */ + +void +nt_read_token (int sock, gss_buffer_t buf) +{ + unsigned char net_len[4]; + uint32_t len; + + if (read(sock, net_len, 4) != 4) + err (1, "read"); + len = (net_len[0] << 0) + | (net_len[1] << 8) + | (net_len[2] << 16) + | (net_len[3] << 24); + + buf->length = len; + buf->value = malloc(len); + if (read (sock, buf->value, len) != len) + err (1, "read"); +} + +void +gss_print_errors (int min_stat) +{ + OM_uint32 new_stat; + OM_uint32 msg_ctx = 0; + gss_buffer_desc status_string; + OM_uint32 ret; + + do { + ret = gss_display_status (&new_stat, + min_stat, + GSS_C_MECH_CODE, + GSS_C_NO_OID, + &msg_ctx, + &status_string); + fprintf (stderr, "%s\n", (char *)status_string.value); + gss_release_buffer (&new_stat, &status_string); + } while (!GSS_ERROR(ret) && msg_ctx != 0); +} + +void +gss_verr(int exitval, int status, const char *fmt, va_list ap) +{ + vwarnx (fmt, ap); + gss_print_errors (status); + exit (exitval); +} + +void +gss_err(int exitval, int status, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + gss_verr (exitval, status, fmt, args); + va_end(args); +} diff --git a/appl/test/nt_gss_common.h b/appl/test/nt_gss_common.h new file mode 100644 index 0000000..50b5c83 --- /dev/null +++ b/appl/test/nt_gss_common.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1997, 1998, 1999 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: nt_gss_common.h 7464 1999-12-02 17:05:13Z joda $ */ + +void nt_write_token (int sock, gss_buffer_t buf); +void nt_read_token (int sock, gss_buffer_t buf); + +void gss_print_errors (int min_stat); + +void gss_verr(int exitval, int status, const char *fmt, va_list ap) + __attribute__ ((format (printf, 3, 0))); + +void gss_err(int exitval, int status, const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))); diff --git a/appl/test/nt_gss_server.c b/appl/test/nt_gss_server.c new file mode 100644 index 0000000..df4a32e --- /dev/null +++ b/appl/test/nt_gss_server.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 1997 - 2000 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 "test_locl.h" +#include <gssapi.h> +#include <krb5.h> +#include "nt_gss_common.h" + +RCSID("$Id: nt_gss_server.c 12323 2003-05-21 15:15:34Z lha $"); + +/* + * This program tries to act as a server for the sample in `Sample + * SSPI Code' in Windows 2000 RC1 SDK. + * + * use --dump-auth to get a binary dump of the authorization data in the ticket + */ + +static int help_flag; +static int version_flag; +static char *port_str; +char *service = SERVICE; +static char *auth_file; + +static struct getargs args[] = { + { "port", 'p', arg_string, &port_str, "port to listen to", "port" }, + { "service", 's', arg_string, &service, "service to use", "service" }, + { "dump-auth", 0, arg_string, &auth_file, "dump authorization data", + "file" }, + { "help", 'h', arg_flag, &help_flag }, + { "version", 0, arg_flag, &version_flag } +}; + +static int num_args = sizeof(args) / sizeof(args[0]); + +static int +proto (int sock, const char *service) +{ + struct sockaddr_in remote, local; + socklen_t addrlen; + gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; + gss_buffer_t input_token, output_token; + gss_buffer_desc real_input_token, real_output_token; + OM_uint32 maj_stat, min_stat; + gss_name_t client_name; + gss_buffer_desc name_token; + + addrlen = sizeof(local); + if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 + || addrlen != sizeof(local)) + err (1, "getsockname)"); + + addrlen = sizeof(remote); + if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 + || addrlen != sizeof(remote)) + err (1, "getpeername"); + + input_token = &real_input_token; + output_token = &real_output_token; + + do { + nt_read_token (sock, input_token); + maj_stat = + gss_accept_sec_context (&min_stat, + &context_hdl, + GSS_C_NO_CREDENTIAL, + input_token, + GSS_C_NO_CHANNEL_BINDINGS, + &client_name, + NULL, + output_token, + NULL, + NULL, + NULL); + if(GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_accept_sec_context"); + if (output_token->length != 0) + nt_write_token (sock, output_token); + if (GSS_ERROR(maj_stat)) { + if (context_hdl != GSS_C_NO_CONTEXT) + gss_delete_sec_context (&min_stat, + &context_hdl, + GSS_C_NO_BUFFER); + break; + } + } while(maj_stat & GSS_S_CONTINUE_NEEDED); + + if (auth_file != NULL) { + int fd = open (auth_file, O_WRONLY | O_CREAT, 0666); +#if 0 + krb5_ticket *ticket; + krb5_data *data; + + ticket = context_hdl->ticket; + data = &ticket->ticket.authorization_data->val[0].ad_data; + + if(fd < 0) + err (1, "open %s", auth_file); + if (write (fd, data->data, data->length) != data->length) + errx (1, "write to %s failed", auth_file); +#endif + if (close (fd)) + err (1, "close %s", auth_file); + } + + maj_stat = gss_display_name (&min_stat, + client_name, + &name_token, + NULL); + if (GSS_ERROR(maj_stat)) + gss_err (1, min_stat, "gss_display_name"); + + fprintf (stderr, "User is `%.*s'\n", (int)name_token.length, + (char *)name_token.value); + + /* write something back */ + + output_token->value = strdup ("hejsan"); + output_token->length = strlen (output_token->value) + 1; + nt_write_token (sock, output_token); + + output_token->value = strdup ("hoppsan"); + output_token->length = strlen (output_token->value) + 1; + nt_write_token (sock, output_token); + + return 0; +} + +static int +doit (int port, const char *service) +{ + int sock, sock2; + struct sockaddr_in my_addr; + int one = 1; + + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) + err (1, "socket"); + + memset (&my_addr, 0, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_port = port; + my_addr.sin_addr.s_addr = INADDR_ANY; + + if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&one, sizeof(one)) < 0) + warn ("setsockopt SO_REUSEADDR"); + + if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) + err (1, "bind"); + + if (listen (sock, 1) < 0) + err (1, "listen"); + + sock2 = accept (sock, NULL, NULL); + if (sock2 < 0) + err (1, "accept"); + + return proto (sock2, service); +} + +static void +usage(int code, struct getargs *args, int num_args) +{ + arg_printusage(args, num_args, NULL, ""); + exit(code); +} + +static int +common_setup(krb5_context *context, int *argc, char **argv, + void (*usage)(int, struct getargs*, int)) +{ + int port = 0; + *argc = krb5_program_setup(context, *argc, argv, args, num_args, usage); + + if(help_flag) + (*usage)(0, args, num_args); + if(version_flag) { + print_version(NULL); + exit(0); + } + + if(port_str){ + struct servent *s = roken_getservbyname(port_str, "tcp"); + if(s) + port = s->s_port; + else { + char *ptr; + + port = strtol (port_str, &ptr, 10); + if (port == 0 && ptr == port_str) + errx (1, "Bad port `%s'", port_str); + port = htons(port); + } + } + + if (port == 0) + port = krb5_getportbyname (*context, PORT, "tcp", 4711); + + return port; +} + +static int +setup(krb5_context *context, int argc, char **argv) +{ + int port = common_setup(context, &argc, argv, usage); + if(argv[argc] != NULL) + usage(1, args, num_args); + return port; +} + +int +main(int argc, char **argv) +{ + krb5_context context = NULL; /* XXX */ + int port = setup(&context, argc, argv); + return doit (port, service); +} diff --git a/appl/test/tcp_client.c b/appl/test/tcp_client.c new file mode 100644 index 0000000..f1a4cb2 --- /dev/null +++ b/appl/test/tcp_client.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 1997 - 1999 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 "test_locl.h" +RCSID("$Id: tcp_client.c 17450 2006-05-05 11:11:43Z lha $"); + +krb5_context context; + +static int +proto (int sock, const char *hostname, const char *service) +{ + krb5_auth_context auth_context; + krb5_error_code status; + krb5_principal server; + krb5_data data; + krb5_data packet; + uint32_t len, net_len; + + status = krb5_auth_con_init (context, &auth_context); + if (status) + krb5_err (context, 1, status, "krb5_auth_con_init"); + + status = krb5_auth_con_setaddrs_from_fd (context, + auth_context, + &sock); + if (status) + krb5_err (context, 1, status, "krb5_auth_con_setaddrs_from_fd"); + + status = krb5_sname_to_principal (context, + hostname, + service, + KRB5_NT_SRV_HST, + &server); + if (status) + krb5_err (context, 1, status, "krb5_sname_to_principal"); + + status = krb5_sendauth (context, + &auth_context, + &sock, + VERSION, + NULL, + server, + AP_OPTS_MUTUAL_REQUIRED, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + if (status) + krb5_err (context, 1, status, "krb5_sendauth"); + + data.data = "hej"; + data.length = 3; + + krb5_data_zero (&packet); + + status = krb5_mk_safe (context, + auth_context, + &data, + &packet, + NULL); + if (status) + krb5_err (context, 1, status, "krb5_mk_safe"); + + len = packet.length; + net_len = htonl(len); + + if (krb5_net_write (context, &sock, &net_len, 4) != 4) + err (1, "krb5_net_write"); + if (krb5_net_write (context, &sock, packet.data, len) != len) + err (1, "krb5_net_write"); + + data.data = "hemligt"; + data.length = 7; + + krb5_data_free (&packet); + + status = krb5_mk_priv (context, + auth_context, + &data, + &packet, + NULL); + if (status) + krb5_err (context, 1, status, "krb5_mk_priv"); + + len = packet.length; + net_len = htonl(len); + + if (krb5_net_write (context, &sock, &net_len, 4) != 4) + err (1, "krb5_net_write"); + if (krb5_net_write (context, &sock, packet.data, len) != len) + err (1, "krb5_net_write"); + return 0; +} + +int +main(int argc, char **argv) +{ + int port = client_setup(&context, &argc, argv); + return client_doit (argv[argc], port, service, proto); +} diff --git a/appl/test/tcp_server.c b/appl/test/tcp_server.c new file mode 100644 index 0000000..97a9b11 --- /dev/null +++ b/appl/test/tcp_server.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1997 - 1999 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 "test_locl.h" +RCSID("$Id: tcp_server.c 17954 2006-09-01 09:01:03Z lha $"); + +krb5_context context; + +static int +proto (int sock, const char *service) +{ + krb5_auth_context auth_context; + krb5_error_code status; + krb5_principal server; + krb5_ticket *ticket; + char *name; + char hostname[MAXHOSTNAMELEN]; + krb5_data packet; + krb5_data data; + uint32_t len, net_len; + ssize_t n; + + status = krb5_auth_con_init (context, &auth_context); + if (status) + krb5_err (context, 1, status, "krb5_auth_con_init"); + + status = krb5_auth_con_setaddrs_from_fd (context, + auth_context, + &sock); + + if (status) + krb5_err (context, 1, status, "krb5_auth_con_setaddrs_from_fd"); + + if(gethostname (hostname, sizeof(hostname)) < 0) + krb5_err (context, 1, errno, "gethostname"); + + status = krb5_sname_to_principal (context, + hostname, + service, + KRB5_NT_SRV_HST, + &server); + if (status) + krb5_err (context, 1, status, "krb5_sname_to_principal"); + + status = krb5_recvauth (context, + &auth_context, + &sock, + VERSION, + server, + 0, + keytab, + &ticket); + if (status) + krb5_err (context, 1, status, "krb5_recvauth"); + + status = krb5_unparse_name (context, + ticket->client, + &name); + if (status) + krb5_err (context, 1, status, "krb5_unparse_name"); + + fprintf (stderr, "User is `%s'\n", name); + free (name); + + krb5_data_zero (&data); + krb5_data_zero (&packet); + + n = krb5_net_read (context, &sock, &net_len, 4); + if (n == 0) + krb5_errx (context, 1, "EOF in krb5_net_read"); + if (n < 0) + krb5_err (context, 1, errno, "krb5_net_read"); + + len = ntohl(net_len); + + krb5_data_alloc (&packet, len); + + n = krb5_net_read (context, &sock, packet.data, len); + if (n == 0) + krb5_errx (context, 1, "EOF in krb5_net_read"); + if (n < 0) + krb5_err (context, 1, errno, "krb5_net_read"); + + status = krb5_rd_safe (context, + auth_context, + &packet, + &data, + NULL); + if (status) + krb5_err (context, 1, status, "krb5_rd_safe"); + + fprintf (stderr, "safe packet: %.*s\n", (int)data.length, + (char *)data.data); + + n = krb5_net_read (context, &sock, &net_len, 4); + if (n == 0) + krb5_errx (context, 1, "EOF in krb5_net_read"); + if (n < 0) + krb5_err (context, 1, errno, "krb5_net_read"); + + len = ntohl(net_len); + + krb5_data_alloc (&packet, len); + + n = krb5_net_read (context, &sock, packet.data, len); + if (n == 0) + krb5_errx (context, 1, "EOF in krb5_net_read"); + if (n < 0) + krb5_err (context, 1, errno, "krb5_net_read"); + + status = krb5_rd_priv (context, + auth_context, + &packet, + &data, + NULL); + if (status) + krb5_err (context, 1, status, "krb5_rd_priv"); + + fprintf (stderr, "priv packet: %.*s\n", (int)data.length, + (char *)data.data); + + return 0; +} + +static int +doit (int port, const char *service) +{ + mini_inetd (port); + + return proto (STDIN_FILENO, service); +} + +int +main(int argc, char **argv) +{ + int port = server_setup(&context, argc, argv); + return doit (port, service); +} diff --git a/appl/test/test_locl.h b/appl/test/test_locl.h new file mode 100644 index 0000000..b203787 --- /dev/null +++ b/appl/test/test_locl.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1997 - 2000 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: test_locl.h 12797 2003-09-09 03:38:51Z lha $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdarg.h> +#include <ctype.h> +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_NETINET_IN6_H +#include <netinet/in6.h> +#endif +#ifdef HAVE_NETINET6_IN6_H +#include <netinet6/in6.h> +#endif + +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#include <errno.h> +#include <roken.h> +#include <getarg.h> +#include <err.h> +#include <krb5.h> + +#define SERVICE "test" + +#define PORT "test" + +extern char *service; +extern char *mech; +extern krb5_keytab keytab; +extern int fork_flag; +int server_setup(krb5_context*, int, char**); +int client_setup(krb5_context*, int*, char**); +int client_doit (const char *hostname, int port, const char *service, + int (*func)(int, const char *hostname, const char *service)); diff --git a/appl/test/uu_client.c b/appl/test/uu_client.c new file mode 100644 index 0000000..6113b8b --- /dev/null +++ b/appl/test/uu_client.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 1997 - 2000 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 "test_locl.h" +RCSID("$Id: uu_client.c 14719 2005-04-03 19:53:32Z lha $"); + +krb5_context context; + +static int +proto (int sock, const char *hostname, const char *service) +{ + struct sockaddr_in remote, local; + socklen_t addrlen; + krb5_address remote_addr, local_addr; + krb5_context context; + krb5_ccache ccache; + krb5_auth_context auth_context; + krb5_error_code status; + krb5_principal client; + krb5_data data; + krb5_data packet; + krb5_creds mcred, cred; + krb5_ticket *ticket; + + addrlen = sizeof(local); + if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 + || addrlen != sizeof(local)) + err (1, "getsockname(%s)", hostname); + + addrlen = sizeof(remote); + if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 + || addrlen != sizeof(remote)) + err (1, "getpeername(%s)", hostname); + + status = krb5_init_context(&context); + if (status) + errx(1, "krb5_init_context failed: %d", status); + + status = krb5_cc_default (context, &ccache); + if (status) + krb5_err(context, 1, status, "krb5_cc_default"); + + status = krb5_auth_con_init (context, &auth_context); + if (status) + krb5_err(context, 1, status, "krb5_auth_con_init"); + + local_addr.addr_type = AF_INET; + local_addr.address.length = sizeof(local.sin_addr); + local_addr.address.data = &local.sin_addr; + + remote_addr.addr_type = AF_INET; + remote_addr.address.length = sizeof(remote.sin_addr); + remote_addr.address.data = &remote.sin_addr; + + status = krb5_auth_con_setaddrs (context, + auth_context, + &local_addr, + &remote_addr); + if (status) + krb5_err(context, 1, status, "krb5_auth_con_setaddr"); + + krb5_cc_clear_mcred(&mcred); + + status = krb5_cc_get_principal(context, ccache, &client); + if(status) + krb5_err(context, 1, status, "krb5_cc_get_principal"); + status = krb5_make_principal(context, &mcred.server, + *krb5_princ_realm(context, client), + "krbtgt", + *krb5_princ_realm(context, client), + NULL); + if(status) + krb5_err(context, 1, status, "krb5_make_principal"); + mcred.client = client; + + status = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred); + if(status) + krb5_err(context, 1, status, "krb5_cc_retrieve_cred"); + + { + char *client_name; + krb5_data data; + status = krb5_unparse_name(context, cred.client, &client_name); + if(status) + krb5_err(context, 1, status, "krb5_unparse_name"); + data.data = client_name; + data.length = strlen(client_name) + 1; + status = krb5_write_message(context, &sock, &data); + if(status) + krb5_err(context, 1, status, "krb5_write_message"); + free(client_name); + } + + status = krb5_write_message(context, &sock, &cred.ticket); + if(status) + krb5_err(context, 1, status, "krb5_write_message"); + + status = krb5_auth_con_setuserkey(context, auth_context, &cred.session); + if(status) + krb5_err(context, 1, status, "krb5_auth_con_setuserkey"); + + status = krb5_recvauth(context, &auth_context, &sock, + VERSION, client, 0, NULL, &ticket); + + if (status) + krb5_err(context, 1, status, "krb5_recvauth"); + + if (ticket->ticket.authorization_data) { + AuthorizationData *authz; + int i; + + printf("Authorization data:\n"); + + authz = ticket->ticket.authorization_data; + for (i = 0; i < authz->len; i++) { + printf("\ttype %d, length %lu\n", + authz->val[i].ad_type, + (unsigned long)authz->val[i].ad_data.length); + } + } + + data.data = "hej"; + data.length = 3; + + krb5_data_zero (&packet); + + status = krb5_mk_safe (context, + auth_context, + &data, + &packet, + NULL); + if (status) + krb5_err(context, 1, status, "krb5_mk_safe"); + + status = krb5_write_message(context, &sock, &packet); + if(status) + krb5_err(context, 1, status, "krb5_write_message"); + + data.data = "hemligt"; + data.length = 7; + + krb5_data_free (&packet); + + status = krb5_mk_priv (context, + auth_context, + &data, + &packet, + NULL); + if (status) + krb5_err(context, 1, status, "krb5_mk_priv"); + + status = krb5_write_message(context, &sock, &packet); + if(status) + krb5_err(context, 1, status, "krb5_write_message"); + return 0; +} + +int +main(int argc, char **argv) +{ + int port = client_setup(&context, &argc, argv); + return client_doit (argv[argc], port, service, proto); +} diff --git a/appl/test/uu_server.c b/appl/test/uu_server.c new file mode 100644 index 0000000..6462363 --- /dev/null +++ b/appl/test/uu_server.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 1997 - 2000, 2007 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 "test_locl.h" +RCSID("$Id: uu_server.c 20880 2007-06-04 16:55:00Z lha $"); + +krb5_context context; + +static int +proto (int sock, const char *service) +{ + struct sockaddr_in remote, local; + socklen_t addrlen; + krb5_address remote_addr, local_addr; + krb5_ccache ccache; + krb5_auth_context auth_context; + krb5_error_code status; + krb5_data packet; + krb5_data data; + krb5_data client_name; + krb5_creds in_creds, *out_creds; + + addrlen = sizeof(local); + if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 + || addrlen != sizeof(local)) + err (1, "getsockname)"); + + addrlen = sizeof(remote); + if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 + || addrlen != sizeof(remote)) + err (1, "getpeername"); + + status = krb5_auth_con_init (context, &auth_context); + if (status) + errx (1, "krb5_auth_con_init: %s", + krb5_get_err_text(context, status)); + + local_addr.addr_type = AF_INET; + local_addr.address.length = sizeof(local.sin_addr); + local_addr.address.data = &local.sin_addr; + + remote_addr.addr_type = AF_INET; + remote_addr.address.length = sizeof(remote.sin_addr); + remote_addr.address.data = &remote.sin_addr; + + status = krb5_auth_con_setaddrs (context, + auth_context, + &local_addr, + &remote_addr); + if (status) + errx (1, "krb5_auth_con_setaddr: %s", + krb5_get_err_text(context, status)); + + status = krb5_read_message(context, &sock, &client_name); + if(status) + krb5_err(context, 1, status, "krb5_read_message"); + + memset(&in_creds, 0, sizeof(in_creds)); + status = krb5_cc_default(context, &ccache); + status = krb5_cc_get_principal(context, ccache, &in_creds.client); + + status = krb5_read_message(context, &sock, &in_creds.second_ticket); + if(status) + krb5_err(context, 1, status, "krb5_read_message"); + + status = krb5_parse_name(context, client_name.data, &in_creds.server); + if(status) + krb5_err(context, 1, status, "krb5_parse_name"); + + status = krb5_get_credentials(context, KRB5_GC_USER_USER, ccache, + &in_creds, &out_creds); + if(status) + krb5_err(context, 1, status, "krb5_get_credentials"); + + status = krb5_cc_default(context, &ccache); + + status = krb5_sendauth(context, + &auth_context, + &sock, + VERSION, + in_creds.client, + in_creds.server, + AP_OPTS_USE_SESSION_KEY, + NULL, + out_creds, + ccache, + NULL, + NULL, + NULL); + + if (status) + krb5_err(context, 1, status, "krb5_sendauth"); + + { + char *str; + krb5_unparse_name(context, in_creds.server, &str); + printf ("User is `%s'\n", str); + free(str); + krb5_unparse_name(context, in_creds.client, &str); + printf ("Server is `%s'\n", str); + free(str); + } + + krb5_data_zero (&data); + krb5_data_zero (&packet); + + status = krb5_read_message(context, &sock, &packet); + if(status) + krb5_err(context, 1, status, "krb5_read_message"); + + status = krb5_rd_safe (context, + auth_context, + &packet, + &data, + NULL); + if (status) + errx (1, "krb5_rd_safe: %s", + krb5_get_err_text(context, status)); + + printf ("safe packet: %.*s\n", (int)data.length, + (char *)data.data); + + status = krb5_read_message(context, &sock, &packet); + if(status) + krb5_err(context, 1, status, "krb5_read_message"); + + status = krb5_rd_priv (context, + auth_context, + &packet, + &data, + NULL); + if (status) + errx (1, "krb5_rd_priv: %s", + krb5_get_err_text(context, status)); + + printf ("priv packet: %.*s\n", (int)data.length, + (char *)data.data); + + return 0; +} + +static int +doit (int port, const char *service) +{ + int sock, sock2; + struct sockaddr_in my_addr; + int one = 1; + + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) + err (1, "socket"); + + memset (&my_addr, 0, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_port = port; + my_addr.sin_addr.s_addr = INADDR_ANY; + + if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&one, sizeof(one)) < 0) + warn ("setsockopt SO_REUSEADDR"); + + if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) + err (1, "bind"); + + if (listen (sock, 1) < 0) + err (1, "listen"); + + sock2 = accept (sock, NULL, NULL); + if (sock2 < 0) + err (1, "accept"); + + return proto (sock2, service); +} + +int +main(int argc, char **argv) +{ + int port = server_setup(&context, argc, argv); + return doit (port, service); +} |