aboutsummaryrefslogtreecommitdiffstats
path: root/appl/kx
diff options
context:
space:
mode:
authorStanislav Sedov <stas@FreeBSD.org>2011-10-05 07:23:29 +0000
committerStanislav Sedov <stas@FreeBSD.org>2011-10-05 07:23:29 +0000
commit7c450da7b446c557e05f34a100b597800967d987 (patch)
tree57a48e7e9b592f2d5b713e80a4455820625c2b7b /appl/kx
parentb4e3a10e9339a8400197298021d6ca9b8e3aa039 (diff)
downloadsrc-7c450da7b446c557e05f34a100b597800967d987.tar.gz
src-7c450da7b446c557e05f34a100b597800967d987.zip
- Import Heimdal 1.5 distribution.vendor/heimdal/1.5
Notes
Notes: svn path=/vendor-crypto/heimdal/dist/; revision=226031 svn path=/vendor-crypto/heimdal/1.5/; revision=226033; tag=vendor/heimdal/1.5
Diffstat (limited to 'appl/kx')
-rw-r--r--appl/kx/ChangeLog457
-rw-r--r--appl/kx/Makefile.am70
-rw-r--r--appl/kx/Makefile.in1142
-rw-r--r--appl/kx/NTMakefile35
-rw-r--r--appl/kx/common.c813
-rw-r--r--appl/kx/context.c94
-rw-r--r--appl/kx/krb5.c447
-rw-r--r--appl/kx/kx.192
-rw-r--r--appl/kx/kx.c711
-rw-r--r--appl/kx/kx.cat139
-rw-r--r--appl/kx/kx.h249
-rw-r--r--appl/kx/kxd.883
-rw-r--r--appl/kx/kxd.c779
-rw-r--r--appl/kx/kxd.cat837
-rw-r--r--appl/kx/rxtelnet.1128
-rw-r--r--appl/kx/rxtelnet.cat152
-rw-r--r--appl/kx/rxtelnet.in72
-rw-r--r--appl/kx/rxterm.1120
-rw-r--r--appl/kx/rxterm.cat147
-rw-r--r--appl/kx/rxterm.in45
-rw-r--r--appl/kx/tenletxr.191
-rw-r--r--appl/kx/tenletxr.cat137
-rw-r--r--appl/kx/tenletxr.in37
-rw-r--r--appl/kx/writeauth.c73
24 files changed, 5750 insertions, 0 deletions
diff --git a/appl/kx/ChangeLog b/appl/kx/ChangeLog
new file mode 100644
index 000000000000..4784630276ea
--- /dev/null
+++ b/appl/kx/ChangeLog
@@ -0,0 +1,457 @@
+2007-04-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * make encoding function independent of krb4 and krb5, enable
+ removal of krb4
+
+2006-10-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: Add man_MANS to EXTRA_DIST
+
+2006-05-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Rename u_intXX_t to uintXX_t
+
+2005-07-09 Love Hörquist Åstrand <lha@it.su.se>
+
+ * kxd.c (doit): only cleaup for active sockets, passive does it
+ own cleaning up
+
+ * fix unconst and shadow warnings
+
+2005-07-07 Assar Westerlund <assar@kth.se>
+
+ * krb4.c: Do not assume that des_key_schedule is an
+ array.
+
+2005-06-07 Love Hörquist Åstrand <lha@it.su.se>
+
+ * (recv_conn): init variables to using them uninitialized
+
+2005-04-30 Love Hörquist Åstrand <lha@it.su.se>
+
+ * kx.c (connect_host): make sure s is initialized
+
+2005-04-20 Love Hörquist Åstrand <lha@it.su.se>
+
+ * krb5.c: cast size_t to unsigned long
+
+2004-03-15 Love Hörquist Åstrand <lha@it.su.se>
+
+ * krb5.c (krb5_destroy): free allocated memory, not something else
+
+2004-03-07 Love Hörquist Åstrand <lha@it.su.se>
+
+ * rxtelnet.1: document new behavior
+
+ * rxtelnet.in: even if kx failes, start anyway From: Harald Barth
+ <haba@pdc.kth.se>
+
+2004-02-18 Love Hörquist Åstrand <lha@it.su.se>
+
+ * krb4.c: remove dup on
+
+2004-01-08 Love Hörquist Åstrand <lha@it.su.se>
+
+ * krb5.c: clean up krb5 support, log to syslog instead of stdout
+ (very confusing for the other end tcp connection), patch
+ originally from joda
+
+2003-11-13 Johan Danielsson <joda@pdc.kth.se>
+
+ * rxtelnet.in: add telnet -F option
+
+2003-05-15 Love Hörquist Åstrand <lha@it.su.se>
+
+ * kxd.c (recv_conn): pass pointer to sockaddr, not pointer to
+ pointer
+
+ * kxd.c (recv_conn): get sizeof of the sockaddr_storage, not the
+ sockaddr pointer
+
+ * kxd.c (recv_conn): if getnameinfo failes, send error to client
+ (and syslog)
+
+2003-04-16 Johan Danielsson <joda@pdc.kth.se>
+
+ * kx.c (doit_{passive,active}): use kc->thataddr directly
+
+ * kx.h: don't directly use sockaddr_storage, since we can't always
+ know what it looks like
+
+2003-04-11 Love Hörquist Åstrand <lha@it.su.se>
+
+ * rxterm.1: spelling, from jmc <jmc@prioris.mini.pw.edu.pl>
+ * rxtelnet.1: spelling, from jmc <jmc@prioris.mini.pw.edu.pl>
+ * kxd.8: spelling, from jmc <jmc@prioris.mini.pw.edu.pl>
+ * kx.1: spelling, from jmc <jmc@prioris.mini.pw.edu.pl>
+
+2003-02-25 Love Hörquist Åstrand <lha@it.su.se>
+
+ * krb4.c: remove \n from warnx, from NetBSD
+
+2002-12-11 Johan Danielsson <joda@pdc.kth.se>
+
+ * kx.c (connect_host): pass size of thisaddr_ss to getsockname
+
+2002-10-15 Johan Danielsson <joda@pdc.kth.se>
+
+ * some ipv6 support (from Love)
+
+2002-09-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * krb5.c (krb5_authenticate): use subkey
+
+2002-08-22 Johan Danielsson <joda@pdc.kth.se>
+
+ * common.c: remove only reference to strndup
+
+2002-05-07 Johan Danielsson <joda@pdc.kth.se>
+
+ * krb5.c: use krb5_warn where appropriate
+
+2002-03-18 Johan Danielsson <joda@pdc.kth.se>
+
+ * rxtelnet.in, rxterm.in: add forward (-f) option
+
+2001-09-17 Assar Westerlund <assar@sics.se>
+
+ * kx.h: add a kludge to make it build on aix (that defines NOERROR
+ in both sys/stream.h and arpa/nameser.h and considers that a fatal
+ error)
+
+2001-07-12 Assar Westerlund <assar@sics.se>
+
+ * common.c (connect_local_xsocket): handle a tcp socket as last
+ resort
+
+ * rxterm.in: add -K (send arguments to kx)
+ * rxtelnet.in: add -K (send arguments to kx)
+
+2001-06-21 Assar Westerlund <assar@sics.se>
+
+ * rxterm.in: add -b for pointing to the rsh program. from
+ <mikan@mikan.net>
+ * rxtelnet.in: add -b for pointing to the telnet program. from
+ <mikan@mikan.net>
+
+2001-01-17 Johan Danielsson <joda@pdc.kth.se>
+
+ * common.c: don't write to string constants
+
+2000-12-31 Assar Westerlund <assar@sics.se>
+
+ * krb5.c (krb5_make_context): handle krb5_init_context failure
+ consistently
+
+2000-10-08 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (doit_passive): check that fds are not too large to select
+ on
+ * kx.c (doit_active): check that fds are not too large to select
+ on
+ * krb5.c (krb5_copy_encrypted): check that fds are not too large
+ to select on
+ * krb4.c (krb4_copy_encrypted): check that fds are not too large
+ to select on
+
+2000-07-17 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: use conditional for X
+
+2000-06-10 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: use INSTALL_SCRIPT for installing rxterm, rxtelnet,
+ tenletxr
+
+2000-04-19 Assar Westerlund <assar@sics.se>
+
+ * common.c: try hostname uncanonified if getaddrinfo() fails
+
+2000-02-06 Assar Westerlund <assar@sics.se>
+
+ * kx.h: remove old prorotypes
+
+2000-01-08 Assar Westerlund <assar@sics.se>
+
+ * common.c (match_local_auth): handle ai_canonname being set in
+ any of the addresses returnedby getaddrinfo. glibc apparently
+ returns the reverse lookup of every address in ai_canonname.
+
+1999-12-28 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (main): call krb5_getportbyname with the default in
+ host-byte-order
+
+1999-12-17 Assar Westerlund <assar@sics.se>
+
+ * common.c (match_local_auth): remove extra brace. spotted by
+ Jakob Schlyter <jakob@cdg.chalmers.se>
+
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * common.c (match_local_auth): handle ai_canonname not being set
+
+1999-12-06 Assar Westerlund <assar@sics.se>
+
+ * krb4.c (krb4_authenticate): the NAT address might not be the one
+ for the relevant realm, try anyway.
+ * kxd.c (recv_conn): type correctness
+ * kx.c (connect_host): typo
+
+1999-12-05 Assar Westerlund <assar@sics.se>
+
+ * common.c (INADDR_LOOPBACK): remove. now in roken.
+
+ * kxd.c (recv_conn): use getnameinfo_verified
+ * kxd.c (recv_conn): replace inaddr2str with getnameinfo
+
+1999-12-04 Assar Westerlund <assar@sics.se>
+
+ * kx.c (connect_host): use getaddrinfo
+ * common.c (find_auth_cookie, match_local_auth): re-write to use
+ getaddrinfo
+
+1999-11-27 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (recv_conn): better errors when getting unrecognized data
+
+1999-11-25 Assar Westerlund <assar@sics.se>
+
+ * krb4.c (krb4_authenticate): obtain the `local' address when
+ doing NAT. also turn on passive mode. From <thn@stacken.kth.se>
+
+1999-11-18 Assar Westerlund <assar@sics.se>
+
+ * krb5.c (krb5_destroy): free the correct part of the context
+
+1999-11-02 Assar Westerlund <assar@sics.se>
+
+ * kx.c (main): redo the v4/v5 selection for consistency. -4 ->
+ try only v4 -5 -> try only v5 none, -45 -> try v5, v4
+
+1999-10-10 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (CLEANFILES): add generated files so that they get
+ cleaned away
+
+1999-09-29 Assar Westerlund <assar@sics.se>
+
+ * common.c (match_local_auth): only look for FamilyLocal (and
+ FamilyWild) cookies. This will not work when we start talking tcp
+ to the local X-server but `connect_local_xsocket' and the rest of
+ the code doesn't handle it anyway and the old code could (and did)
+ pick up the wrong cookie sometimes. If we have to match
+ FamilyInternet cookies, the search order has to be changed anyway
+
+1999-09-02 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (childhandler): watch for child `wait_on_pid' to die.
+ (recv_conn): set `wait_on_pid' instead of looping on waitpid here
+ also. This should solve the problem of kxd looping which was
+ caused by the signal handler getting invoked before this waitpid
+ and reaping the child leaving this poor loop without any child
+
+1999-08-19 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (recv_conn): give better error message
+ (doit_active): don't die if fork gives EAGAIN
+
+1999-08-19 Johan Danielsson <joda@pdc.kth.se>
+
+ * kxd.c (recv_conn): call setjob on crays;
+ (doit_passive): if fork fails with EAGAIN, don't shutdown, just close
+ the connection re-implement `-t' flag
+
+1999-07-12 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: handle not building X programs
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * kx.c: conditionalize krb_enable_debug
+
+1999-06-20 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (main): hopefully do inetd confusion right
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * krb4.c (krb4_authenticate): get rid of a warning
+
+ * kx.h: const-pollution
+
+ * kx.c: use get_default_username and resulting const pollution
+
+ * context.c (context_set): const pollution
+
+1999-05-22 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (recv_conn): fix syslog messages
+ (main): fix inetd_flag thinko
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * kx.c (main): don't byte-swap the argument to krb5_getportbyname
+
+ * kx.c (main): try to use $USERNAME
+
+1999-05-10 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (SOURCES*): update sources list
+
+ * kx.c (main): forgot to conditionalize some KRB5 code
+
+ * kxd.c (main): use getarg
+ (*): handle v4 and/or v5
+
+ * kx.h: update
+
+ * kx.c (main): use getarg.
+ (*): handle v4 and/or v5
+
+ * common.c (do_enccopy, copy_encrypted): remove use
+ net_{read,write} instead of krb_net_{read,write}
+ (krb_get_int, krb_put_int): include fallback of these for when we
+ compile without krb4
+
+ * Makefile.am (*_SOURCES): remove encdata, add krb[45].c,
+ context.c
+ (LDADD): add krb5
+
+ * krb4.c, krb5.c, context.c: new files
+
+1999-05-08 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (doit_passive): handle error code from
+ create_and_write_cookie
+
+ * kx.c (doit_active): handle error code from
+ create_and_write_cookie
+
+ * common.c (create_and_write_cookie): try to return better (and
+ correct) errors. Based on a patch from Love <lha@e.kth.se>
+
+ * common.c (try_pie): more braces
+ (match_local_auth): new function
+ (find_auth_cookie): new function
+ (replace_cookie): don't just take the first auth cookie. based on
+ patch from Ake Sandgren <ake@@cs.umu.se>
+
+Wed Apr 7 23:39:23 1999 Assar Westerlund <assar@sics.se>
+
+ * common.c (get_xsockets): init local variable to get rid of a gcc
+ warning
+
+Thu Apr 1 21:11:36 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.in: fix for writeauth.o
+
+Fri Mar 19 15:12:31 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kx.c: add gcc-braces
+
+Thu Mar 18 11:18:20 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: include Makefile.am.common
+
+Thu Mar 11 14:58:32 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * writeauth.c: protoize
+
+ * common.c: fix some warnings
+
+Wed Mar 10 19:33:39 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kxd.c: openlog -> roken_openlog
+
+Wed Feb 3 22:01:55 1999 Assar Westerlund <assar@sics.se>
+
+ * rxtelnet.in: print out what telnet program we are running. From
+ <nissej@pdc.kth.se>
+
+ * tenletxr.in: add --version, [-h | --help], -v
+
+ * rxterm.in: add --version, [-h | --help], -v
+
+ * rxtelnet.in: add --version, [-h | --help], -v
+
+ * Makefile.in (rxterm, rxtelnet, telnetxr): substitute VERSION and
+ PACKAGE
+
+ * rxtelnet.in: update usage string
+
+Fri Jan 22 23:51:05 1999 Assar Westerlund <assar@sics.se>
+
+ * common.c (verify_and_remove_cookies): give back a meaningful
+ error message if we're using the wrong cookie
+
+Fri Dec 18 17:42:02 1998 Assar Westerlund <assar@sics.se>
+
+ * common.c (replace_cookie): try to handle the case of not finding
+ any cookies
+
+Sun Nov 22 10:31:53 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (WFLAGS): set
+
+Wed Nov 18 20:25:37 1998 Assar Westerlund <assar@sics.se>
+
+ * rxtelnet.in: new argument -n for not starting any terminal
+ emulator
+
+ * kx.c (doit_passive): parse $DISPLAY correctly
+
+Fri Oct 2 06:34:51 1998 Assar Westerlund <assar@sics.se>
+
+ * kx.c (doit_active): check DISPLAY to figure out what local
+ socket to connect to. From Åke Sandgren <ake@cs.umu.se>
+
+Thu Oct 1 23:02:29 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * kx.h: case MAY_HAVE_X11_PIPES with Solaris
+
+Tue Sep 29 02:22:44 1998 Assar Westerlund <assar@sics.se>
+
+ * kx.c: fix from Ake Sandgren <ake@cs.umu.se>
+
+Mon Sep 28 18:04:03 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * common.c (try_pipe): return -1 if I_PUSH fails with ENOSYS
+
+Sat Sep 26 17:34:21 1998 Assar Westerlund <assar@sics.se>
+
+ * kxd.c: create sockets before setuid to handle Solaris' strange
+ permissions on /tmp/.X11-{unix,pipe}
+
+ * common.c (chown_xsockets): new function
+
+ * kx.h (chown_xsockets): new prototype
+
+Sun Aug 16 18:34:30 1998 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (doit_passive): conditionalize stream pipe code
+
+ * implement support for Solaris's named-pipe X transport
+
+Thu May 28 17:20:39 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * common.c: fix for (compiler?) bug in solaris 2.4 bind
+
+ * kx.c: get_xsockets returns int, not unsigned
+
+Wed May 27 04:20:20 1998 Assar Westerlund <assar@sics.se>
+
+ * kxd.c (doit): better error reporting
+
+Tue May 26 17:41:23 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * kx.c: use krb_enable_debug
+
+Mon May 25 05:22:18 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (clean): remove encdata.c
+
+Fri May 1 07:16:36 1998 Assar Westerlund <assar@sics.se>
+
+ * kx.c: unifdef -DHAVE_H_ERRNO
+
diff --git a/appl/kx/Makefile.am b/appl/kx/Makefile.am
new file mode 100644
index 000000000000..37036bd58846
--- /dev/null
+++ b/appl/kx/Makefile.am
@@ -0,0 +1,70 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+AM_CPPFLAGS += $(X_CFLAGS)
+
+WFLAGS += $(WFLAGS_NOIMPLICITINT)
+
+if HAVE_X
+
+bin_PROGRAMS = kx
+bin_SCRIPTS = rxterm rxtelnet tenletxr
+libexec_PROGRAMS = kxd
+
+else
+
+bin_PROGRAMS =
+bin_SCRIPTS =
+libexec_PROGRAMS =
+
+endif
+
+CLEANFILES = rxterm rxtelnet tenletxr
+
+if NEED_WRITEAUTH
+XauWriteAuth_c = writeauth.c
+endif
+
+kx_SOURCES = \
+ kx.c \
+ kx.h \
+ common.c \
+ context.c \
+ krb5.c \
+ $(XauWriteAuth_c)
+
+EXTRA_kx_SOURCES = writeauth.c
+
+kxd_SOURCES = \
+ kxd.c \
+ kx.h \
+ common.c \
+ context.c \
+ krb5.c \
+ $(XauWriteAuth_c)
+
+EXTRA_kxd_SOURCES = writeauth.c
+
+EXTRA_DIST = NTMakefile rxterm.in rxtelnet.in tenletxr.in $(man_MANS)
+
+man_MANS = kx.1 rxtelnet.1 rxterm.1 tenletxr.1 kxd.8
+
+rxterm: rxterm.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/rxterm.in > $@
+ chmod +x $@
+
+rxtelnet: rxtelnet.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/rxtelnet.in > $@
+ chmod +x $@
+
+tenletxr: tenletxr.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/tenletxr.in > $@
+ chmod +x $@
+
+LDADD = \
+ $(LIB_kafs) \
+ $(LIB_krb5) \
+ $(LIB_hcrypto) \
+ $(LIB_roken) \
+ $(X_LIBS) $(LIB_XauReadAuth) $(X_PRE_LIBS) $(X_EXTRA_LIBS)
diff --git a/appl/kx/Makefile.in b/appl/kx/Makefile.in
new file mode 100644
index 000000000000..3b0d36798ddd
--- /dev/null
+++ b/appl/kx/Makefile.in
@@ -0,0 +1,1142 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# $Id$
+
+# $Id$
+
+# $Id$
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@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 ChangeLog
+@HAVE_X_TRUE@bin_PROGRAMS = kx$(EXEEXT)
+@HAVE_X_TRUE@libexec_PROGRAMS = kxd$(EXEEXT)
+subdir = appl/kx
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \
+ $(top_srcdir)/cf/auth-modules.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/dispatch.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/libtool.m4 \
+ $(top_srcdir)/cf/ltoptions.m4 $(top_srcdir)/cf/ltsugar.m4 \
+ $(top_srcdir)/cf/ltversion.m4 $(top_srcdir)/cf/lt~obsolete.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/pkg.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.ac
+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 =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" \
+ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
+ "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS)
+am__kx_SOURCES_DIST = kx.c kx.h common.c context.c krb5.c writeauth.c
+@NEED_WRITEAUTH_TRUE@am__objects_1 = writeauth.$(OBJEXT)
+am_kx_OBJECTS = kx.$(OBJEXT) common.$(OBJEXT) context.$(OBJEXT) \
+ krb5.$(OBJEXT) $(am__objects_1)
+kx_OBJECTS = $(am_kx_OBJECTS)
+kx_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = $(top_builddir)/lib/kafs/libkafs.la \
+ $(am__DEPENDENCIES_1)
+kx_DEPENDENCIES = $(am__DEPENDENCIES_2) $(LIB_krb5) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am__kxd_SOURCES_DIST = kxd.c kx.h common.c context.c krb5.c \
+ writeauth.c
+am_kxd_OBJECTS = kxd.$(OBJEXT) common.$(OBJEXT) context.$(OBJEXT) \
+ krb5.$(OBJEXT) $(am__objects_1)
+kxd_OBJECTS = $(am_kxd_OBJECTS)
+kxd_LDADD = $(LDADD)
+kxd_DEPENDENCIES = $(am__DEPENDENCIES_2) $(LIB_krb5) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+SCRIPTS = $(bin_SCRIPTS)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+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 = $(kx_SOURCES) $(EXTRA_kx_SOURCES) $(kxd_SOURCES) \
+ $(EXTRA_kxd_SOURCES)
+DIST_SOURCES = $(am__kx_SOURCES_DIST) $(EXTRA_kx_SOURCES) \
+ $(am__kxd_SOURCES_DIST) $(EXTRA_kxd_SOURCES)
+man1dir = $(mandir)/man1
+man8dir = $(mandir)/man8
+MANS = $(man_MANS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AMTAR = @AMTAR@
+AR = @AR@
+ASN1_COMPILE = @ASN1_COMPILE@
+ASN1_COMPILE_DEP = @ASN1_COMPILE_DEP@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CAPNG_CFLAGS = @CAPNG_CFLAGS@
+CAPNG_LIBS = @CAPNG_LIBS@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMPILE_ET = @COMPILE_ET@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBHEADER = @DBHEADER@
+DBLIB = @DBLIB@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIR_com_err = @DIR_com_err@
+DIR_hcrypto = @DIR_hcrypto@
+DIR_hdbdir = @DIR_hdbdir@
+DIR_roken = @DIR_roken@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INCLUDES_roken = @INCLUDES_roken@
+INCLUDE_hcrypto = @INCLUDE_hcrypto@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+INCLUDE_krb4 = @INCLUDE_krb4@
+INCLUDE_libedit = @INCLUDE_libedit@
+INCLUDE_libintl = @INCLUDE_libintl@
+INCLUDE_openldap = @INCLUDE_openldap@
+INCLUDE_readline = @INCLUDE_readline@
+INCLUDE_sqlite3 = @INCLUDE_sqlite3@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+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_dispatch_async_f = @LIB_dispatch_async_f@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_dns_search = @LIB_dns_search@
+LIB_door_create = @LIB_door_create@
+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_libedit = @LIB_libedit@
+LIB_libintl = @LIB_libintl@
+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_sqlite3 = @LIB_sqlite3@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_AFS = @NO_AFS@
+NROFF = @NROFF@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LDADD = @PTHREAD_LDADD@
+PTHREAD_LIBADD = @PTHREAD_LIBADD@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SLC = @SLC@
+SLC_DEP = @SLC_DEP@
+STRIP = @STRIP@
+VERSION = @VERSION@
+VERSIONING = @VERSIONING@
+WFLAGS = @WFLAGS@ $(WFLAGS_NOIMPLICITINT)
+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_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUFFIXES = .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include
+AM_CPPFLAGS = $(INCLUDES_roken) $(X_CFLAGS)
+@do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME
+AM_CFLAGS = $(WFLAGS)
+CP = cp
+buildinclude = $(top_builddir)/include
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_setpcred = @LIB_setpcred@
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+libexec_heimdaldir = $(libexecdir)/heimdal
+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
+LIB_heimbase = $(top_builddir)/base/libheimbase.la
+@DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la
+@HAVE_X_FALSE@bin_SCRIPTS =
+@HAVE_X_TRUE@bin_SCRIPTS = rxterm rxtelnet tenletxr
+CLEANFILES = rxterm rxtelnet tenletxr
+@NEED_WRITEAUTH_TRUE@XauWriteAuth_c = writeauth.c
+kx_SOURCES = \
+ kx.c \
+ kx.h \
+ common.c \
+ context.c \
+ krb5.c \
+ $(XauWriteAuth_c)
+
+EXTRA_kx_SOURCES = writeauth.c
+kxd_SOURCES = \
+ kxd.c \
+ kx.h \
+ common.c \
+ context.c \
+ krb5.c \
+ $(XauWriteAuth_c)
+
+EXTRA_kxd_SOURCES = writeauth.c
+EXTRA_DIST = NTMakefile rxterm.in rxtelnet.in tenletxr.in $(man_MANS)
+man_MANS = kx.1 rxtelnet.1 rxterm.1 tenletxr.1 kxd.8
+LDADD = \
+ $(LIB_kafs) \
+ $(LIB_krb5) \
+ $(LIB_hcrypto) \
+ $(LIB_roken) \
+ $(X_LIBS) $(LIB_XauReadAuth) $(X_PRE_LIBS) $(X_EXTRA_LIBS)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .et .h .x .z .hx .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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/kx/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign appl/kx/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
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)"
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
+
+clean-libexecPROGRAMS:
+ @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+kx$(EXEEXT): $(kx_OBJECTS) $(kx_DEPENDENCIES)
+ @rm -f kx$(EXEEXT)
+ $(LINK) $(kx_OBJECTS) $(kx_LDADD) $(LIBS)
+kxd$(EXEEXT): $(kxd_OBJECTS) $(kxd_DEPENDENCIES)
+ @rm -f kxd$(EXEEXT)
+ $(LINK) $(kxd_OBJECTS) $(kxd_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kxd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writeauth.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man1: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ { for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ test -z "$$files" || { \
+ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
+install-man8: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ { for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ test -z "$$files" || { \
+ echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(man8dir)" && rm -f $$files; }
+
+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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ 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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ 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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @list='$(MANS)'; if test -n "$$list"; then \
+ list=`for p in $$list; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+ if test -n "$$list" && \
+ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
+ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+ echo " typically \`make maintainer-clean' will remove them" >&2; \
+ exit 1; \
+ else :; fi; \
+ else :; fi
+ @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 "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$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) $(SCRIPTS) $(MANS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-binPROGRAMS clean-generic clean-libexecPROGRAMS \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS \
+ install-libexecPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-libexecPROGRAMS uninstall-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+uninstall-man: uninstall-man1 uninstall-man8
+
+.MAKE: check-am 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-binPROGRAMS clean-generic clean-libexecPROGRAMS \
+ clean-libtool 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-binPROGRAMS install-binSCRIPTS 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-libexecPROGRAMS install-man install-man1 install-man8 \
+ 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-binPROGRAMS uninstall-binSCRIPTS uninstall-hook \
+ uninstall-libexecPROGRAMS uninstall-man uninstall-man1 \
+ uninstall-man8
+
+
+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 $< $@
+
+.hx.h:
+ @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="$${tsrcdir}/cf/maybe-valgrind.sh -s $${tsrcdir} -o $${tobjdir}" 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
+
+rxterm: rxterm.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/rxterm.in > $@
+ chmod +x $@
+
+rxtelnet: rxtelnet.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/rxtelnet.in > $@
+ chmod +x $@
+
+tenletxr: tenletxr.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/tenletxr.in > $@
+ chmod +x $@
+
+# 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/kx/NTMakefile b/appl/kx/NTMakefile
new file mode 100644
index 000000000000..7d4b89a831e6
--- /dev/null
+++ b/appl/kx/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER 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.
+#
+
+RELDIR=appl\kx
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/appl/kx/common.c b/appl/kx/common.c
new file mode 100644
index 000000000000..b19b685f30b1
--- /dev/null
+++ b/appl/kx/common.c
@@ -0,0 +1,813 @@
+/*
+ * Copyright (c) 1995 - 2001 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 "kx.h"
+
+RCSID("$Id$");
+
+char x_socket[MaxPathLen];
+
+uint32_t display_num;
+char display[MaxPathLen];
+int display_size = sizeof(display);
+char xauthfile[MaxPathLen];
+int xauthfile_size = sizeof(xauthfile);
+u_char cookie[16];
+size_t cookie_len = sizeof(cookie);
+
+#ifndef X_UNIX_PATH
+#define X_UNIX_PATH "/tmp/.X11-unix/X"
+#endif
+
+#ifndef X_PIPE_PATH
+#define X_PIPE_PATH "/tmp/.X11-pipe/X"
+#endif
+
+/*
+ * Allocate a unix domain socket in `s' for display `dpy' and with
+ * filename `pattern'
+ *
+ * 0 if all is OK
+ * -1 if bind failed badly
+ * 1 if dpy is already used */
+
+static int
+try_socket (struct x_socket *s, int dpy, const char *pattern)
+{
+ struct sockaddr_un addr;
+ int fd;
+
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0)
+ err (1, "socket AF_UNIX");
+ memset (&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ snprintf (addr.sun_path, sizeof(addr.sun_path), pattern, dpy);
+ if(bind(fd,
+ (struct sockaddr *)&addr,
+ sizeof(addr)) < 0) {
+ close (fd);
+ if (errno == EADDRINUSE ||
+ errno == EACCES /* Cray return EACCESS */
+#ifdef ENOTUNIQ
+ || errno == ENOTUNIQ /* bug in Solaris 2.4 */
+#endif
+ )
+ return 1;
+ else
+ return -1;
+ }
+ s->fd = fd;
+ s->pathname = strdup (addr.sun_path);
+ if (s->pathname == NULL)
+ errx (1, "strdup: out of memory");
+ s->flags = UNIX_SOCKET;
+ return 0;
+}
+
+#ifdef MAY_HAVE_X11_PIPES
+/*
+ * Allocate a stream (masqueraded as a named pipe)
+ *
+ * 0 if all is OK
+ * -1 if bind failed badly
+ * 1 if dpy is already used
+ */
+
+static int
+try_pipe (struct x_socket *s, int dpy, const char *pattern)
+{
+ char path[MAXPATHLEN];
+ int ret;
+ int fd;
+ int pipefd[2];
+
+ snprintf (path, sizeof(path), pattern, dpy);
+ fd = open (path, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if (fd < 0) {
+ if (errno == EEXIST)
+ return 1;
+ else
+ return -1;
+ }
+
+ close (fd);
+
+ ret = pipe (pipefd);
+ if (ret < 0)
+ err (1, "pipe");
+
+ ret = ioctl (pipefd[1], I_PUSH, "connld");
+ if (ret < 0) {
+ if(errno == ENOSYS)
+ return -1;
+ err (1, "ioctl I_PUSH");
+ }
+
+ ret = fattach (pipefd[1], path);
+ if (ret < 0)
+ err (1, "fattach %s", path);
+
+ s->fd = pipefd[0];
+ close (pipefd[1]);
+ s->pathname = strdup (path);
+ if (s->pathname == NULL)
+ errx (1, "strdup: out of memory");
+ s->flags = STREAM_PIPE;
+ return 0;
+}
+#endif /* MAY_HAVE_X11_PIPES */
+
+/*
+ * Try to create a TCP socket in `s' corresponding to display `dpy'.
+ *
+ * 0 if all is OK
+ * -1 if bind failed badly
+ * 1 if dpy is already used
+ */
+
+static int
+try_tcp (struct x_socket *s, int dpy)
+{
+ struct sockaddr_in tcpaddr;
+ struct in_addr local;
+ int one = 1;
+ int fd;
+
+ memset(&local, 0, sizeof(local));
+ local.s_addr = htonl(INADDR_LOOPBACK);
+
+ fd = socket (AF_INET, SOCK_STREAM, 0);
+ if (fd < 0)
+ err (1, "socket AF_INET");
+#if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT)
+ setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&one,
+ sizeof(one));
+#endif
+ memset (&tcpaddr, 0, sizeof(tcpaddr));
+ tcpaddr.sin_family = AF_INET;
+ tcpaddr.sin_addr = local;
+ tcpaddr.sin_port = htons(6000 + dpy);
+ if (bind (fd, (struct sockaddr *)&tcpaddr,
+ sizeof(tcpaddr)) < 0) {
+ close (fd);
+ if (errno == EADDRINUSE)
+ return 1;
+ else
+ return -1;
+ }
+ s->fd = fd;
+ s->pathname = NULL;
+ s->flags = TCP;
+ return 0;
+}
+
+/*
+ * The potential places to create unix sockets.
+ */
+
+static char *x_sockets[] = {
+X_UNIX_PATH "%u",
+"/var/X/.X11-unix/X" "%u",
+"/usr/spool/sockets/X11/" "%u",
+NULL
+};
+
+/*
+ * Dito for stream pipes.
+ */
+
+#ifdef MAY_HAVE_X11_PIPES
+static char *x_pipes[] = {
+X_PIPE_PATH "%u",
+"/var/X/.X11-pipe/X" "%u",
+NULL
+};
+#endif
+
+/*
+ * Create the directory corresponding to dirname of `path' or fail.
+ */
+
+static void
+try_mkdir (const char *path)
+{
+ char *dir;
+ char *p;
+ int oldmask;
+
+ if((dir = strdup (path)) == NULL)
+ errx (1, "strdup: out of memory");
+ p = strrchr (dir, '/');
+ if (p)
+ *p = '\0';
+
+ oldmask = umask(0);
+ mkdir (dir, 01777);
+ umask (oldmask);
+ free (dir);
+}
+
+/*
+ * Allocate a display, returning the number of sockets in `number' and
+ * all the corresponding sockets in `sockets'. If `tcp_socket' is
+ * true, also allcoaet a TCP socket.
+ *
+ * The return value is the display allocated or -1 if an error occurred.
+ */
+
+int
+get_xsockets (int *number, struct x_socket **sockets, int tcp_socket)
+{
+ int dpy;
+ struct x_socket *s;
+ int n;
+ int i;
+
+ s = malloc (sizeof(*s) * 5);
+ if (s == NULL)
+ errx (1, "malloc: out of memory");
+
+ try_mkdir (X_UNIX_PATH);
+ try_mkdir (X_PIPE_PATH);
+
+ for(dpy = 4; dpy < 256; ++dpy) {
+ char **path;
+ int tmp = 0;
+
+ n = 0;
+ for (path = x_sockets; *path; ++path) {
+ tmp = try_socket (&s[n], dpy, *path);
+ if (tmp == -1) {
+ if (errno != ENOTDIR && errno != ENOENT)
+ err(1, "failed to open '%s'", *path);
+ } else if (tmp == 1) {
+ while(--n >= 0) {
+ close (s[n].fd);
+ free (s[n].pathname);
+ }
+ break;
+ } else if (tmp == 0)
+ ++n;
+ }
+ if (tmp == 1)
+ continue;
+
+#ifdef MAY_HAVE_X11_PIPES
+ for (path = x_pipes; *path; ++path) {
+ tmp = try_pipe (&s[n], dpy, *path);
+ if (tmp == -1) {
+ if (errno != ENOTDIR && errno != ENOENT && errno != ENOSYS)
+ err(1, "failed to open '%s'", *path);
+ } else if (tmp == 1) {
+ while (--n >= 0) {
+ close (s[n].fd);
+ free (s[n].pathname);
+ }
+ break;
+ } else if (tmp == 0)
+ ++n;
+ }
+
+ if (tmp == 1)
+ continue;
+#endif
+
+ if (tcp_socket) {
+ tmp = try_tcp (&s[n], dpy);
+ if (tmp == -1)
+ err(1, "failed to open tcp stocket");
+ else if (tmp == 1) {
+ while (--n >= 0) {
+ close (s[n].fd);
+ free (s[n].pathname);
+ }
+ break;
+ } else if (tmp == 0)
+ ++n;
+ }
+ break;
+ }
+ if (dpy == 256)
+ errx (1, "no free x-servers");
+ for (i = 0; i < n; ++i)
+ if (s[i].flags & LISTENP
+ && listen (s[i].fd, SOMAXCONN) < 0)
+ err (1, "listen %s", s[i].pathname ? s[i].pathname : "tcp");
+ *number = n;
+ *sockets = s;
+ return dpy;
+}
+
+/*
+ * Change owner on the `n' sockets in `sockets' to `uid', `gid'.
+ * Return 0 is succesful or -1 if an error occurred.
+ */
+
+int
+chown_xsockets (int n, struct x_socket *sockets, uid_t uid, gid_t gid)
+{
+ int i;
+
+ for (i = 0; i < n; ++i)
+ if (sockets[i].pathname != NULL)
+ if (chown (sockets[i].pathname, uid, gid) < 0)
+ return -1;
+ return 0;
+}
+
+/*
+ * Connect to local display `dnr' with local transport or TCP.
+ * Return a file descriptor.
+ */
+
+int
+connect_local_xsocket (unsigned dnr)
+{
+ int fd;
+ char **path;
+
+ for (path = x_sockets; *path; ++path) {
+ struct sockaddr_un addr;
+
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0)
+ break;
+ memset (&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ snprintf (addr.sun_path, sizeof(addr.sun_path), *path, dnr);
+ if (connect (fd, (struct sockaddr *)&addr, sizeof(addr)) == 0)
+ return fd;
+ close(fd);
+ }
+ {
+ struct sockaddr_in addr;
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0)
+ err (1, "socket AF_INET");
+ memset (&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ addr.sin_port = htons(6000 + dnr);
+ if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == 0)
+ return fd;
+ close(fd);
+ }
+ err (1, "connecting to local display %u", dnr);
+}
+
+/*
+ * Create a cookie file with a random cookie for the localhost. The
+ * file name will be stored in `xauthfile' (but not larger than
+ * `xauthfile_size'), and the cookie returned in `cookie', `cookie_sz'.
+ * Return 0 if succesful, or errno.
+ */
+
+int
+create_and_write_cookie (char *file,
+ size_t file_size,
+ u_char *cookie_buf,
+ size_t cookie_sz)
+{
+ Xauth auth;
+ char tmp[64];
+ int fd;
+ FILE *f;
+ char hostname[MaxHostNameLen];
+ int saved_errno;
+
+ gethostname (hostname, sizeof(hostname));
+
+ auth.family = FamilyLocal;
+ auth.address = hostname;
+ auth.address_length = strlen(auth.address);
+ snprintf (tmp, sizeof(tmp), "%d", display_num);
+ auth.number_length = strlen(tmp);
+ auth.number = tmp;
+ auth.name = COOKIE_TYPE;
+ auth.name_length = strlen(auth.name);
+ auth.data_length = cookie_sz;
+ auth.data = (char*)cookie_buf;
+#ifdef KRB5
+ krb5_generate_random_block (cookie_buf, cookie_sz);
+#else
+ krb_generate_random_block (cookie_buf, cookie_sz);
+#endif
+
+ strlcpy(file, "/tmp/AXXXXXX", file_size);
+ fd = mkstemp(file);
+ if(fd < 0) {
+ saved_errno = errno;
+ syslog(LOG_ERR, "create_and_write_cookie: mkstemp: %m");
+ return saved_errno;
+ }
+ f = fdopen(fd, "r+");
+ if(f == NULL){
+ saved_errno = errno;
+ close(fd);
+ return errno;
+ }
+ if(XauWriteAuth(f, &auth) == 0) {
+ saved_errno = errno;
+ fclose(f);
+ return saved_errno;
+ }
+
+ /*
+ * I would like to write a cookie for localhost:n here, but some
+ * stupid code in libX11 will not look for cookies of that type,
+ * so we are forced to use FamilyWild instead.
+ */
+
+ auth.family = FamilyWild;
+ auth.address_length = 0;
+
+ if (XauWriteAuth(f, &auth) == 0) {
+ saved_errno = errno;
+ fclose (f);
+ return saved_errno;
+ }
+
+ if(fclose(f))
+ return errno;
+ return 0;
+}
+
+/*
+ * Verify and remove cookies. Read and parse a X-connection from
+ * `fd'. Check the cookie used is the same as in `cookie'. Remove the
+ * cookie and copy the rest of it to `sock'.
+ * Expect cookies iff cookiesp.
+ * Return 0 iff ok.
+ *
+ * The protocol is as follows:
+ *
+ * C->S: [Bl] 1
+ * unused 1
+ * protocol major version 2
+ * protocol minor version 2
+ * length of auth protocol name(n) 2
+ * length of auth protocol data 2
+ * unused 2
+ * authorization protocol name n
+ * pad pad(n)
+ * authorization protocol data d
+ * pad pad(d)
+ *
+ * S->C: Failed
+ * 0 1
+ * length of reason 1
+ * protocol major version 2
+ * protocol minor version 2
+ * length in 4 bytes unit of
+ * additional data (n+p)/4 2
+ * reason n
+ * unused p = pad(n)
+ */
+
+int
+verify_and_remove_cookies (int fd, int sock, int cookiesp)
+{
+ u_char beg[12];
+ int bigendianp;
+ unsigned n, d, npad, dpad;
+ char *protocol_name, *protocol_data;
+ u_char zeros[6] = {0, 0, 0, 0, 0, 0};
+ u_char refused[20] = {0, 10,
+ 0, 0, /* protocol major version */
+ 0, 0, /* protocol minor version */
+ 0, 0, /* length of additional data / 4 */
+ 'b', 'a', 'd', ' ', 'c', 'o', 'o', 'k', 'i', 'e',
+ 0, 0};
+
+ if (net_read (fd, beg, sizeof(beg)) != sizeof(beg))
+ return 1;
+ if (net_write (sock, beg, 6) != 6)
+ return 1;
+ bigendianp = beg[0] == 'B';
+ if (bigendianp) {
+ n = (beg[6] << 8) | beg[7];
+ d = (beg[8] << 8) | beg[9];
+ } else {
+ n = (beg[7] << 8) | beg[6];
+ d = (beg[9] << 8) | beg[8];
+ }
+ npad = (4 - (n % 4)) % 4;
+ dpad = (4 - (d % 4)) % 4;
+ protocol_name = malloc(n + npad);
+ if (n + npad != 0 && protocol_name == NULL)
+ return 1;
+ protocol_data = malloc(d + dpad);
+ if (d + dpad != 0 && protocol_data == NULL) {
+ free (protocol_name);
+ return 1;
+ }
+ if (net_read (fd, protocol_name, n + npad) != n + npad)
+ goto fail;
+ if (net_read (fd, protocol_data, d + dpad) != d + dpad)
+ goto fail;
+ if (cookiesp) {
+ if (strncmp (protocol_name, COOKIE_TYPE, strlen(COOKIE_TYPE)) != 0)
+ goto refused;
+ if (d != cookie_len ||
+ memcmp (protocol_data, cookie, cookie_len) != 0)
+ goto refused;
+ }
+ free (protocol_name);
+ free (protocol_data);
+ if (net_write (sock, zeros, 6) != 6)
+ return 1;
+ return 0;
+refused:
+ refused[2] = beg[2];
+ refused[3] = beg[3];
+ refused[4] = beg[4];
+ refused[5] = beg[5];
+ if (bigendianp)
+ refused[7] = 3;
+ else
+ refused[6] = 3;
+
+ net_write (fd, refused, sizeof(refused));
+fail:
+ free (protocol_name);
+ free (protocol_data);
+ return 1;
+}
+
+/*
+ * Return 0 iff `cookie' is compatible with the cookie for the
+ * localhost with name given in `ai' (or `hostname') and display
+ * number in `disp_nr'.
+ */
+
+static int
+match_local_auth (Xauth* auth,
+ struct addrinfo *ai, const char *hostname, int disp_nr)
+{
+ int auth_disp;
+ char *tmp_disp;
+ struct addrinfo *a;
+
+ tmp_disp = malloc(auth->number_length + 1);
+ if (tmp_disp == NULL)
+ return -1;
+ memcpy(tmp_disp, auth->number, auth->number_length);
+ tmp_disp[auth->number_length] = '\0';
+ auth_disp = atoi(tmp_disp);
+ free (tmp_disp);
+ if (auth_disp != disp_nr)
+ return 1;
+ for (a = ai; a != NULL; a = a->ai_next) {
+ if ((auth->family == FamilyLocal
+ || auth->family == FamilyWild)
+ && a->ai_canonname != NULL
+ && strncmp (auth->address,
+ a->ai_canonname,
+ auth->address_length) == 0)
+ return 0;
+ }
+ if (hostname != NULL
+ && (auth->family == FamilyLocal
+ || auth->family == FamilyWild)
+ && strncmp (auth->address, hostname, auth->address_length) == 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Find `our' cookie from the cookie file `f' and return it or NULL.
+ */
+
+static Xauth*
+find_auth_cookie (FILE *f)
+{
+ Xauth *ret = NULL;
+ char local_hostname[MaxHostNameLen];
+ char *display_str = getenv("DISPLAY");
+ char d[MaxHostNameLen + 4];
+ char *colon;
+ struct addrinfo *ai;
+ struct addrinfo hints;
+ int disp;
+ int error;
+
+ if(display_str == NULL)
+ display_str = ":0";
+ strlcpy(d, display_str, sizeof(d));
+ display_str = d;
+ colon = strchr (display_str, ':');
+ if (colon == NULL)
+ disp = 0;
+ else {
+ *colon = '\0';
+ disp = atoi (colon + 1);
+ }
+ if (strcmp (display_str, "") == 0
+ || strncmp (display_str, "unix", 4) == 0
+ || strncmp (display_str, "localhost", 9) == 0) {
+ gethostname (local_hostname, sizeof(local_hostname));
+ display_str = local_hostname;
+ }
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ error = getaddrinfo (display_str, NULL, &hints, &ai);
+ if (error)
+ ai = NULL;
+
+ for (; (ret = XauReadAuth (f)) != NULL; XauDisposeAuth(ret)) {
+ if (match_local_auth (ret, ai, display_str, disp) == 0) {
+ if (ai != NULL)
+ freeaddrinfo (ai);
+ return ret;
+ }
+ }
+ if (ai != NULL)
+ freeaddrinfo (ai);
+ return NULL;
+}
+
+/*
+ * Get rid of the cookie that we were sent and get the correct one
+ * from our own cookie file instead.
+ */
+
+int
+replace_cookie(int xserver, int fd, char *filename, int cookiesp) /* XXX */
+{
+ u_char beg[12];
+ int bigendianp;
+ unsigned n, d, npad, dpad;
+ FILE *f;
+ u_char zeros[6] = {0, 0, 0, 0, 0, 0};
+
+ if (net_read (fd, beg, sizeof(beg)) != sizeof(beg))
+ return 1;
+ if (net_write (xserver, beg, 6) != 6)
+ return 1;
+ bigendianp = beg[0] == 'B';
+ if (bigendianp) {
+ n = (beg[6] << 8) | beg[7];
+ d = (beg[8] << 8) | beg[9];
+ } else {
+ n = (beg[7] << 8) | beg[6];
+ d = (beg[9] << 8) | beg[8];
+ }
+ if (n != 0 || d != 0)
+ return 1;
+ f = fopen(filename, "r");
+ if (f != NULL) {
+ Xauth *auth = find_auth_cookie (f);
+ u_char len[6] = {0, 0, 0, 0, 0, 0};
+
+ fclose (f);
+
+ if (auth != NULL) {
+ n = auth->name_length;
+ d = auth->data_length;
+ } else {
+ n = 0;
+ d = 0;
+ }
+ if (bigendianp) {
+ len[0] = n >> 8;
+ len[1] = n & 0xFF;
+ len[2] = d >> 8;
+ len[3] = d & 0xFF;
+ } else {
+ len[0] = n & 0xFF;
+ len[1] = n >> 8;
+ len[2] = d & 0xFF;
+ len[3] = d >> 8;
+ }
+ if (net_write (xserver, len, 6) != 6) {
+ XauDisposeAuth(auth);
+ return 1;
+ }
+ if(n != 0 && net_write (xserver, auth->name, n) != n) {
+ XauDisposeAuth(auth);
+ return 1;
+ }
+ npad = (4 - (n % 4)) % 4;
+ if (npad && net_write (xserver, zeros, npad) != npad) {
+ XauDisposeAuth(auth);
+ return 1;
+ }
+ if (d != 0 && net_write (xserver, auth->data, d) != d) {
+ XauDisposeAuth(auth);
+ return 1;
+ }
+ XauDisposeAuth(auth);
+ dpad = (4 - (d % 4)) % 4;
+ if (dpad && net_write (xserver, zeros, dpad) != dpad)
+ return 1;
+ } else {
+ if(net_write(xserver, zeros, 6) != 6)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Some simple controls on the address and corresponding socket
+ */
+
+int
+suspicious_address (int sock, struct sockaddr *addr)
+{
+ char data[40];
+ socklen_t len = sizeof(data);
+
+ switch (addr->sa_family) {
+ case AF_INET:
+ return ((struct sockaddr_in *)addr)->sin_addr.s_addr !=
+ htonl(INADDR_LOOPBACK)
+#if defined(IP_OPTIONS) && defined(HAVE_GETSOCKOPT)
+ || getsockopt (sock, IPPROTO_IP, IP_OPTIONS, data, &len) < 0
+ || len != 0
+#endif
+ ;
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ /* XXX check route headers */
+ return !IN6_IS_ADDR_LOOPBACK(&((struct sockaddr_in6*)addr)->sin6_addr);
+#endif
+ default:
+ return 1;
+ }
+}
+
+/*
+ * This really sucks, but these functions are used and if we're not
+ * linking against libkrb they don't exist. Using the heimdal storage
+ * functions will not work either cause we do not always link with
+ * libkrb5 either.
+ */
+
+int
+kx_get_int(void *f, uint32_t *to, int size, int lsb)
+{
+ int i;
+ unsigned char *from = (unsigned char *)f;
+
+ *to = 0;
+ if(lsb){
+ for(i = size-1; i >= 0; i--)
+ *to = (*to << 8) | from[i];
+ }else{
+ for(i = 0; i < size; i++)
+ *to = (*to << 8) | from[i];
+ }
+ return size;
+}
+
+int
+kx_put_int(uint32_t from, void *to, size_t rem, int size)
+{
+ int i;
+ unsigned char *p = (unsigned char *)to;
+
+ if (rem < size)
+ return -1;
+
+ for(i = size - 1; i >= 0; i--){
+ p[i] = from & 0xff;
+ from >>= 8;
+ }
+ return size;
+}
diff --git a/appl/kx/context.c b/appl/kx/context.c
new file mode 100644
index 000000000000..a0520a3822d6
--- /dev/null
+++ b/appl/kx/context.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1995 - 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 "kx.h"
+
+RCSID("$Id$");
+
+/*
+ * Set the common part of the context `kc'
+ */
+
+void
+context_set (kx_context *kc, const char *host, const char *user, int port,
+ int debug_flag, int keepalive_flag, int tcp_flag)
+{
+ kc->thisaddr = (struct sockaddr*)&kc->__ss_this;
+ kc->thataddr = (struct sockaddr*)&kc->__ss_that;
+ kc->host = host;
+ kc->user = user;
+ kc->port = port;
+ kc->debug_flag = debug_flag;
+ kc->keepalive_flag = keepalive_flag;
+ kc->tcp_flag = tcp_flag;
+}
+
+/*
+ * dispatch functions
+ */
+
+void
+context_destroy (kx_context *kc)
+{
+ (*kc->destroy)(kc);
+}
+
+int
+context_authenticate (kx_context *kc, int s)
+{
+ return (*kc->authenticate)(kc, s);
+}
+
+int
+context_userok (kx_context *kc, char *user)
+{
+ return (*kc->userok)(kc, user);
+}
+
+ssize_t
+kx_read (kx_context *kc, int fd, void *buf, size_t len)
+{
+ return (*kc->read)(kc, fd, buf, len);
+}
+
+ssize_t
+kx_write (kx_context *kc, int fd, const void *buf, size_t len)
+{
+ return (*kc->write)(kc, fd, buf, len);
+}
+
+int
+copy_encrypted (kx_context *kc, int fd1, int fd2)
+{
+ return (*kc->copy_encrypted)(kc, fd1, fd2);
+}
diff --git a/appl/kx/krb5.c b/appl/kx/krb5.c
new file mode 100644
index 000000000000..eeb62a2d2694
--- /dev/null
+++ b/appl/kx/krb5.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 1995 - 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 "kx.h"
+
+RCSID("$Id$");
+
+#ifdef KRB5
+
+struct krb5_kx_context {
+ krb5_context context;
+ krb5_keyblock *keyblock;
+ krb5_crypto crypto;
+ krb5_principal client;
+ krb5_log_facility *log;
+
+};
+
+typedef struct krb5_kx_context krb5_kx_context;
+
+#define K5DATA(kc) ((krb5_kx_context*)kc->data)
+#define CONTEXT(kc) (K5DATA(kc)->context)
+
+/*
+ *
+ */
+
+static void
+ksyslog(krb5_context context, krb5_error_code ret, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 3, 0)));
+
+static void
+ksyslog(krb5_context context, krb5_error_code ret, const char *fmt, ...)
+{
+ const char *msg;
+ char *str = NULL;
+ va_list va;
+
+ msg = krb5_get_error_message(context, ret);
+
+ va_start(va, fmt);
+ vasprintf(&str, fmt, va);
+ va_end(va);
+
+ syslog(LOG_ERR, "%s: %s", str, msg);
+
+ krb5_free_error_message(context, msg);
+ free(str);
+}
+
+/*
+ * Destroy the krb5 context in `c'.
+ */
+
+static void
+krb5_destroy (kx_context *kc)
+{
+ if (K5DATA(kc)->keyblock)
+ krb5_free_keyblock (CONTEXT(kc), K5DATA(kc)->keyblock);
+ if (K5DATA(kc)->crypto)
+ krb5_crypto_destroy (CONTEXT(kc), K5DATA(kc)->crypto);
+ if (K5DATA(kc)->client)
+ krb5_free_principal (CONTEXT(kc), K5DATA(kc)->client);
+ if (CONTEXT(kc))
+ krb5_free_context (CONTEXT(kc));
+ memset (kc->data, 0, sizeof(krb5_kx_context));
+ free (kc->data);
+}
+
+/*
+ * Read the authentication information from `s' and return 0 if
+ * succesful, else -1.
+ */
+
+static int
+krb5_authenticate (kx_context *kc, int s)
+{
+ krb5_auth_context auth_context = NULL;
+ krb5_error_code ret;
+ krb5_principal server;
+ const char *host = kc->host;
+
+ ret = krb5_sname_to_principal (CONTEXT(kc),
+ host, "host", KRB5_NT_SRV_HST, &server);
+ if (ret) {
+ krb5_warn (CONTEXT(kc), ret, "krb5_sname_to_principal: %s", host);
+ return 1;
+ }
+
+ ret = krb5_sendauth (CONTEXT(kc),
+ &auth_context,
+ &s,
+ KX_VERSION,
+ NULL,
+ server,
+ AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (ret) {
+ if(ret != KRB5_SENDAUTH_BADRESPONSE)
+ krb5_warn (CONTEXT(kc), ret, "krb5_sendauth: %s", host);
+ return 1;
+ }
+
+ ret = krb5_auth_con_getkey (CONTEXT(kc), auth_context,
+ &K5DATA(kc)->keyblock);
+ if (ret) {
+ krb5_warn (CONTEXT(kc), ret, "krb5_auth_con_getkey: %s", host);
+ krb5_auth_con_free (CONTEXT(kc), auth_context);
+ return 1;
+ }
+
+ ret = krb5_crypto_init (CONTEXT(kc), K5DATA(kc)->keyblock,
+ 0, &K5DATA(kc)->crypto);
+ if (ret) {
+ krb5_warn (CONTEXT(kc), ret, "krb5_crypto_init");
+ krb5_auth_con_free (CONTEXT(kc), auth_context);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Read an encapsulated krb5 packet from `fd' into `buf' (of size
+ * `len'). Return the number of bytes read or 0 on EOF or -1 on
+ * error.
+ */
+
+static ssize_t
+krb5_read (kx_context *kc,
+ int fd, void *buf, size_t len)
+{
+ size_t data_len, outer_len;
+ krb5_error_code ret;
+ unsigned char tmp[4];
+ krb5_data data;
+ int l;
+
+ l = krb5_net_read (CONTEXT(kc), &fd, tmp, 4);
+ if (l == 0)
+ return l;
+ if (l != 4)
+ return -1;
+ data_len = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3];
+ outer_len = krb5_get_wrapped_length (CONTEXT(kc),
+ K5DATA(kc)->crypto, data_len);
+ if (outer_len > len)
+ return -1;
+ if (krb5_net_read (CONTEXT(kc), &fd, buf, outer_len) != outer_len)
+ return -1;
+
+ ret = krb5_decrypt (CONTEXT(kc), K5DATA(kc)->crypto,
+ KRB5_KU_OTHER_ENCRYPTED,
+ buf, outer_len, &data);
+ if (ret) {
+ krb5_warn (CONTEXT(kc), ret, "krb5_decrypt");
+ return -1;
+ }
+ if (data_len > data.length) {
+ krb5_data_free (&data);
+ return -1;
+ }
+ memmove (buf, data.data, data_len);
+ krb5_data_free (&data);
+ return data_len;
+}
+
+/*
+ * Write an encapsulated krb5 packet on `fd' with the data in `buf,
+ * len'. Return len or -1 on error.
+ */
+
+static ssize_t
+krb5_write(kx_context *kc,
+ int fd, const void *buf, size_t len)
+{
+ krb5_data data;
+ krb5_error_code ret;
+ unsigned char tmp[4];
+ size_t outlen;
+
+ ret = krb5_encrypt (CONTEXT(kc), K5DATA(kc)->crypto,
+ KRB5_KU_OTHER_ENCRYPTED,
+ buf, len, &data);
+ if (ret){
+ krb5_warn (CONTEXT(kc), ret, "krb5_write");
+ return -1;
+ }
+
+ outlen = data.length;
+ tmp[0] = (len >> 24) & 0xFF;
+ tmp[1] = (len >> 16) & 0xFF;
+ tmp[2] = (len >> 8) & 0xFF;
+ tmp[3] = (len >> 0) & 0xFF;
+
+ if (krb5_net_write (CONTEXT(kc), &fd, tmp, 4) != 4 ||
+ krb5_net_write (CONTEXT(kc), &fd, data.data, outlen) != outlen) {
+ krb5_data_free (&data);
+ return -1;
+ }
+ krb5_data_free (&data);
+ return len;
+}
+
+/*
+ * Copy from the unix socket `from_fd' encrypting to `to_fd'.
+ * Return 0, -1 or len.
+ */
+
+static int
+copy_out (kx_context *kc, int from_fd, int to_fd)
+{
+ char buf[32768];
+ ssize_t len;
+
+ len = read (from_fd, buf, sizeof(buf));
+ if (len == 0)
+ return 0;
+ if (len < 0) {
+ krb5_warn (CONTEXT(kc), errno, "read");
+ return len;
+ }
+ return krb5_write (kc, to_fd, buf, len);
+}
+
+/*
+ * Copy from the socket `from_fd' decrypting to `to_fd'.
+ * Return 0, -1 or len.
+ */
+
+static int
+copy_in (kx_context *kc, int from_fd, int to_fd)
+{
+ char buf[33000]; /* XXX */
+
+ ssize_t len;
+
+ len = krb5_read (kc, from_fd, buf, sizeof(buf));
+ if (len == 0)
+ return 0;
+ if (len < 0) {
+ krb5_warn (CONTEXT(kc), errno, "krb5_read");
+ return len;
+ }
+
+ return krb5_net_write (CONTEXT(kc), &to_fd, buf, len);
+}
+
+/*
+ * Copy data between `fd1' and `fd2', encrypting in one direction and
+ * decrypting in the other.
+ */
+
+static int
+krb5_copy_encrypted (kx_context *kc, int fd1, int fd2)
+{
+ for (;;) {
+ fd_set fdset;
+ int ret;
+
+ if (fd1 >= FD_SETSIZE || fd2 >= FD_SETSIZE) {
+ krb5_warnx (CONTEXT(kc), "fd too large");
+ return 1;
+ }
+
+ FD_ZERO(&fdset);
+ FD_SET(fd1, &fdset);
+ FD_SET(fd2, &fdset);
+
+ ret = select (max(fd1, fd2)+1, &fdset, NULL, NULL, NULL);
+ if (ret < 0 && errno != EINTR) {
+ krb5_warn (CONTEXT(kc), errno, "select");
+ return 1;
+ }
+ if (FD_ISSET(fd1, &fdset)) {
+ ret = copy_out (kc, fd1, fd2);
+ if (ret <= 0)
+ return ret;
+ }
+ if (FD_ISSET(fd2, &fdset)) {
+ ret = copy_in (kc, fd2, fd1);
+ if (ret <= 0)
+ return ret;
+ }
+ }
+}
+
+/*
+ * Return 0 if the user authenticated on `kc' is allowed to login as
+ * `user'.
+ */
+
+static int
+krb5_userok (kx_context *kc, char *user)
+{
+ krb5_error_code ret;
+ char *tmp;
+
+ ret = krb5_unparse_name (CONTEXT(kc), K5DATA(kc)->client, &tmp);
+ if (ret)
+ krb5_err (CONTEXT(kc), 1, ret, "krb5_unparse_name");
+ kc->user = tmp;
+
+ return !krb5_kuserok (CONTEXT(kc), K5DATA(kc)->client, user);
+}
+
+/*
+ * Create an instance of an krb5 context.
+ */
+
+void
+krb5_make_context (kx_context *kc)
+{
+ krb5_kx_context *c;
+ krb5_error_code ret;
+
+ kc->authenticate = krb5_authenticate;
+ kc->userok = krb5_userok;
+ kc->read = krb5_read;
+ kc->write = krb5_write;
+ kc->copy_encrypted = krb5_copy_encrypted;
+ kc->destroy = krb5_destroy;
+ kc->user = NULL;
+ kc->data = malloc(sizeof(krb5_kx_context));
+
+ if (kc->data == NULL) {
+ syslog (LOG_ERR, "failed to malloc %lu bytes",
+ (unsigned long)sizeof(krb5_kx_context));
+ exit(1);
+ }
+ memset (kc->data, 0, sizeof(krb5_kx_context));
+ c = (krb5_kx_context *)kc->data;
+ ret = krb5_init_context (&c->context);
+ if (ret) {
+ syslog (LOG_ERR, "failed initialise krb5 context");
+ exit(1);
+ }
+}
+
+/*
+ * Receive authentication information on `sock' (first four bytes
+ * in `buf').
+ */
+
+int
+recv_v5_auth (kx_context *kc, int sock, u_char *buf)
+{
+ uint32_t len;
+ krb5_error_code ret;
+ krb5_principal server;
+ krb5_auth_context auth_context = NULL;
+ krb5_ticket *ticket;
+
+ if (memcmp (buf, "\x00\x00\x00\x13", 4) != 0)
+ return 1;
+ len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]);
+ if (net_read(sock, buf, len) != len) {
+ syslog (LOG_ERR, "read: %m");
+ exit (1);
+ }
+ if (len != sizeof(KRB5_SENDAUTH_VERSION)
+ || memcmp (buf, KRB5_SENDAUTH_VERSION, len) != 0) {
+ syslog (LOG_ERR, "bad sendauth version: %.8s", buf);
+ exit (1);
+ }
+
+ krb5_make_context (kc);
+ krb5_openlog(CONTEXT(kc), "kxd", &K5DATA(kc)->log);
+ krb5_set_warn_dest(CONTEXT(kc), K5DATA(kc)->log);
+
+ ret = krb5_sock_to_principal (CONTEXT(kc), sock, "host",
+ KRB5_NT_SRV_HST, &server);
+ if (ret) {
+ ksyslog (CONTEXT(kc), ret, "krb5_sock_to_principal");
+ exit (1);
+ }
+
+ ret = krb5_recvauth (CONTEXT(kc),
+ &auth_context,
+ &sock,
+ KX_VERSION,
+ server,
+ KRB5_RECVAUTH_IGNORE_VERSION,
+ NULL,
+ &ticket);
+ krb5_free_principal (CONTEXT(kc), server);
+ if (ret) {
+ ksyslog (CONTEXT(kc), ret, "krb5_recvauth");
+ exit (1);
+ }
+
+ ret = krb5_auth_con_getkey (CONTEXT(kc), auth_context, &K5DATA(kc)->keyblock);
+ if (ret) {
+ ksyslog (CONTEXT(kc), ret, "krb5_auth_con_getkey");
+ exit (1);
+ }
+
+ ret = krb5_crypto_init (CONTEXT(kc), K5DATA(kc)->keyblock, 0, &K5DATA(kc)->crypto);
+ if (ret) {
+ ksyslog (CONTEXT(kc), ret, "krb5_crypto_init");
+ exit (1);
+ }
+
+ K5DATA(kc)->client = ticket->client;
+ ticket->client = NULL;
+ krb5_free_ticket (CONTEXT(kc), ticket);
+
+ krb5_auth_con_free(CONTEXT(kc), auth_context);
+
+ return 0;
+}
+
+#endif /* KRB5 */
diff --git a/appl/kx/kx.1 b/appl/kx/kx.1
new file mode 100644
index 000000000000..2f5e35cecdf9
--- /dev/null
+++ b/appl/kx/kx.1
@@ -0,0 +1,92 @@
+.\" Copyright (c) 1996 - 1997 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$
+.\"
+.Dd September 27, 1996
+.Dt KX 1
+.Os KTH-KRB
+.Sh NAME
+.Nm kx
+.Nd securely forward X conections
+.Sh SYNOPSIS
+.Ar kx
+.Op Fl l Ar username
+.Op Fl k
+.Op Fl d
+.Op Fl t
+.Op Fl p Ar port
+.Op Fl P
+.Ar host
+.Sh DESCRIPTION
+The
+.Nm
+program forwards an X connection from a remote client to a local screen
+through an authenticated and encrypted stream. Options supported by
+.Nm kx :
+.Bl -tag -width Ds
+.It Fl l
+Log in on the remote the host as user
+.Ar username .
+.It Fl k
+Do not enable keep-alives on the TCP connections.
+.It Fl d
+Do not fork. This is mainly useful for debugging.
+.It Fl t
+Listen not only on a UNIX-domain socket but on a TCP socket as well.
+.It Fl p
+Use the port
+.Ar port .
+.It Fl P
+Force passive mode.
+.El
+.Pp
+This program is used by
+.Nm rxtelnet
+and
+.Nm rxterm
+and you should not need to run it directly.
+.Pp
+It connects to a
+.Nm kxd
+on the host
+.Ar host
+and then will relay the traffic from the remote X clients to the local
+server. When started, it prints the display and Xauthority-file to be
+used on host
+.Ar host
+and then goes to the background, waiting for connections from the
+remote
+.Nm kxd .
+.Sh SEE ALSO
+.Xr rxtelnet 1 ,
+.Xr rxterm 1 ,
+.Xr kxd 8
diff --git a/appl/kx/kx.c b/appl/kx/kx.c
new file mode 100644
index 000000000000..ffc2e85b58c1
--- /dev/null
+++ b/appl/kx/kx.c
@@ -0,0 +1,711 @@
+/*
+ * Copyright (c) 1995-2003 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 "kx.h"
+
+RCSID("$Id$");
+
+static int nchild;
+static int donep;
+
+/*
+ * Signal handler that justs waits for the children when they die.
+ */
+
+static RETSIGTYPE
+childhandler (int sig)
+{
+ pid_t pid;
+ int status;
+
+ do {
+ pid = waitpid (-1, &status, WNOHANG|WUNTRACED);
+ if (pid > 0 && (WIFEXITED(status) || WIFSIGNALED(status)))
+ if (--nchild == 0 && donep)
+ exit (0);
+ } while(pid > 0);
+ signal (SIGCHLD, childhandler);
+ SIGRETURN(0);
+}
+
+/*
+ * Handler for SIGUSR1.
+ * This signal means that we should wait until there are no children
+ * left and then exit.
+ */
+
+static RETSIGTYPE
+usr1handler (int sig)
+{
+ donep = 1;
+
+ SIGRETURN(0);
+}
+
+/*
+ * Almost the same as for SIGUSR1, except we should exit immediately
+ * if there are no active children.
+ */
+
+static RETSIGTYPE
+usr2handler (int sig)
+{
+ donep = 1;
+ if (nchild == 0)
+ exit (0);
+
+ SIGRETURN(0);
+}
+
+/*
+ * Establish authenticated connection. Return socket or -1.
+ */
+
+static int
+connect_host (kx_context *kc)
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+ socklen_t addrlen;
+ int s = -1;
+ struct sockaddr_storage thisaddr_ss;
+ struct sockaddr *thisaddr = (struct sockaddr *)&thisaddr_ss;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(kc->port));
+
+ error = getaddrinfo (kc->host, portstr, &hints, &ai);
+ if (error) {
+ warnx ("%s: %s", kc->host, gai_strerror(error));
+ return -1;
+ }
+
+ 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)", kc->host);
+ close (s);
+ continue;
+ }
+ break;
+ }
+
+ if (a == NULL) {
+ freeaddrinfo (ai);
+ return -1;
+ }
+
+ addrlen = sizeof(thisaddr_ss);
+ if (getsockname (s, thisaddr, &addrlen) < 0 ||
+ addrlen != a->ai_addrlen)
+ err(1, "getsockname(%s)", kc->host);
+ memcpy (&kc->__ss_this, thisaddr, sizeof(kc->__ss_this));
+ kc->thisaddr_len = addrlen;
+ memcpy (&kc->__ss_that, a->ai_addr, sizeof(kc->__ss_that));
+ kc->thataddr_len = a->ai_addrlen;
+ freeaddrinfo (ai);
+ if ((*kc->authenticate)(kc, s))
+ return -1;
+ return s;
+}
+
+/*
+ * Get rid of the cookie that we were sent and get the correct one
+ * from our own cookie file instead and then just copy data in both
+ * directions.
+ */
+
+static int
+passive_session (int xserver, int fd, kx_context *kc)
+{
+ if (replace_cookie (xserver, fd, XauFileName(), 1))
+ return 1;
+ else
+ return copy_encrypted (kc, xserver, fd);
+}
+
+static int
+active_session (int xserver, int fd, kx_context *kc)
+{
+ if (verify_and_remove_cookies (xserver, fd, 1))
+ return 1;
+ else
+ return copy_encrypted (kc, xserver, fd);
+}
+
+/*
+ * fork (unless debugp) and print the output that will be used by the
+ * script to capture the display, xauth cookie and pid.
+ */
+
+static void
+status_output (int debugp)
+{
+ if(debugp)
+ printf ("%u\t%s\t%s\n", (unsigned)getpid(), display, xauthfile);
+ else {
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0) {
+ err(1, "fork");
+ } else if (pid > 0) {
+ printf ("%u\t%s\t%s\n", (unsigned)pid, display, xauthfile);
+ exit (0);
+ } else {
+ fclose(stdout);
+ }
+ }
+}
+
+/*
+ * Obtain an authenticated connection on `kc'. Send a kx message
+ * saying we are `kc->user' and want to use passive mode. Wait for
+ * answer on that connection and fork of a child for every new
+ * connection we have to make.
+ */
+
+static int
+doit_passive (kx_context *kc)
+{
+ int otherside;
+ u_char msg[1024], *p;
+ int len;
+ uint32_t tmp;
+ const char *host = kc->host;
+
+ otherside = connect_host (kc);
+
+ if (otherside < 0)
+ return 1;
+#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
+ if (kc->keepalive_flag) {
+ int one = 1;
+
+ setsockopt (otherside, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
+ sizeof(one));
+ }
+#endif
+
+ p = msg;
+ *p++ = INIT;
+ len = strlen(kc->user);
+ p += kx_put_int (len, p, sizeof(msg) - 1, 4);
+ memcpy(p, kc->user, len);
+ p += len;
+ *p++ = PASSIVE | (kc->keepalive_flag ? KEEP_ALIVE : 0);
+ if (kx_write (kc, otherside, msg, p - msg) != p - msg)
+ err (1, "write to %s", host);
+ len = kx_read (kc, otherside, msg, sizeof(msg));
+ if (len <= 0)
+ errx (1,
+ "error reading initial message from %s: "
+ "this probably means it's using an old version.",
+ host);
+ p = (u_char *)msg;
+ if (*p == ERROR) {
+ p++;
+ p += kx_get_int (p, &tmp, 4, 0);
+ errx (1, "%s: %.*s", host, (int)tmp, p);
+ } else if (*p != ACK) {
+ errx (1, "%s: strange msg %d", host, *p);
+ } else
+ p++;
+ p += kx_get_int (p, &tmp, 4, 0);
+ memcpy(display, p, tmp);
+ display[tmp] = '\0';
+ p += tmp;
+
+ p += kx_get_int (p, &tmp, 4, 0);
+ memcpy(xauthfile, p, tmp);
+ xauthfile[tmp] = '\0';
+ p += tmp;
+
+ status_output (kc->debug_flag);
+ for (;;) {
+ pid_t child;
+
+ len = kx_read (kc, otherside, msg, sizeof(msg));
+ if (len < 0)
+ err (1, "read from %s", host);
+ else if (len == 0)
+ return 0;
+
+ p = (u_char *)msg;
+ if (*p == ERROR) {
+ p++;
+ p += kx_get_int (p, &tmp, 4, 0);
+ errx (1, "%s: %.*s", host, (int)tmp, p);
+ } else if(*p != NEW_CONN) {
+ errx (1, "%s: strange msg %d", host, *p);
+ } else {
+ p++;
+ p += kx_get_int (p, &tmp, 4, 0);
+ }
+
+ ++nchild;
+ child = fork ();
+ if (child < 0) {
+ warn("fork");
+ continue;
+ } else if (child == 0) {
+ int fd;
+ int xserver;
+
+ close (otherside);
+
+ socket_set_port(kc->thataddr, htons(tmp));
+
+ fd = socket (kc->thataddr->sa_family, SOCK_STREAM, 0);
+ if (fd < 0)
+ err(1, "socket");
+#if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT)
+ {
+ int one = 1;
+
+ setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&one,
+ sizeof(one));
+ }
+#endif
+#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
+ if (kc->keepalive_flag) {
+ int one = 1;
+
+ setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
+ sizeof(one));
+ }
+#endif
+
+ if (connect (fd, kc->thataddr, kc->thataddr_len) < 0)
+ err(1, "connect(%s)", host);
+ {
+ int d = 0;
+ char *s;
+
+ s = getenv ("DISPLAY");
+ if (s != NULL) {
+ s = strchr (s, ':');
+ if (s != NULL)
+ d = atoi (s + 1);
+ }
+
+ xserver = connect_local_xsocket (d);
+ if (xserver < 0)
+ return 1;
+ }
+ return passive_session (xserver, fd, kc);
+ } else {
+ }
+ }
+}
+
+/*
+ * Allocate a local pseudo-xserver and wait for connections
+ */
+
+static int
+doit_active (kx_context *kc)
+{
+ int otherside;
+ int nsockets;
+ struct x_socket *sockets;
+ u_char msg[1024], *p;
+ int len;
+ int tmp, tmp2;
+ char *str;
+ int i;
+ size_t rem;
+ uint32_t other_port;
+ int error;
+ const char *host = kc->host;
+
+ otherside = connect_host (kc);
+ if (otherside < 0)
+ return 1;
+#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
+ if (kc->keepalive_flag) {
+ int one = 1;
+
+ setsockopt (otherside, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
+ sizeof(one));
+ }
+#endif
+ p = msg;
+ rem = sizeof(msg);
+ *p++ = INIT;
+ --rem;
+ len = strlen(kc->user);
+ tmp = kx_put_int (len, p, rem, 4);
+ if (tmp < 0)
+ return 1;
+ p += tmp;
+ rem -= tmp;
+ memcpy(p, kc->user, len);
+ p += len;
+ rem -= len;
+ *p++ = (kc->keepalive_flag ? KEEP_ALIVE : 0);
+ --rem;
+
+ str = getenv("DISPLAY");
+ if (str == NULL || (str = strchr(str, ':')) == NULL)
+ str = ":0";
+ len = strlen (str);
+ tmp = kx_put_int (len, p, rem, 4);
+ if (tmp < 0)
+ return 1;
+ rem -= tmp;
+ p += tmp;
+ memcpy (p, str, len);
+ p += len;
+ rem -= len;
+
+ str = getenv("XAUTHORITY");
+ if (str == NULL)
+ str = "";
+ len = strlen (str);
+ tmp = kx_put_int (len, p, rem, 4);
+ if (tmp < 0)
+ return 1;
+ p += len;
+ rem -= len;
+ memcpy (p, str, len);
+ p += len;
+ rem -= len;
+
+ if (kx_write (kc, otherside, msg, p - msg) != p - msg)
+ err (1, "write to %s", host);
+
+ len = kx_read (kc, otherside, msg, sizeof(msg));
+ if (len < 0)
+ err (1, "read from %s", host);
+ p = (u_char *)msg;
+ if (*p == ERROR) {
+ uint32_t u32;
+
+ p++;
+ p += kx_get_int (p, &u32, 4, 0);
+ errx (1, "%s: %.*s", host, (int)u32, p);
+ } else if (*p != ACK) {
+ errx (1, "%s: strange msg %d", host, *p);
+ }
+
+ tmp2 = get_xsockets (&nsockets, &sockets, kc->tcp_flag);
+ if (tmp2 < 0)
+ errx(1, "Failed to open sockets");
+ display_num = tmp2;
+ if (kc->tcp_flag)
+ snprintf (display, display_size, "localhost:%u", display_num);
+ else
+ snprintf (display, display_size, ":%u", display_num);
+ error = create_and_write_cookie (xauthfile, xauthfile_size,
+ cookie, cookie_len);
+ if (error)
+ errx(1, "failed creating cookie file: %s", strerror(error));
+
+ status_output (kc->debug_flag);
+ for (;;) {
+ fd_set fdset;
+ pid_t child;
+ int fd, thisfd = -1;
+ socklen_t zero = 0;
+
+ FD_ZERO(&fdset);
+ for (i = 0; i < nsockets; ++i) {
+ if (sockets[i].fd >= FD_SETSIZE)
+ errx (1, "fd too large");
+ FD_SET(sockets[i].fd, &fdset);
+ }
+ if (select(FD_SETSIZE, &fdset, NULL, NULL, NULL) <= 0)
+ continue;
+ for (i = 0; i < nsockets; ++i)
+ if (FD_ISSET(sockets[i].fd, &fdset)) {
+ thisfd = sockets[i].fd;
+ break;
+ }
+ fd = accept (thisfd, NULL, &zero);
+ if (fd < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ err(1, "accept");
+ }
+
+ p = msg;
+ *p++ = NEW_CONN;
+ if (kx_write (kc, otherside, msg, p - msg) != p - msg)
+ err (1, "write to %s", host);
+ len = kx_read (kc, otherside, msg, sizeof(msg));
+ if (len < 0)
+ err (1, "read from %s", host);
+ p = (u_char *)msg;
+ if (*p == ERROR) {
+ uint32_t val;
+
+ p++;
+ p += kx_get_int (p, &val, 4, 0);
+ errx (1, "%s: %.*s", host, (int)val, p);
+ } else if (*p != NEW_CONN) {
+ errx (1, "%s: strange msg %d", host, *p);
+ } else {
+ p++;
+ p += kx_get_int (p, &other_port, 4, 0);
+ }
+
+ ++nchild;
+ child = fork ();
+ if (child < 0) {
+ warn("fork");
+ continue;
+ } else if (child == 0) {
+ int s;
+
+ for (i = 0; i < nsockets; ++i)
+ close (sockets[i].fd);
+
+ close (otherside);
+
+ socket_set_port(kc->thataddr, htons(tmp));
+
+ s = socket (kc->thataddr->sa_family, SOCK_STREAM, 0);
+ if (s < 0)
+ err(1, "socket");
+#if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT)
+ {
+ int one = 1;
+
+ setsockopt (s, IPPROTO_TCP, TCP_NODELAY, (void *)&one,
+ sizeof(one));
+ }
+#endif
+#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
+ if (kc->keepalive_flag) {
+ int one = 1;
+
+ setsockopt (s, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
+ sizeof(one));
+ }
+#endif
+
+ if (connect (s, kc->thataddr, kc->thataddr_len) < 0)
+ err(1, "connect");
+
+ return active_session (fd, s, kc);
+ } else {
+ close (fd);
+ }
+ }
+}
+
+/*
+ * Should we interpret `disp' as this being a passive call?
+ */
+
+static int
+check_for_passive (const char *disp)
+{
+ char local_hostname[MaxHostNameLen];
+
+ gethostname (local_hostname, sizeof(local_hostname));
+
+ return disp != NULL &&
+ (*disp == ':'
+ || strncmp(disp, "unix", 4) == 0
+ || strncmp(disp, "localhost", 9) == 0
+ || strncmp(disp, local_hostname, strlen(local_hostname)) == 0);
+}
+
+/*
+ * Set up signal handlers and then call the functions.
+ */
+
+static int
+doit (kx_context *kc, int passive_flag)
+{
+ signal (SIGCHLD, childhandler);
+ signal (SIGUSR1, usr1handler);
+ signal (SIGUSR2, usr2handler);
+ if (passive_flag)
+ return doit_passive (kc);
+ else
+ return doit_active (kc);
+}
+
+#ifdef KRB5
+
+/*
+ * Start a v5-authenticatated kx connection.
+ */
+
+static int
+doit_v5 (const char *host, int port, const char *user,
+ int passive_flag, int debug_flag, int keepalive_flag, int tcp_flag)
+{
+ int ret;
+ kx_context context;
+
+ krb5_make_context (&context);
+ context_set (&context,
+ host, user, port, debug_flag, keepalive_flag, tcp_flag);
+
+ ret = doit (&context, passive_flag);
+ context_destroy (&context);
+ return ret;
+}
+#endif /* KRB5 */
+
+/*
+ * Variables set from the arguments
+ */
+
+#ifdef KRB5
+static int use_v5 = -1;
+#endif
+static char *port_str = NULL;
+static const char *user = NULL;
+static int tcp_flag = 0;
+static int passive_flag = 0;
+static int keepalive_flag = 1;
+static int debug_flag = 0;
+static int version_flag = 0;
+static int help_flag = 0;
+
+struct getargs args[] = {
+#ifdef KRB5
+ { "krb5", '5', arg_flag, &use_v5, "Use Kerberos V5",
+ NULL },
+#endif
+ { "port", 'p', arg_string, &port_str, "Use this port",
+ "number-of-service" },
+ { "user", 'l', arg_string, &user, "Run as this user",
+ NULL },
+ { "tcp", 't', arg_flag, &tcp_flag,
+ "Use a TCP connection for X11" },
+ { "passive", 'P', arg_flag, &passive_flag,
+ "Force a passive connection" },
+ { "keepalive", 'k', arg_negative_flag, &keepalive_flag,
+ "disable keep-alives" },
+ { "debug", 'd', arg_flag, &debug_flag,
+ "Enable debug information" },
+ { "version", 0, arg_flag, &version_flag, "Print version",
+ NULL },
+ { "help", 0, arg_flag, &help_flag, NULL,
+ NULL }
+};
+
+static void
+usage(int ret)
+{
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "host");
+ exit (ret);
+}
+
+/*
+ * kx - forward an x-connection over a kerberos-encrypted channel.
+ */
+
+int
+main(int argc, char **argv)
+{
+ int port = 0;
+ int optidx = 0;
+ int ret = 1;
+ char *host = NULL;
+
+ setprogname (argv[0]);
+
+ if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optidx))
+ usage (1);
+
+ if (help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version (NULL);
+ return 0;
+ }
+
+ if (optidx != argc - 1)
+ usage (1);
+
+ host = argv[optidx];
+
+ 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 (user == NULL) {
+ user = get_default_username ();
+ if (user == NULL)
+ errx (1, "who are you?");
+ }
+
+ if (!passive_flag)
+ passive_flag = check_for_passive (getenv("DISPLAY"));
+
+#if defined(HAVE_KERNEL_ENABLE_DEBUG)
+ if (krb_debug_flag)
+ krb_enable_debug ();
+#endif
+
+#ifdef KRB5
+ if (ret && use_v5) {
+ if (port == 0)
+ port = krb5_getportbyname(NULL, "kx", "tcp", KX_PORT);
+ ret = doit_v5 (host, port, user,
+ passive_flag, debug_flag, keepalive_flag, tcp_flag);
+ }
+#endif
+ return ret;
+}
diff --git a/appl/kx/kx.cat1 b/appl/kx/kx.cat1
new file mode 100644
index 000000000000..7a03ee512daf
--- /dev/null
+++ b/appl/kx/kx.cat1
@@ -0,0 +1,39 @@
+
+KX(1) BSD General Commands Manual KX(1)
+
+NNAAMMEE
+ kkxx -- securely forward X conections
+
+SSYYNNOOPPSSIISS
+ _k_x [--ll _u_s_e_r_n_a_m_e] [--kk] [--dd] [--tt] [--pp _p_o_r_t] [--PP] _h_o_s_t
+
+DDEESSCCRRIIPPTTIIOONN
+ The kkxx program forwards an X connection from a remote client to a local
+ screen through an authenticated and encrypted stream. Options supported
+ by kkxx:
+
+ --ll Log in on the remote the host as user _u_s_e_r_n_a_m_e.
+
+ --kk Do not enable keep-alives on the TCP connections.
+
+ --dd Do not fork. This is mainly useful for debugging.
+
+ --tt Listen not only on a UNIX-domain socket but on a TCP socket as
+ well.
+
+ --pp Use the port _p_o_r_t.
+
+ --PP Force passive mode.
+
+ This program is used by rrxxtteellnneett and rrxxtteerrmm and you should not need to
+ run it directly.
+
+ It connects to a kkxxdd on the host _h_o_s_t and then will relay the traffic
+ from the remote X clients to the local server. When started, it prints
+ the display and Xauthority-file to be used on host _h_o_s_t and then goes to
+ the background, waiting for connections from the remote kkxxdd.
+
+SSEEEE AALLSSOO
+ rxtelnet(1), rxterm(1), kxd(8)
+
+KTH-KRB September 27, 1996 KTH-KRB
diff --git a/appl/kx/kx.h b/appl/kx/kx.h
new file mode 100644
index 000000000000..dbc5c08ee512
--- /dev/null
+++ b/appl/kx/kx.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 1995 - 2001 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$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.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_TCP_H
+#include <netinet/tcp.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xauth.h>
+
+#ifdef HAVE_SYS_STREAM_H
+#include <sys/stream.h>
+#endif
+#ifdef HAVE_SYS_STROPTS_H
+#include <sys/stropts.h>
+#endif
+
+/* defined by aix's sys/stream.h and again by arpa/nameser.h */
+
+#undef NOERROR
+
+/* as far as we know, this is only used with later versions of Slowlaris */
+#if SunOS >= 50 && defined(HAVE_SYS_STROPTS_H) && defined(HAVE_FATTACH) && defined(I_PUSH)
+#define MAY_HAVE_X11_PIPES
+#endif
+
+#ifdef SOCKS
+#include <socks.h>
+/* This doesn't belong here. */
+struct tm *localtime(const time_t *);
+struct hostent *gethostbyname(const char *);
+#endif
+
+#ifdef KRB5
+#include <krb5.h>
+#endif
+
+#include <err.h>
+#include <getarg.h>
+#include <roken.h>
+
+struct x_socket {
+ char *pathname;
+ int fd;
+ enum {
+ LISTENP = 0x80,
+ TCP = LISTENP | 1,
+ UNIX_SOCKET = LISTENP | 2,
+ STREAM_PIPE = 3
+ } flags;
+};
+
+extern char x_socket[];
+extern uint32_t display_num;
+extern char display[];
+extern int display_size;
+extern char xauthfile[];
+extern int xauthfile_size;
+extern u_char cookie[];
+extern size_t cookie_len;
+
+int get_xsockets (int *number, struct x_socket **sockets, int tcpp);
+int chown_xsockets (int n, struct x_socket *sockets, uid_t uid, gid_t gid);
+
+int connect_local_xsocket (unsigned dnr);
+int create_and_write_cookie (char *file,
+ size_t file_size,
+ u_char *cookie_buf,
+ size_t sz);
+int verify_and_remove_cookies (int fd, int sock, int cookiesp);
+int replace_cookie(int xserver, int fd, char *filename, int cookiesp);
+
+int suspicious_address (int sock, struct sockaddr *addr);
+
+#define KX_PORT 2111
+
+#define KX_OLD_VERSION "KXSERV.1"
+#define KX_VERSION "KXSERV.2"
+
+#define COOKIE_TYPE "MIT-MAGIC-COOKIE-1"
+
+enum { INIT = 0, ACK = 1, NEW_CONN = 2, ERROR = 3 };
+
+enum kx_flags { PASSIVE = 1, KEEP_ALIVE = 2 };
+
+typedef enum kx_flags kx_flags;
+
+struct kx_context {
+ int (*authenticate)(struct kx_context *kc, int s);
+ int (*userok)(struct kx_context *kc, char *user);
+ ssize_t (*read)(struct kx_context *kc,
+ int fd, void *buf, size_t len);
+ ssize_t (*write)(struct kx_context *kc,
+ int fd, const void *buf, size_t len);
+ int (*copy_encrypted)(struct kx_context *kc,
+ int fd1, int fd2);
+ void (*destroy)(struct kx_context *kc);
+ const char *host;
+ const char *user;
+ int port;
+ int debug_flag;
+ int keepalive_flag;
+ int tcp_flag;
+ struct sockaddr_storage __ss_this;
+ struct sockaddr_storage __ss_that;
+ struct sockaddr *thisaddr;
+ struct sockaddr *thataddr;
+ socklen_t thisaddr_len, thataddr_len;
+ void *data;
+};
+
+typedef struct kx_context kx_context;
+
+void
+context_set (kx_context *kc, const char *host, const char *user, int port,
+ int debug_flag, int keepalive_flag, int tcp_flag);
+
+void
+context_destroy (kx_context *kc);
+
+int
+context_authenticate (kx_context *kc, int s);
+
+int
+context_userok (kx_context *kc, char *user);
+
+ssize_t
+kx_read (kx_context *kc, int fd, void *buf, size_t len);
+
+ssize_t
+kx_write (kx_context *kc, int fd, const void *buf, size_t len);
+
+int
+copy_encrypted (kx_context *kc, int fd1, int fd2);
+
+#ifdef KRB5
+
+void
+krb5_make_context (kx_context *c);
+
+int
+recv_v5_auth (kx_context *kc, int sock, u_char *buf);
+
+#endif
+
+void
+fatal (kx_context *kc, int fd, char *format, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 3, 4)))
+#endif
+;
+
+int
+kx_get_int(void *f, uint32_t *to, int size, int lsb);
+
+int
+kx_put_int(uint32_t from, void *to, size_t rem, int size);
diff --git a/appl/kx/kxd.8 b/appl/kx/kxd.8
new file mode 100644
index 000000000000..4a0101ec2d47
--- /dev/null
+++ b/appl/kx/kxd.8
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1996 - 1997, 2001 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$
+.\"
+.Dd September 27, 1996
+.Dt KXD 8
+.Os KTH-KRB
+.Sh NAME
+.Nm kxd
+.Nd securely forward X conections
+.Sh SYNOPSIS
+.Ar kxd
+.Op Fl t
+.Op Fl i
+.Op Fl p Ar port
+.Sh DESCRIPTION
+This is the daemon for
+.Nm kx .
+.Pp
+Options supported by
+.Nm kxd :
+.Bl -tag -width Ds
+.It Fl t
+TCP. Normally
+.Nm kxd
+will only listen for X connections on a UNIX socket, but some machines
+(for example, Cray) have X libraries that are not able to use UNIX
+sockets and thus you need to use TCP to talk to the pseudo-xserver
+created by
+.Nm kxd .
+This option decreases the security significantly and should only be
+used when it is necessary and you have considered the consequences of
+doing so.
+.It Fl i
+Interactive. Do not expect to be started by
+.Nm inetd ,
+but allocate and listen to the socket yourself. Handy for testing
+and debugging.
+.It Fl p
+Port. Listen on the port
+.Ar port .
+Only usable with
+.Fl i .
+.El
+.Sh EXAMPLES
+Put the following in
+.Pa /etc/inetd.conf :
+.Bd -literal
+kx stream tcp nowait root /usr/athena/libexec/kxd kxd
+.Ed
+.Sh SEE ALSO
+.Xr kx 1 ,
+.Xr rxtelnet 1 ,
+.Xr rxterm 1
diff --git a/appl/kx/kxd.c b/appl/kx/kxd.c
new file mode 100644
index 000000000000..8598fb1672a6
--- /dev/null
+++ b/appl/kx/kxd.c
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 1995 - 2003 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 "kx.h"
+
+RCSID("$Id$");
+
+static pid_t wait_on_pid = -1;
+static int done = 0;
+
+/*
+ * Signal handler that justs waits for the children when they die.
+ */
+
+static RETSIGTYPE
+childhandler (int sig)
+{
+ pid_t pid;
+ int status;
+
+ do {
+ pid = waitpid (-1, &status, WNOHANG|WUNTRACED);
+ if (pid > 0 && pid == wait_on_pid)
+ done = 1;
+ } while(pid > 0);
+ signal (SIGCHLD, childhandler);
+ SIGRETURN(0);
+}
+
+/*
+ * Print the error message `format' and `...' on fd and die.
+ */
+
+void
+fatal (kx_context *kc, int fd, char *format, ...)
+{
+ u_char msg[1024];
+ u_char *p;
+ va_list args;
+ int len;
+
+ va_start(args, format);
+ p = msg;
+ *p++ = ERROR;
+ vsnprintf ((char *)p + 4, sizeof(msg) - 5, format, args);
+ syslog (LOG_ERR, "%s", (char *)p + 4);
+ len = strlen ((char *)p + 4);
+ p += kx_put_int (len, p, 4, 4);
+ p += len;
+ kx_write (kc, fd, msg, p - msg);
+ va_end(args);
+ exit (1);
+}
+
+/*
+ * Remove all sockets and cookie files.
+ */
+
+static void
+cleanup(int nsockets, struct x_socket *sockets)
+{
+ int i;
+
+ if(xauthfile[0])
+ unlink(xauthfile);
+ for (i = 0; i < nsockets; ++i) {
+ if (sockets[i].pathname != NULL) {
+ unlink (sockets[i].pathname);
+ free (sockets[i].pathname);
+ }
+ }
+ free(sockets);
+}
+
+/*
+ * Prepare to receive a connection on `sock'.
+ */
+
+static int
+recv_conn (int sock, kx_context *kc,
+ int *dispnr, int *nsockets, struct x_socket **sockets,
+ int tcp_flag)
+{
+ u_char msg[1024], *p;
+ char user[256];
+ socklen_t addrlen;
+ struct passwd *passwd;
+ char remotehost[MaxHostNameLen];
+ char remoteaddr[INET6_ADDRSTRLEN];
+ int ret = 1;
+ int flags;
+ int len;
+ uint32_t tmp32;
+
+ memset(kc, 0, sizeof(*kc));
+ *nsockets = 0;
+ *sockets = NULL;
+ *dispnr = 0;
+
+ addrlen = sizeof(kc->__ss_this);
+ kc->thisaddr = (struct sockaddr*)&kc->__ss_this;
+ if (getsockname (sock, kc->thisaddr, &addrlen) < 0) {
+ syslog (LOG_ERR, "getsockname: %m");
+ exit (1);
+ }
+ kc->thisaddr_len = addrlen;
+ addrlen = sizeof(kc->__ss_that);
+ kc->thataddr = (struct sockaddr*)&kc->__ss_that;
+ if (getpeername (sock, kc->thataddr, &addrlen) < 0) {
+ syslog (LOG_ERR, "getpeername: %m");
+ exit (1);
+ }
+ kc->thataddr_len = addrlen;
+
+ getnameinfo_verified (kc->thataddr,
+ kc->thataddr_len,
+ remotehost, sizeof(remotehost),
+ NULL, 0, 0);
+
+ if (net_read (sock, msg, 4) != 4) {
+ syslog (LOG_ERR, "read: %m");
+ exit (1);
+ }
+
+#ifdef KRB5
+ if (ret && recv_v5_auth (kc, sock, msg) == 0)
+ ret = 0;
+#endif
+ if (ret) {
+ syslog (LOG_ERR, "unrecognized auth protocol: %x %x %x %x",
+ msg[0], msg[1], msg[2], msg[3]);
+ exit (1);
+ }
+
+ len = kx_read (kc, sock, msg, sizeof(msg));
+ if (len < 0) {
+ syslog (LOG_ERR, "kx_read failed");
+ exit (1);
+ }
+ p = (u_char *)msg;
+ if (*p != INIT)
+ fatal(kc, sock, "Bad message");
+ p++;
+ if ((p - msg) < sizeof(msg))
+ fatal(kc, sock, "user");
+
+ p += kx_get_int (p, &tmp32, 4, 0);
+ if (tmp32 >= sizeof(user) - 1)
+ fatal(kc, sock, "user name too long");
+ if ((p - msg) + tmp32 >= sizeof(msg))
+ fatal(kc, sock, "user too long");
+ memcpy (user, p, tmp32);
+ p += tmp32;
+ user[tmp32] = '\0';
+
+ passwd = k_getpwnam (user);
+ if (passwd == NULL)
+ fatal (kc, sock, "cannot find uid for %s", user);
+
+ if (context_userok (kc, user) != 0)
+ fatal (kc, sock, "%s not allowed to login as %s",
+ kc->user, user);
+
+ if ((p - msg) >= sizeof(msg))
+ fatal(kc, sock, "user too long");
+
+ flags = *p++;
+
+ if (flags & PASSIVE) {
+ pid_t pid;
+ int tmp;
+
+ tmp = get_xsockets (nsockets, sockets, tcp_flag);
+ if (tmp < 0) {
+ fatal (kc, sock, "Cannot create X socket(s): %s",
+ strerror(errno));
+ }
+ *dispnr = tmp;
+
+ if (chown_xsockets (*nsockets, *sockets,
+ passwd->pw_uid, passwd->pw_gid)) {
+ cleanup (*nsockets, *sockets);
+ fatal (kc, sock, "Cannot chown sockets: %s",
+ strerror(errno));
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ cleanup (*nsockets, *sockets);
+ fatal (kc, sock, "fork: %s", strerror(errno));
+ } else if (pid != 0) {
+ wait_on_pid = pid;
+ while (!done)
+ pause ();
+ cleanup (*nsockets, *sockets);
+ exit (0);
+ }
+ }
+
+ if (setgid (passwd->pw_gid) ||
+ initgroups(passwd->pw_name, passwd->pw_gid) ||
+#ifdef HAVE_GETUDBNAM /* XXX this happens on crays */
+ setjob(passwd->pw_uid, 0) == -1 ||
+#endif
+ setuid(passwd->pw_uid)) {
+ syslog(LOG_ERR, "setting uid/groups: %m");
+ fatal (kc, sock, "cannot set uid");
+ }
+
+ ret = getnameinfo(kc->thataddr, kc->thataddr_len,
+ remoteaddr, sizeof(remoteaddr),
+ NULL, 0, NI_NUMERICHOST);
+ if (ret != 0)
+ fatal (kc, sock, "getnameinfo failed: %s", gai_strerror(ret));
+
+ syslog (LOG_INFO, "from %s(%s): %s -> %s",
+ remotehost, remoteaddr,
+ kc->user, user);
+ umask(077);
+ if (!(flags & PASSIVE)) {
+ p += kx_get_int (p, &tmp32, 4, 0);
+ if (tmp32 > display_size)
+ fatal(kc, sock, "display too large");
+ if ((p - msg) + tmp32 + 8 >= sizeof(msg))
+ fatal(kc, sock, "user too long");
+ memcpy (display, p, tmp32);
+ display[tmp32] = '\0';
+ p += tmp32;
+ p += kx_get_int (p, &tmp32, 4, 0);
+ len = min(tmp32, xauthfile_size);
+ memcpy (xauthfile, p, len);
+ xauthfile[len] = '\0';
+ }
+#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
+ if (flags & KEEP_ALIVE) {
+ int one = 1;
+
+ setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
+ sizeof(one));
+ }
+#endif
+ return flags;
+}
+
+/*
+ *
+ */
+
+static int
+passive_session (kx_context *kc, int fd, int sock, int cookiesp)
+{
+ if (verify_and_remove_cookies (fd, sock, cookiesp))
+ return 1;
+ else
+ return copy_encrypted (kc, fd, sock);
+}
+
+/*
+ *
+ */
+
+static int
+active_session (kx_context *kc, int fd, int sock, int cookiesp)
+{
+ fd = connect_local_xsocket(0);
+
+ if (replace_cookie (fd, sock, xauthfile, cookiesp))
+ return 1;
+ else
+ return copy_encrypted (kc, fd, sock);
+}
+
+/*
+ * Handle a new connection.
+ */
+
+static int
+doit_conn (kx_context *kc,
+ int fd, int meta_sock, int flags, int cookiesp)
+{
+ int sock, sock2, port;
+ struct sockaddr_storage __ss_addr;
+ struct sockaddr *addr = (struct sockaddr*)&__ss_addr;
+ struct sockaddr_storage __ss_thisaddr;
+ struct sockaddr *thisaddr = (struct sockaddr*)&__ss_thisaddr;
+ socklen_t addrlen;
+ u_char msg[1024], *p;
+
+ sock = socket (kc->thisaddr->sa_family, SOCK_STREAM, 0);
+ if (sock < 0) {
+ syslog (LOG_ERR, "socket: %m");
+ return 1;
+ }
+#if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT)
+ {
+ int one = 1;
+ setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (void *)&one, sizeof(one));
+ }
+#endif
+#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
+ if (flags & KEEP_ALIVE) {
+ int one = 1;
+
+ setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
+ sizeof(one));
+ }
+#endif
+ memset (&__ss_addr, 0, sizeof(__ss_addr));
+ addr->sa_family = kc->thisaddr->sa_family;
+ if (kc->thisaddr_len > sizeof(__ss_addr)) {
+ syslog(LOG_ERR, "error in af");
+ return 1;
+ }
+ if (bind (sock, addr, kc->thisaddr_len) < 0) {
+ syslog (LOG_ERR, "bind: %m");
+ return 1;
+ }
+ addrlen = sizeof(__ss_addr);
+ if (getsockname (sock, addr, &addrlen) < 0) {
+ syslog (LOG_ERR, "getsockname: %m");
+ return 1;
+ }
+ if (listen (sock, SOMAXCONN) < 0) {
+ syslog (LOG_ERR, "listen: %m");
+ return 1;
+ }
+ port = socket_get_port(addr);
+
+ p = msg;
+ *p++ = NEW_CONN;
+ p += kx_put_int (ntohs(port), p, 4, 4);
+
+ if (kx_write (kc, meta_sock, msg, p - msg) < 0) {
+ syslog (LOG_ERR, "write: %m");
+ return 1;
+ }
+
+ addrlen = sizeof(__ss_thisaddr);
+ sock2 = accept (sock, thisaddr, &addrlen);
+ if (sock2 < 0) {
+ syslog (LOG_ERR, "accept: %m");
+ return 1;
+ }
+ close (sock);
+ close (meta_sock);
+
+ if (flags & PASSIVE)
+ return passive_session (kc, fd, sock2, cookiesp);
+ else
+ return active_session (kc, fd, sock2, cookiesp);
+}
+
+/*
+ * Is the current user the owner of the console?
+ */
+
+static void
+check_user_console (kx_context *kc, int fd)
+{
+ struct stat sb;
+
+ if (stat ("/dev/console", &sb) < 0)
+ fatal (kc, fd, "Cannot stat /dev/console: %s", strerror(errno));
+ if (getuid() != sb.st_uid)
+ fatal (kc, fd, "Permission denied");
+}
+
+/* close down the new connection with a reasonable error message */
+static void
+close_connection(int fd, const char *message)
+{
+ char buf[264]; /* max message */
+ char *p;
+ int lsb = 0;
+ size_t mlen;
+
+ mlen = strlen(message);
+ if(mlen > 255)
+ mlen = 255;
+
+ /* read first part of connection packet, to get byte order */
+ if(read(fd, buf, 6) != 6) {
+ close(fd);
+ return;
+ }
+ if(buf[0] == 0x6c)
+ lsb++;
+ p = buf;
+ *p++ = 0; /* failed */
+ *p++ = mlen; /* length of message */
+ p += 4; /* skip protocol version */
+ p += 2; /* skip additional length */
+ memcpy(p, message, mlen); /* copy message */
+ p += mlen;
+ while((p - buf) % 4) /* pad to multiple of 4 bytes */
+ *p++ = 0;
+
+ /* now fill in length of additional data */
+ if(lsb) {
+ buf[6] = (p - buf - 8) / 4;
+ buf[7] = 0;
+ }else{
+ buf[6] = 0;
+ buf[7] = (p - buf - 8) / 4;
+ }
+ write(fd, buf, p - buf);
+ close(fd);
+}
+
+
+/*
+ * Handle a passive session on `sock'
+ */
+
+static int
+doit_passive (kx_context *kc,
+ int sock,
+ int flags,
+ int dispnr,
+ int nsockets,
+ struct x_socket *sockets,
+ int tcp_flag)
+{
+ int tmp;
+ int len;
+ size_t rem;
+ u_char msg[1024], *p;
+ int error;
+
+ display_num = dispnr;
+ if (tcp_flag)
+ snprintf (display, display_size, "localhost:%u", display_num);
+ else
+ snprintf (display, display_size, ":%u", display_num);
+ error = create_and_write_cookie (xauthfile, xauthfile_size,
+ cookie, cookie_len);
+ if (error) {
+ cleanup(nsockets, sockets);
+ fatal (kc, sock, "Cookie-creation failed: %s", strerror(error));
+ return 1;
+ }
+
+ p = msg;
+ rem = sizeof(msg);
+ *p++ = ACK;
+ --rem;
+
+ len = strlen (display);
+ tmp = kx_put_int (len, p, rem, 4);
+ if (tmp < 0 || rem < len + 4) {
+ syslog (LOG_ERR, "doit: buffer too small");
+ cleanup(nsockets, sockets);
+ return 1;
+ }
+ p += tmp;
+ rem -= tmp;
+
+ memcpy (p, display, len);
+ p += len;
+ rem -= len;
+
+ len = strlen (xauthfile);
+ tmp = kx_put_int (len, p, rem, 4);
+ if (tmp < 0 || rem < len + 4) {
+ syslog (LOG_ERR, "doit: buffer too small");
+ cleanup(nsockets, sockets);
+ return 1;
+ }
+ p += tmp;
+ rem -= tmp;
+
+ memcpy (p, xauthfile, len);
+ p += len;
+ rem -= len;
+
+ if(kx_write (kc, sock, msg, p - msg) < 0) {
+ syslog (LOG_ERR, "write: %m");
+ cleanup(nsockets, sockets);
+ return 1;
+ }
+ for (;;) {
+ pid_t child;
+ int fd = -1;
+ fd_set fds;
+ int i;
+ int ret;
+ int cookiesp = TRUE;
+
+ FD_ZERO(&fds);
+ if (sock >= FD_SETSIZE) {
+ syslog (LOG_ERR, "fd too large");
+ cleanup(nsockets, sockets);
+ return 1;
+ }
+
+ FD_SET(sock, &fds);
+ for (i = 0; i < nsockets; ++i) {
+ if (sockets[i].fd >= FD_SETSIZE) {
+ syslog (LOG_ERR, "fd too large");
+ cleanup(nsockets, sockets);
+ return 1;
+ }
+ FD_SET(sockets[i].fd, &fds);
+ }
+ ret = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
+ if(ret <= 0)
+ continue;
+ if(FD_ISSET(sock, &fds)){
+ /* there are no processes left on the remote side
+ */
+ cleanup(nsockets, sockets);
+ exit(0);
+ } else if(ret) {
+ for (i = 0; i < nsockets; ++i) {
+ if (FD_ISSET(sockets[i].fd, &fds)) {
+ if (sockets[i].flags == TCP) {
+ struct sockaddr_storage __ss_peer;
+ struct sockaddr *peer = (struct sockaddr*)&__ss_peer;
+ socklen_t slen = sizeof(__ss_peer);
+
+ fd = accept (sockets[i].fd,
+ peer,
+ &slen);
+ if (fd < 0 && errno != EINTR)
+ syslog (LOG_ERR, "accept: %m");
+
+ /* XXX */
+ if (fd >= 0 && suspicious_address (fd, peer)) {
+ close (fd);
+ fd = -1;
+ errno = EINTR;
+ }
+ } else if(sockets[i].flags == UNIX_SOCKET) {
+ socklen_t zero = 0;
+
+ fd = accept (sockets[i].fd, NULL, &zero);
+
+ if (fd < 0 && errno != EINTR)
+ syslog (LOG_ERR, "accept: %m");
+#ifdef MAY_HAVE_X11_PIPES
+ } else if(sockets[i].flags == STREAM_PIPE) {
+ /*
+ * this code tries to handle the
+ * send fd-over-pipe stuff for
+ * solaris
+ */
+
+ struct strrecvfd strrecvfd;
+
+ ret = ioctl (sockets[i].fd,
+ I_RECVFD, &strrecvfd);
+ if (ret < 0 && errno != EINTR) {
+ syslog (LOG_ERR, "ioctl I_RECVFD: %m");
+ }
+
+ /* XXX */
+ if (ret == 0) {
+ if (strrecvfd.uid != getuid()) {
+ close (strrecvfd.fd);
+ fd = -1;
+ errno = EINTR;
+ } else {
+ fd = strrecvfd.fd;
+ cookiesp = FALSE;
+ }
+ }
+#endif /* MAY_HAVE_X11_PIPES */
+ } else
+ abort ();
+ break;
+ }
+ }
+ }
+ if (fd < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return 1;
+ }
+
+ child = fork ();
+ if (child < 0) {
+ syslog (LOG_ERR, "fork: %m");
+ if(errno != EAGAIN)
+ return 1;
+ close_connection(fd, strerror(errno));
+ } else if (child == 0) {
+ for (i = 0; i < nsockets; ++i)
+ close (sockets[i].fd);
+ return doit_conn (kc, fd, sock, flags, cookiesp);
+ } else {
+ close (fd);
+ }
+ }
+}
+
+/*
+ * Handle an active session on `sock'
+ */
+
+static int
+doit_active (kx_context *kc,
+ int sock,
+ int flags,
+ int tcp_flag)
+{
+ u_char msg[1024], *p;
+
+ check_user_console (kc, sock);
+
+ p = msg;
+ *p++ = ACK;
+
+ if(kx_write (kc, sock, msg, p - msg) < 0) {
+ syslog (LOG_ERR, "write: %m");
+ return 1;
+ }
+ for (;;) {
+ pid_t child;
+ int len;
+
+ len = kx_read (kc, sock, msg, sizeof(msg));
+ if (len < 0) {
+ syslog (LOG_ERR, "read: %m");
+ return 1;
+ }
+ p = (u_char *)msg;
+ if (*p != NEW_CONN) {
+ syslog (LOG_ERR, "bad_message: %d", *p);
+ return 1;
+ }
+
+ child = fork ();
+ if (child < 0) {
+ syslog (LOG_ERR, "fork: %m");
+ if (errno != EAGAIN)
+ return 1;
+ } else if (child == 0) {
+ return doit_conn (kc, sock, sock, flags, 1);
+ } else {
+ }
+ }
+}
+
+/*
+ * Receive a connection on `sock' and process it.
+ */
+
+static int
+doit(int sock, int tcp_flag)
+{
+ int ret;
+ kx_context context;
+ int dispnr;
+ int nsockets;
+ struct x_socket *sockets;
+ int flags;
+
+ flags = recv_conn (sock, &context, &dispnr, &nsockets, &sockets, tcp_flag);
+
+ if (flags & PASSIVE) {
+ ret = doit_passive (&context, sock, flags, dispnr,
+ nsockets, sockets, tcp_flag);
+ } else {
+ ret = doit_active (&context, sock, flags, tcp_flag);
+ cleanup(nsockets, sockets);
+ }
+ context_destroy (&context);
+ return ret;
+}
+
+static char *port_str = NULL;
+static int inetd_flag = 1;
+static int tcp_flag = 0;
+static int version_flag = 0;
+static int help_flag = 0;
+
+struct getargs args[] = {
+ { "inetd", 'i', arg_negative_flag, &inetd_flag,
+ "Not started from inetd" },
+ { "tcp", 't', arg_flag, &tcp_flag, "Use TCP" },
+ { "port", 'p', arg_string, &port_str, "Use this port",
+ "port" },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage(int ret)
+{
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "host");
+ exit (ret);
+}
+
+/*
+ * kxd - receive a forwarded X conncection
+ */
+
+int
+main (int argc, char **argv)
+{
+ int port;
+ int optidx = 0;
+
+ setprogname (argv[0]);
+ roken_openlog ("kxd", LOG_ODELAY | LOG_PID, LOG_DAEMON);
+
+ if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optidx))
+ usage (1);
+
+ if (help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version (NULL);
+ return 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);
+ }
+ } else {
+#if defined(KRB5)
+ port = krb5_getportbyname(NULL, "kx", "tcp", KX_PORT);
+#else
+#error define KRB5
+#endif
+ }
+
+ if (!inetd_flag)
+ mini_inetd (port, NULL);
+
+ signal (SIGCHLD, childhandler);
+ return doit(STDIN_FILENO, tcp_flag);
+}
diff --git a/appl/kx/kxd.cat8 b/appl/kx/kxd.cat8
new file mode 100644
index 000000000000..41567cd5beb3
--- /dev/null
+++ b/appl/kx/kxd.cat8
@@ -0,0 +1,37 @@
+
+KXD(8) BSD System Manager's Manual KXD(8)
+
+NNAAMMEE
+ kkxxdd -- securely forward X conections
+
+SSYYNNOOPPSSIISS
+ _k_x_d [--tt] [--ii] [--pp _p_o_r_t]
+
+DDEESSCCRRIIPPTTIIOONN
+ This is the daemon for kkxx.
+
+ Options supported by kkxxdd:
+
+ --tt TCP. Normally kkxxdd will only listen for X connections on a UNIX
+ socket, but some machines (for example, Cray) have X libraries
+ that are not able to use UNIX sockets and thus you need to use
+ TCP to talk to the pseudo-xserver created by kkxxdd. This option
+ decreases the security significantly and should only be used when
+ it is necessary and you have considered the consequences of doing
+ so.
+
+ --ii Interactive. Do not expect to be started by iinneettdd, but allocate
+ and listen to the socket yourself. Handy for testing and debug-
+ ging.
+
+ --pp Port. Listen on the port _p_o_r_t. Only usable with --ii.
+
+EEXXAAMMPPLLEESS
+ Put the following in _/_e_t_c_/_i_n_e_t_d_._c_o_n_f:
+
+ kx stream tcp nowait root /usr/athena/libexec/kxd kxd
+
+SSEEEE AALLSSOO
+ kx(1), rxtelnet(1), rxterm(1)
+
+KTH-KRB September 27, 1996 KTH-KRB
diff --git a/appl/kx/rxtelnet.1 b/appl/kx/rxtelnet.1
new file mode 100644
index 000000000000..8cdb5ae8022d
--- /dev/null
+++ b/appl/kx/rxtelnet.1
@@ -0,0 +1,128 @@
+.\" Copyright (c) 1996 - 1998, 2001 - 2002 Kungliga Tekniska Högskolan
+.\" (Royal Institute of Technology, Stockholm, Sweden).
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" 3. Neither the name of the Institute nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd March 7, 2004
+.Dt RXTELNET 1
+.Os KTH_KRB
+.Sh NAME
+.Nm rxtelnet
+.Nd start a telnet and forward X-connections.
+.Sh SYNOPSIS
+.Nm rxtelnet
+.Op Fl l Ar username
+.Op Fl k
+.Op Fl t Ar telnet_args
+.Op Fl x Ar xterm_args
+.Op Fl K Ar kx_args
+.Op Fl w Ar term_emulator
+.Op Fl b Ar telnet_program
+.Op Fl n
+.Op Fl v
+.Ar host
+.Op Ar port
+.Sh DESCRIPTION
+The
+.Nm
+program starts an
+.Nm xterm
+window with a telnet to host
+.Ar host .
+From this window you will also be able to run X clients that will be
+able to connect securely to your X server. If
+.Ar port
+is given, that port will be used instead of the default.
+.Pp
+If setting up the X forwarding failes,
+.Nm
+will still telnet in to the remote host, but without X forwarding.
+.Pp
+The supported options are:
+.Bl -tag -width Ds
+.It Fl l
+Log in on the remote host as user
+.Ar username .
+.It Fl k
+Disables keep-alives.
+.It Fl t
+Send
+.Ar telnet_args
+as arguments to
+.Nm telnet .
+.It Fl x
+Send
+.Ar xterm_args
+as arguments to
+.Nm xterm .
+.It Fl X
+Send
+.Ar kx_args
+as arguments to
+.Nm kx .
+.It Fl w
+Use
+.Ar term_emulator
+instead of xterm.
+.It Fl b
+Use
+.Ar telnet_program
+instead of telnet.
+.It Fl n
+Do not start any terminal emulator.
+.It Fl v
+Be verbose.
+.El
+.Sh EXAMPLE
+To login from host
+.Va foo
+(where your display is)
+to host
+.Va bar ,
+you might do the following.
+.Bl -enum
+.It
+On foo:
+.Nm
+.Va bar
+.It
+You will get a new window with a
+.Nm telnet
+to
+.Va bar .
+In this window you will be able to start X clients.
+.El
+.Sh SEE ALSO
+.Xr kx 1 ,
+.Xr rxterm 1 ,
+.Xr telnet 1 ,
+.Xr tenletxr 1 ,
+.Xr kxd 8
diff --git a/appl/kx/rxtelnet.cat1 b/appl/kx/rxtelnet.cat1
new file mode 100644
index 000000000000..f11e2b7140d8
--- /dev/null
+++ b/appl/kx/rxtelnet.cat1
@@ -0,0 +1,52 @@
+
+RXTELNET(1) BSD General Commands Manual RXTELNET(1)
+
+NNAAMMEE
+ rrxxtteellnneett -- start a telnet and forward X-connections.
+
+SSYYNNOOPPSSIISS
+ rrxxtteellnneett [--ll _u_s_e_r_n_a_m_e] [--kk] [--tt _t_e_l_n_e_t___a_r_g_s] [--xx _x_t_e_r_m___a_r_g_s] [--KK _k_x___a_r_g_s]
+ [--ww _t_e_r_m___e_m_u_l_a_t_o_r] [--bb _t_e_l_n_e_t___p_r_o_g_r_a_m] [--nn] [--vv] _h_o_s_t [_p_o_r_t]
+
+DDEESSCCRRIIPPTTIIOONN
+ The rrxxtteellnneett program starts an xxtteerrmm window with a telnet to host _h_o_s_t.
+ From this window you will also be able to run X clients that will be able
+ to connect securely to your X server. If _p_o_r_t is given, that port will be
+ used instead of the default.
+
+ If setting up the X forwarding failes, rrxxtteellnneett will still telnet in to
+ the remote host, but without X forwarding.
+
+ The supported options are:
+
+ --ll Log in on the remote host as user _u_s_e_r_n_a_m_e.
+
+ --kk Disables keep-alives.
+
+ --tt Send _t_e_l_n_e_t___a_r_g_s as arguments to tteellnneett.
+
+ --xx Send _x_t_e_r_m___a_r_g_s as arguments to xxtteerrmm.
+
+ --XX Send _k_x___a_r_g_s as arguments to kkxx.
+
+ --ww Use _t_e_r_m___e_m_u_l_a_t_o_r instead of xterm.
+
+ --bb Use _t_e_l_n_e_t___p_r_o_g_r_a_m instead of telnet.
+
+ --nn Do not start any terminal emulator.
+
+ --vv Be verbose.
+
+EEXXAAMMPPLLEE
+ To login from host _f_o_o (where your display is) to host _b_a_r, you might do
+ the following.
+
+ 1. On foo: rrxxtteellnneett _b_a_r
+
+ 2. You will get a new window with a tteellnneett to _b_a_r. In this window you
+ will be able to start X clients.
+
+SSEEEE AALLSSOO
+ kx(1), rxterm(1), telnet(1), tenletxr(1), kxd(8)
+
+KTH_KRB March 7, 2004 KTH_KRB
diff --git a/appl/kx/rxtelnet.in b/appl/kx/rxtelnet.in
new file mode 100644
index 000000000000..d5cf010f2f65
--- /dev/null
+++ b/appl/kx/rxtelnet.in
@@ -0,0 +1,72 @@
+#!/bin/sh
+# $Id$
+#
+usage="Usage: $0 [-l username] [-k] [-fF] [-t args_to_telnet] [-x args_to_xterm] [-K args_to_kx] [-w term_emulator] [-b telnet_binary] [-n] [-v] [-h | --help] [--version] host [port]"
+binary=telnet
+term=
+kx_args=-P
+while true
+do
+ case $1 in
+ -l) telnet_args="${telnet_args} -l $2 "; kx_args="${kx_args} -l $2"; title="${2}@"; shift 2;;
+ -t) telnet_args="${telnet_args} $2 "; shift 2;;
+ -x) xterm_args="${xterm_args} $2 "; shift 2;;
+ -f) telnet_args="${telnet_args} -f"; shift;;
+ -F) telnet_args="${telnet_args} -F"; shift;;
+ -k) kx_args="${kx_args} -k"; shift;;
+ -K) kx_args="${kx_args} $2 "; shift 2;;
+ -n) term=none; shift;;
+ -w) term=$2; shift 2;;
+ -b) binary=$2; shift 2;;
+ --version) echo "$0: %PACKAGE% %VERSION%"; exit 0;;
+ -h) echo $usage; exit 0;;
+ --help) echo $usage; exit 0;;
+ -v) set -x; verb=1; shift;;
+ -*) echo "$0: Bad option $1"; echo $usage; exit 1;;
+ *) break;;
+ esac
+done
+if test $# -lt 1; then
+ echo $usage
+ exit 1
+fi
+host=$1
+port=$2
+title="${title}${host}"
+bindir=%bindir%
+pdc_trams=`dirname $0`
+PATH=$pdc_trams:$bindir:$PATH
+export PATH
+set -- `kx $kx_args $host`
+if test $# -ne 3; then
+ echo "Warning: Cound not setup X forwarding"
+ pid=NO
+ disp=""
+ auth=""
+else
+ screen=`echo $DISPLAY | sed -ne 's/[^:]*:[0-9]*\(\.[0-9]*\)/\1/p'`
+ pid=$1
+ disp=${2}${screen}
+ auth=$3
+fi
+oldifs=$IFS
+IFS=:
+set -- $PATH
+IFS=$oldifs
+if test -z "$term"; then
+ for j in xterm dtterm aixterm dxterm hpterm; do
+ for i in $*; do
+ test -n "$i" || i="."
+ if test -x $i/$j; then
+ term=$j; break 2
+ fi
+ done
+ done
+fi
+test "$verb" && echo "Telnet command used is `type $binary`."
+if test -n "$term" -a "$term" != "none"; then
+ ($term -title $title -n $title $xterm_args -e env DISPLAY=$disp XAUTHORITY=$auth $binary -D $telnet_args $host $port; test x"$pid" != xNO && kill -USR2 $pid) &
+else
+ env DISPLAY=$disp XAUTHORITY=$auth $binary -D $telnet_args $host $port
+ test x"$pid" != xNO && kill -USR2 $pid
+fi
diff --git a/appl/kx/rxterm.1 b/appl/kx/rxterm.1
new file mode 100644
index 000000000000..a7e848c6e6c1
--- /dev/null
+++ b/appl/kx/rxterm.1
@@ -0,0 +1,120 @@
+.\" Copyright (c) 1996 - 1997, 2001 - 2003 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$
+.\"
+.Dd April 11, 2003
+.Dt RXTERM 1
+.Os KTH_KRB
+.Sh NAME
+.Nm rxterm
+.Nd start a secure remote xterm
+.Sh SYNOPSIS
+.Nm rxterm
+.Op Fl l Ar username
+.Op Fl k
+.Op Fl r Ar rsh_args
+.Op Fl x Ar xterm_args
+.Op Fl K Ar kx_args
+.Op Fl w Ar term_emulator
+.Op Fl b Ar rsh_program
+.Ar host
+.Op Ar port
+.Sh DESCRIPTION
+The
+.Nm
+program starts an
+.Nm xterm
+window on host
+.Ar host .
+From this window you will also be able to run X clients that will be
+able to connect securely to your X server. If
+.Ar port
+is given, that port will be used instead of the default.
+.Pp
+The supported options are:
+.Bl -tag -width Ds
+.It Fl l
+Log in on the remote host as user
+.Ar username .
+.It Fl k
+Disable keep-alives.
+.It Fl r
+Send
+.Ar rsh_args
+as arguments to
+.Nm rsh .
+.It Fl x
+Send
+.Ar xterm_args
+as arguments to
+.Nm xterm .
+.It Fl X
+Send
+.Ar kx_args
+as arguments to
+.Nm kx .
+.It Fl w
+Use
+.Ar term_emulator
+instead of xterm.
+.It Fl b
+Use
+.Ar rsh_program
+instead of rsh.
+.It Fl v
+Be verbose.
+.El
+.Sh EXAMPLE
+To login from host
+.Va foo
+(where your display is)
+to host
+.Va bar ,
+you might do the following.
+.Bl -enum
+.It
+On foo:
+.Nm
+.Va bar
+.It
+You will get a new window running an
+.Nm xterm
+on host
+.Va bar .
+In this window you will be able to start X clients.
+.El
+.Sh SEE ALSO
+.Xr kx 1 ,
+.Xr rsh 1 ,
+.Xr rxtelnet 1 ,
+.Xr tenletxr 1 ,
+.Xr kxd 8
diff --git a/appl/kx/rxterm.cat1 b/appl/kx/rxterm.cat1
new file mode 100644
index 000000000000..4d6ca6f0096c
--- /dev/null
+++ b/appl/kx/rxterm.cat1
@@ -0,0 +1,47 @@
+
+RXTERM(1) BSD General Commands Manual RXTERM(1)
+
+NNAAMMEE
+ rrxxtteerrmm -- start a secure remote xterm
+
+SSYYNNOOPPSSIISS
+ rrxxtteerrmm [--ll _u_s_e_r_n_a_m_e] [--kk] [--rr _r_s_h___a_r_g_s] [--xx _x_t_e_r_m___a_r_g_s] [--KK _k_x___a_r_g_s]
+ [--ww _t_e_r_m___e_m_u_l_a_t_o_r] [--bb _r_s_h___p_r_o_g_r_a_m] _h_o_s_t [_p_o_r_t]
+
+DDEESSCCRRIIPPTTIIOONN
+ The rrxxtteerrmm program starts an xxtteerrmm window on host _h_o_s_t. From this window
+ you will also be able to run X clients that will be able to connect
+ securely to your X server. If _p_o_r_t is given, that port will be used
+ instead of the default.
+
+ The supported options are:
+
+ --ll Log in on the remote host as user _u_s_e_r_n_a_m_e.
+
+ --kk Disable keep-alives.
+
+ --rr Send _r_s_h___a_r_g_s as arguments to rrsshh.
+
+ --xx Send _x_t_e_r_m___a_r_g_s as arguments to xxtteerrmm.
+
+ --XX Send _k_x___a_r_g_s as arguments to kkxx.
+
+ --ww Use _t_e_r_m___e_m_u_l_a_t_o_r instead of xterm.
+
+ --bb Use _r_s_h___p_r_o_g_r_a_m instead of rsh.
+
+ --vv Be verbose.
+
+EEXXAAMMPPLLEE
+ To login from host _f_o_o (where your display is) to host _b_a_r, you might do
+ the following.
+
+ 1. On foo: rrxxtteerrmm _b_a_r
+
+ 2. You will get a new window running an xxtteerrmm on host _b_a_r. In this
+ window you will be able to start X clients.
+
+SSEEEE AALLSSOO
+ kx(1), rsh(1), rxtelnet(1), tenletxr(1), kxd(8)
+
+KTH_KRB April 11, 2003 KTH_KRB
diff --git a/appl/kx/rxterm.in b/appl/kx/rxterm.in
new file mode 100644
index 000000000000..d0a409031bbd
--- /dev/null
+++ b/appl/kx/rxterm.in
@@ -0,0 +1,45 @@
+#!/bin/sh
+# $Id$
+#
+usage="Usage: $0 [-l username] [-k] [-f] [-r rsh_args] [-x xterm_args] [-K kx_args] [-w term_emulator] [-b rsh_binary][-v] [-h | --help] [--version] host"
+binary=rsh
+term=xterm
+while true
+do
+ case $1 in
+ -l) rsh_args="${rsh_args} -l $2 "; kx_args="${kx_args} -l $2"; title="${2}@"; shift 2;;
+ -r) rsh_args="${rsh_args} $2 "; shift 2;;
+ -x) xterm_args="${xterm_args} $2 "; shift 2;;
+ -f) rsh_args="${rsh_args} -f"; shift;;
+ -k) kx_args="${kx_args} -k"; shift;;
+ -K) kx_args="${kx_args} $2 "; shift 2;;
+ -w) term=$2; shift 2;;
+ -b) binary=$2; shift 2;;
+ --version) echo "$0: %PACKAGE% %VERSION%"; exit 0;;
+ -h) echo $usage; exit 0;;
+ --help) echo $usage; exit 0;;
+ -v) set -x; shift;;
+ -*) echo "$0: Bad option $1"; echo $usage; exit 1;;
+ *) break;;
+ esac
+done
+if test $# -lt 1; then
+ echo "Usage: $0 host [arguments to $term]"
+ exit 1
+fi
+host=$1
+title="${title}${host}"
+bindir=%bindir%
+pdc_trams=`dirname $0`
+PATH=$pdc_trams:$bindir:$PATH
+export PATH
+set -- `kx $kx_args $host`
+if test $# -ne 3; then
+ exit 1
+fi
+screen=`echo $DISPLAY | sed -ne 's/[^:]*:[0-9]*\(\.[0-9]*\)/\1/p'`
+pid=$1
+disp=${2}${screen}
+auth=$3
+kill -USR1 $pid
+$binary -n $rsh_args $host "/bin/sh -c 'DISPLAY=$disp XAUTHORITY=$auth $term -T $title -n $title $xterm_args </dev/null >/dev/null 2>/dev/null &'"
diff --git a/appl/kx/tenletxr.1 b/appl/kx/tenletxr.1
new file mode 100644
index 000000000000..e030d1534cd4
--- /dev/null
+++ b/appl/kx/tenletxr.1
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1997, 2001 - 2002 Kungliga Tekniska Högskolan
+.\" (Royal Institute of Technology, Stockholm, Sweden).
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" 3. Neither the name of the Institute nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd March 31, 1997
+.Dt TENLETXR 1
+.Os KTH_KRB
+.Sh NAME
+.Nm tenletxr
+.Nd forward X-connections backwards.
+.Sh SYNOPSIS
+.Nm tenletxr
+.Op Fl l Ar username
+.Op Fl k
+.Ar host
+.Op Ar port
+.Sh DESCRIPTION
+The
+.Nm
+program
+enables forwarding of X-connections from this machine to host
+.Ar host .
+If
+.Ar port
+is given, that port will be used instead of the default.
+.Pp
+The supported options are:
+.Bl -tag -width Ds
+.It Fl l
+Log in on the remote host as user
+.Ar username
+.It Fl k
+Disables keep-alives.
+.El
+.Sh EXAMPLE
+To login from host
+.Va foo
+to host
+.Va bar
+(where your display is),
+you might do the following.
+.Bl -enum
+.It
+On foo:
+.Nm
+.Va bar
+.It
+You will get a new shell where you will be able to start X clients
+that will show their windows on
+.Va bar .
+.El
+.Sh BUGS
+It currently checks if you have permission to run it by checking if
+you own
+.Pa /dev/console
+on the remote host.
+.Sh SEE ALSO
+.Xr kx 1 ,
+.Xr rxtelnet 1 ,
+.Xr rxterm 1 ,
+.Xr telnet 1 ,
+.Xr kxd 8
diff --git a/appl/kx/tenletxr.cat1 b/appl/kx/tenletxr.cat1
new file mode 100644
index 000000000000..da659754bc36
--- /dev/null
+++ b/appl/kx/tenletxr.cat1
@@ -0,0 +1,37 @@
+
+TENLETXR(1) BSD General Commands Manual TENLETXR(1)
+
+NNAAMMEE
+ tteennlleettxxrr -- forward X-connections backwards.
+
+SSYYNNOOPPSSIISS
+ tteennlleettxxrr [--ll _u_s_e_r_n_a_m_e] [--kk] _h_o_s_t [_p_o_r_t]
+
+DDEESSCCRRIIPPTTIIOONN
+ The tteennlleettxxrr program enables forwarding of X-connections from this
+ machine to host _h_o_s_t. If _p_o_r_t is given, that port will be used instead
+ of the default.
+
+ The supported options are:
+
+ --ll Log in on the remote host as user _u_s_e_r_n_a_m_e
+
+ --kk Disables keep-alives.
+
+EEXXAAMMPPLLEE
+ To login from host _f_o_o to host _b_a_r (where your display is), you might do
+ the following.
+
+ 1. On foo: tteennlleettxxrr _b_a_r
+
+ 2. You will get a new shell where you will be able to start X clients
+ that will show their windows on _b_a_r.
+
+BBUUGGSS
+ It currently checks if you have permission to run it by checking if you
+ own _/_d_e_v_/_c_o_n_s_o_l_e on the remote host.
+
+SSEEEE AALLSSOO
+ kx(1), rxtelnet(1), rxterm(1), telnet(1), kxd(8)
+
+KTH_KRB March 31, 1997 KTH_KRB
diff --git a/appl/kx/tenletxr.in b/appl/kx/tenletxr.in
new file mode 100644
index 000000000000..e0b57ae8c32b
--- /dev/null
+++ b/appl/kx/tenletxr.in
@@ -0,0 +1,37 @@
+#!/bin/sh
+# $Id$
+#
+usage="Usage: $0 [-l username] [-k] [-v] [-h | --help] [--version] host [port]"
+while true
+do
+ case $1 in
+ -l) kx_args="${kx_args} -l $2"; shift 2;;
+ -k) kx_args="${kx_args} -k"; shift;;
+ --version) echo "$0: %PACKAGE% %VERSION%"; exit 0;;
+ -h) echo $usage; exit 0;;
+ --help) echo $usage; exit 0;;
+ -v) set -x; shift;;
+ -*) echo "$0: Bad option $1"; echo $usage; exit 1;;
+ *) break;;
+ esac
+done
+if test $# -lt 1; then
+ echo $usage
+ exit 1
+fi
+host=$1
+port=$2
+bindir=%bindir%
+pdc_trams=`dirname $0`
+PATH=$pdc_trams:$bindir:$PATH
+export PATH
+set -- `kx $kx_args $host`
+if test $# -ne 3; then
+ exit 1
+fi
+screen=`echo $DISPLAY | sed -ne 's/[^:]*:[0-9]*\(\.[0-9]*\)/\1/p'`
+pid=$1
+disp=${2}${screen}
+auth=$3
+env DISPLAY=$disp XAUTHORITY=$auth $SHELL
+kill -USR2 $pid
diff --git a/appl/kx/writeauth.c b/appl/kx/writeauth.c
new file mode 100644
index 000000000000..d142278c914d
--- /dev/null
+++ b/appl/kx/writeauth.c
@@ -0,0 +1,73 @@
+/* $XConsortium: AuWrite.c,v 1.6 94/04/17 20:15:45 gildea Exp $ */
+
+/*
+
+Copyright (c) 1988 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id$");
+#endif
+
+#include <X11/Xauth.h>
+
+static int
+write_short (unsigned short s, FILE *file)
+{
+ unsigned char file_short[2];
+
+ file_short[0] = (s & (unsigned)0xff00) >> 8;
+ file_short[1] = s & 0xff;
+ if (fwrite (file_short, sizeof (file_short), 1, file) != 1)
+ return 0;
+ return 1;
+}
+
+static int
+write_counted_string (unsigned short count, char *string, FILE *file)
+{
+ if (write_short (count, file) == 0)
+ return 0;
+ if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
+ return 0;
+ return 1;
+}
+
+int
+XauWriteAuth (FILE *auth_file, Xauth *auth)
+{
+ if (write_short (auth->family, auth_file) == 0)
+ return 0;
+ if (write_counted_string (auth->address_length, auth->address, auth_file) == 0)
+ return 0;
+ if (write_counted_string (auth->number_length, auth->number, auth_file) == 0)
+ return 0;
+ if (write_counted_string (auth->name_length, auth->name, auth_file) == 0)
+ return 0;
+ if (write_counted_string (auth->data_length, auth->data, auth_file) == 0)
+ return 0;
+ return 1;
+}