summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/rsh
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/appl/rsh')
-rw-r--r--crypto/heimdal/appl/rsh/ChangeLog237
-rw-r--r--crypto/heimdal/appl/rsh/Makefile.am19
-rw-r--r--crypto/heimdal/appl/rsh/Makefile.in698
-rw-r--r--crypto/heimdal/appl/rsh/common.c124
-rw-r--r--crypto/heimdal/appl/rsh/rsh.c948
-rw-r--r--crypto/heimdal/appl/rsh/rsh_locl.h139
-rw-r--r--crypto/heimdal/appl/rsh/rshd.c850
7 files changed, 3015 insertions, 0 deletions
diff --git a/crypto/heimdal/appl/rsh/ChangeLog b/crypto/heimdal/appl/rsh/ChangeLog
new file mode 100644
index 0000000..c07d8d0
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/ChangeLog
@@ -0,0 +1,237 @@
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (doit): addrinfo returned from getaddrinfo() is not usable
+ directly as hints. copy it and set AI_PASSIVE.
+
+1999-11-20 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (main): remember to close the priviledged sockets before
+ calling rlogin
+
+1999-11-02 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (main): redo the v4/v5 selection for consistency. -4 ->
+ try only v4 -5 -> try only v5 none, -45 -> try v5, v4
+
+1999-10-26 Assar Westerlund <assar@sics.se>
+
+ * rshd.c (main): ignore SIGPIPE
+
+ * common.c (do_read): the encoded length can be longer than the
+ buffer being used, allocate memory for it dynamically. From Brian
+ A May <bmay@dgs.monash.edu.au>
+
+1999-10-14 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (proto): be more careful and don't print errno when read()
+ returns 0
+
+1999-09-20 Assar Westerlund <assar@sics.se>
+
+ * rshd.c (recv_krb4_auth): set `iv'
+
+1999-08-16 Assar Westerlund <assar@sics.se>
+
+ * common.c (do_read): be careful with the return value from
+ krb5_net_read
+
+1999-08-05 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: call freehostent
+
+ * rsh.c: remove some dead code
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * rshd.c: re-write the handling of forwarded credentials and
+ stuff. From Miroslav Ruda <ruda@ics.muni.cz>
+
+ * rsh_locl.h: always include kafs.h
+
+ * rsh.c: add `-z' and `-G' options
+
+ * rsh.c (loop): shutdown one side of the TCP connection on EOF.
+ From Brian A May <bmay@dgs.monash.edu.au>
+
+ * common.c (do_read): handle EOF. From Brian A May
+ <bmay@dgs.monash.edu.au>
+
+1999-08-01 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: const fixes
+
+1999-07-29 Assar Westerlund <assar@sics.se>
+
+ * rshd.c: v6-ify
+
+ * rsh.c: v6-ify
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * rsh_locl.h: move around kafs.h
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * rsh_locl.h: <shadow.h>
+
+ * rsh.c, rshd.c: improve forwarding and implement unique ccache on
+ server. From Miroslav Ruda <ruda@ics.muni.cz>
+
+1999-07-03 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (construct_command): handle argc == 0 for generality
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: new option `-e' for not trying to open an stderr socket
+
+1999-06-17 Assar Westerlund <assar@sics.se>
+
+ * rsh_locl.h (RSH_BUFSIZ): bump to 16 * 1024 to be sure that we
+ don't leave any data inside des_enc_read. (that constant should
+ really be exported in some way...)
+
+1999-06-15 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: use get_default_username and resulting const pollution
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (main): try $USERNAME
+
+1999-05-14 Assar Westerlund <assar@sics.se>
+
+ * rshd.c (doit): afslog correctly
+
+1999-05-11 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (main): add fallback to rlogin
+
+1999-05-10 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (send_krb5_auth): call krb5_sendauth with ccache == NULL.
+ check return value from krb5_crypto_init
+
+ * common.c (do_write, do_read): always return -1 for failure
+ (net_write, net_read): remove. they already exist in libroken
+
+1999-05-09 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: make sure it tries with all other authentication methods
+ after one has failed
+ * rsh.c (main): detect the case of no command given.
+
+1999-04-11 Assar Westerlund <assar@sics.se>
+
+ * rsh.c: new option --forwardable. use print_version
+
+Sat Apr 10 17:10:55 1999 Assar Westerlund <assar@sics.se>
+
+ * rshd.c (setup_copier): use `socketpair' instead of `pipe'. Some
+ shells don't think it's a rsh session if they find a pipe at the
+ other end.
+ (setup_environment): add SSH_CLIENT just to make bash happy
+
+ * common.c (do_read): use krb5_get_wrapped_length
+
+Wed Mar 24 03:59:42 1999 Assar Westerlund <assar@sics.se>
+
+ * rsh.c (loop): more braces to make gcc happy
+
+Tue Mar 23 17:08:32 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * rsh_locl.h: kafs.h
+
+ * rshd.c: add `-P', `-v', and `-L' flags
+
+Thu Mar 18 11:37:24 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: include Makefile.am.common
+
+Tue Dec 1 14:44:44 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * appl/rsh/rshd.c: update to new crypto framework
+
+ * appl/rsh/rsh_locl.h: update to new crypto framework
+
+ * appl/rsh/rsh.c: update to new crypto framework
+
+ * appl/rsh/common.c: update to new crypto framework
+
+Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rsh.c (main): initialize host
+
+ * appl/rsh/rshd.c (recv_krb5_auth): disable `do_encrypt' if not
+ encrypting.
+
+Thu Jul 30 23:12:17 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rsh.c: kludges for parsing `rsh hostname -l user'
+
+Thu Jul 23 19:49:03 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * appl/rsh/rshd.c: use krb5_verify_authenticator_checksum
+
+Sat Apr 18 21:13:06 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * appl/rsh/rsh.c: Don't try v5 if (only) `-4' is specified.
+
+Sun Dec 21 09:44:05 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c (recv_krb5_auth): swap the order of the
+ `local_user' and the `remote_user'
+
+ * appl/rsh/rsh.c (send_krb5_auth): swap the order of the
+ `local_user' and the `remote_user'
+
+Sat Nov 29 07:10:11 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c: updated to use getarg.
+ changed `struct fd_set' to `fd_set'.
+ implemented broken/BSD authentication (requires iruserok)
+
+Wed Nov 12 02:35:57 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rsh_locl.h: add AUTH_BROKEN and PATH_RSH
+
+ * appl/rsh/Makefile.am: set BINDIR
+
+ * appl/rsh/rsh.c: implemented BSD-style reserved port
+ `authentication'
+
+Sun Aug 24 08:06:54 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c: syslog remote shells
+
+Tue Aug 12 01:29:46 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rshd/rshd.c: Use `krb5_sock_to_principal'. Send server
+ parameter to krb5_rd_req/krb5_recvauth. Set addresses in
+ auth_context.
+
+Fri Jul 25 17:32:12 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c: implement forwarding
+
+ * appl/rsh/rsh.c: Use getarg. Implement forwarding.
+
+Sun Jul 13 00:32:16 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh: Conditionalize the krb4-support.
+
+Wed Jul 9 06:58:00 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rsh.c: use the correct user for the checksum
+
+Mon Jul 7 11:15:51 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh/rshd.c: Now works. Also implementd encryption and
+ `-p'.
+
+ * appl/rsh/common.c: new file
+
+Mon Jun 30 06:08:14 1997 Assar Westerlund <assar@sics.se>
+
+ * appl/rsh: New program.
+
diff --git a/crypto/heimdal/appl/rsh/Makefile.am b/crypto/heimdal/appl/rsh/Makefile.am
new file mode 100644
index 0000000..0875f9f
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/Makefile.am
@@ -0,0 +1,19 @@
+# $Id: Makefile.am,v 1.13 1999/04/09 18:24:05 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_krb4)
+
+bin_PROGRAMS = rsh
+
+libexec_PROGRAMS = rshd
+
+rsh_SOURCES = rsh.c common.c rsh_locl.h
+
+rshd_SOURCES = rshd.c common.c rsh_locl.h
+
+LDADD = $(LIB_kafs) \
+ $(LIB_krb5) \
+ $(LIB_krb4) \
+ $(top_builddir)/lib/des/libdes.la \
+ $(LIB_roken)
diff --git a/crypto/heimdal/appl/rsh/Makefile.in b/crypto/heimdal/appl/rsh/Makefile.in
new file mode 100644
index 0000000..1800c7b
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/Makefile.in
@@ -0,0 +1,698 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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.
+
+# $Id: Makefile.am,v 1.13 1999/04/09 18:24:05 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+bin_PROGRAMS = rsh
+
+libexec_PROGRAMS = rshd
+
+rsh_SOURCES = rsh.c common.c rsh_locl.h
+
+rshd_SOURCES = rshd.c common.c rsh_locl.h
+
+LDADD = $(LIB_kafs) $(LIB_krb5) $(LIB_krb4) $(top_builddir)/lib/des/libdes.la $(LIB_roken)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../include/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = rsh$(EXEEXT)
+libexec_PROGRAMS = rshd$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+rsh_OBJECTS = rsh.$(OBJEXT) common.$(OBJEXT)
+rsh_LDADD = $(LDADD)
+@KRB4_TRUE@@KRB5_FALSE@rsh_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_TRUE@rsh_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_FALSE@rsh_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_TRUE@@KRB5_TRUE@rsh_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+rsh_LDFLAGS =
+rshd_OBJECTS = rshd.$(OBJEXT) common.$(OBJEXT)
+rshd_LDADD = $(LDADD)
+@KRB4_TRUE@@KRB5_FALSE@rshd_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_TRUE@rshd_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_FALSE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+@KRB4_FALSE@@KRB5_FALSE@rshd_DEPENDENCIES = \
+@KRB4_FALSE@@KRB5_FALSE@$(top_builddir)/lib/des/libdes.la
+@KRB4_TRUE@@KRB5_TRUE@rshd_DEPENDENCIES = \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/kafs/libkafs.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/asn1/libasn1.la \
+@KRB4_TRUE@@KRB5_TRUE@$(top_builddir)/lib/des/libdes.la
+rshd_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(rsh_SOURCES) $(rshd_SOURCES)
+OBJECTS = $(rsh_OBJECTS) $(rshd_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign appl/rsh/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+rsh$(EXEEXT): $(rsh_OBJECTS) $(rsh_DEPENDENCIES)
+ @rm -f rsh$(EXEEXT)
+ $(LINK) $(rsh_LDFLAGS) $(rsh_OBJECTS) $(rsh_LDADD) $(LIBS)
+
+rshd$(EXEEXT): $(rshd_OBJECTS) $(rshd_DEPENDENCIES)
+ @rm -f rshd$(EXEEXT)
+ $(LINK) $(rshd_LDFLAGS) $(rshd_OBJECTS) $(rshd_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = appl/rsh
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS install-libexecPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(libexecdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-libexecPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-libexecPROGRAMS clean-compile \
+ clean-libtool clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-libexecPROGRAMS \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-local install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+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 \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(include_HEADERS) $(build_HEADERZ)'; \
+ for f in $$foo; do \
+ f=`basename $$f`; \
+ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
+ else file="$$f"; fi; \
+ if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
+ : ; else \
+ echo " cp $$file $(buildinclude)/$$f"; \
+ cp $$file $(buildinclude)/$$f; \
+ fi ; \
+ done
+
+all-local: install-build-headers
+#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-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /dev/null 2>&1; then \
+ echo "PASS: $$i"; \
+ else \
+ echo "FAIL: $$i"; \
+ failed=`expr $$failed + 1`; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ fi
+
+# 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/crypto/heimdal/appl/rsh/common.c b/crypto/heimdal/appl/rsh/common.c
new file mode 100644
index 0000000..6614137
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/common.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "rsh_locl.h"
+RCSID("$Id: common.c,v 1.12 1999/12/02 17:04:56 joda Exp $");
+
+ssize_t
+do_read (int fd,
+ void *buf,
+ size_t sz)
+{
+ int ret;
+
+ if (do_encrypt) {
+#ifdef KRB4
+ if (auth_method == AUTH_KRB4) {
+ return des_enc_read (fd, buf, sz, schedule, &iv);
+ } else
+#endif /* KRB4 */
+ if(auth_method == AUTH_KRB5) {
+ u_int32_t len, outer_len;
+ int status;
+ krb5_data data;
+ void *edata;
+
+ ret = krb5_net_read (context, &fd, &len, 4);
+ if (ret <= 0)
+ return ret;
+ len = ntohl(len);
+ if (len > sz)
+ abort ();
+ outer_len = krb5_get_wrapped_length (context, crypto, len);
+ edata = malloc (outer_len);
+ if (edata == NULL)
+ errx (1, "malloc: cannot allocate %u bytes", outer_len);
+ ret = krb5_net_read (context, &fd, edata, outer_len);
+ if (ret <= 0)
+ return ret;
+
+ status = krb5_decrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
+ edata, outer_len, &data);
+ free (edata);
+
+ if (status)
+ errx (1, "%s", krb5_get_err_text (context, status));
+ memcpy (buf, data.data, len);
+ krb5_data_free (&data);
+ return len;
+ } else {
+ abort ();
+ }
+ } else
+ return read (fd, buf, sz);
+}
+
+ssize_t
+do_write (int fd, void *buf, size_t sz)
+{
+ if (do_encrypt) {
+#ifdef KRB4
+ if(auth_method == AUTH_KRB4) {
+ return des_enc_write (fd, buf, sz, schedule, &iv);
+ } else
+#endif /* KRB4 */
+ if(auth_method == AUTH_KRB5) {
+ krb5_error_code status;
+ krb5_data data;
+ u_int32_t len;
+ int ret;
+
+ status = krb5_encrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
+ buf, sz, &data);
+
+ if (status)
+ errx (1, "%s", krb5_get_err_text(context, status));
+
+ assert (krb5_get_wrapped_length (context, crypto,
+ sz) == data.length);
+
+ len = htonl(sz);
+ ret = krb5_net_write (context, &fd, &len, 4);
+ if (ret != 4)
+ return ret;
+ ret = krb5_net_write (context, &fd, data.data, data.length);
+ if (ret != data.length)
+ return ret;
+ free (data.data);
+ return sz;
+ } else {
+ abort();
+ }
+ } else
+ return write (fd, buf, sz);
+}
diff --git a/crypto/heimdal/appl/rsh/rsh.c b/crypto/heimdal/appl/rsh/rsh.c
new file mode 100644
index 0000000..444748e
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/rsh.c
@@ -0,0 +1,948 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "rsh_locl.h"
+RCSID("$Id: rsh.c,v 1.46 1999/12/16 11:53:50 assar Exp $");
+
+enum auth_method auth_method;
+int do_encrypt;
+int do_forward;
+int do_forwardable;
+int do_unique_tkfile = 0;
+char *unique_tkfile = NULL;
+char tkfile[MAXPATHLEN];
+krb5_context context;
+krb5_keyblock *keyblock;
+krb5_crypto crypto;
+des_key_schedule schedule;
+des_cblock iv;
+
+
+/*
+ *
+ */
+
+static int input = 1; /* Read from stdin */
+
+static int
+loop (int s, int errsock)
+{
+ fd_set real_readset;
+ int count = 1;
+
+ FD_ZERO(&real_readset);
+ FD_SET(s, &real_readset);
+ if (errsock != -1) {
+ FD_SET(errsock, &real_readset);
+ ++count;
+ }
+ if(input)
+ FD_SET(STDIN_FILENO, &real_readset);
+
+ for (;;) {
+ int ret;
+ fd_set readset;
+ char buf[RSH_BUFSIZ];
+
+ readset = real_readset;
+ ret = select (max(s, errsock) + 1, &readset, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ err (1, "select");
+ }
+ if (FD_ISSET(s, &readset)) {
+ ret = do_read (s, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read");
+ else if (ret == 0) {
+ close (s);
+ FD_CLR(s, &real_readset);
+ if (--count == 0)
+ return 0;
+ } else
+ net_write (STDOUT_FILENO, buf, ret);
+ }
+ if (errsock != -1 && FD_ISSET(errsock, &readset)) {
+ ret = do_read (errsock, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read");
+ else if (ret == 0) {
+ close (errsock);
+ FD_CLR(errsock, &real_readset);
+ if (--count == 0)
+ return 0;
+ } else
+ net_write (STDERR_FILENO, buf, ret);
+ }
+ if (FD_ISSET(STDIN_FILENO, &readset)) {
+ ret = read (STDIN_FILENO, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read");
+ else if (ret == 0) {
+ close (STDIN_FILENO);
+ FD_CLR(STDIN_FILENO, &real_readset);
+ shutdown (s, SHUT_WR);
+ } else
+ do_write (s, buf, ret);
+ }
+ }
+}
+
+#ifdef KRB4
+static int
+send_krb4_auth(int s,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ const char *hostname,
+ const char *remote_user,
+ const char *local_user,
+ size_t cmd_len,
+ const char *cmd)
+{
+ KTEXT_ST text;
+ CREDENTIALS cred;
+ MSG_DAT msg;
+ int status;
+ size_t len;
+
+ status = krb_sendauth (do_encrypt ? KOPT_DO_MUTUAL : 0,
+ s, &text, "rcmd",
+ (char *)hostname, krb_realmofhost (hostname),
+ getpid(), &msg, &cred, schedule,
+ (struct sockaddr_in *)thisaddr,
+ (struct sockaddr_in *)thataddr,
+ KCMD_VERSION);
+ if (status != KSUCCESS) {
+ warnx ("%s: %s", hostname, krb_get_err_text(status));
+ return 1;
+ }
+ memcpy (iv, cred.session, sizeof(iv));
+
+ len = strlen(remote_user) + 1;
+ if (net_write (s, remote_user, len) != len) {
+ warn("write");
+ return 1;
+ }
+ if (net_write (s, cmd, cmd_len) != cmd_len) {
+ warn("write");
+ return 1;
+ }
+ return 0;
+}
+#endif /* KRB4 */
+
+/*
+ * Send forward information on `s' for host `hostname', them being
+ * forwardable themselves if `forwardable'
+ */
+
+static int
+krb5_forward_cred (krb5_auth_context auth_context,
+ int s,
+ const char *hostname,
+ int forwardable)
+{
+ krb5_error_code ret;
+ krb5_ccache ccache;
+ krb5_creds creds;
+ krb5_kdc_flags flags;
+ krb5_data out_data;
+ krb5_principal principal;
+
+ memset (&creds, 0, sizeof(creds));
+
+ ret = krb5_cc_default (context, &ccache);
+ if (ret) {
+ warnx ("could not forward creds: krb5_cc_default: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ ret = krb5_cc_get_principal (context, ccache, &principal);
+ if (ret) {
+ warnx ("could not forward creds: krb5_cc_get_principal: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ creds.client = principal;
+
+ ret = krb5_build_principal (context,
+ &creds.server,
+ strlen(principal->realm),
+ principal->realm,
+ "krbtgt",
+ principal->realm,
+ NULL);
+
+ if (ret) {
+ warnx ("could not forward creds: krb5_build_principal: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ creds.times.endtime = 0;
+
+ flags.i = 0;
+ flags.b.forwarded = 1;
+ flags.b.forwardable = forwardable;
+
+ ret = krb5_get_forwarded_creds (context,
+ auth_context,
+ ccache,
+ flags.i,
+ hostname,
+ &creds,
+ &out_data);
+ if (ret) {
+ warnx ("could not forward creds: krb5_get_forwarded_creds: %s",
+ krb5_get_err_text (context, ret));
+ return 1;
+ }
+
+ ret = krb5_write_message (context,
+ (void *)&s,
+ &out_data);
+ krb5_data_free (&out_data);
+
+ if (ret)
+ warnx ("could not forward creds: krb5_write_message: %s",
+ krb5_get_err_text (context, ret));
+ return 0;
+}
+
+static int
+send_krb5_auth(int s,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ const char *hostname,
+ const char *remote_user,
+ const char *local_user,
+ size_t cmd_len,
+ const char *cmd)
+{
+ krb5_principal server;
+ krb5_data cksum_data;
+ int status;
+ size_t len;
+ krb5_auth_context auth_context = NULL;
+
+ status = krb5_sname_to_principal(context,
+ hostname,
+ "host",
+ KRB5_NT_SRV_HST,
+ &server);
+ if (status) {
+ warnx ("%s: %s", hostname, krb5_get_err_text(context, status));
+ return 1;
+ }
+
+ cksum_data.length = asprintf ((char **)&cksum_data.data,
+ "%u:%s%s%s",
+ ntohs(socket_get_port(thataddr)),
+ do_encrypt ? "-x " : "",
+ cmd,
+ remote_user);
+
+ status = krb5_sendauth (context,
+ &auth_context,
+ &s,
+ KCMD_VERSION,
+ NULL,
+ server,
+ do_encrypt ? AP_OPTS_MUTUAL_REQUIRED : 0,
+ &cksum_data,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (status) {
+ warnx ("%s: %s", hostname, krb5_get_err_text(context, status));
+ return 1;
+ }
+
+ status = krb5_auth_con_getkey (context, auth_context, &keyblock);
+ if (status) {
+ warnx ("krb5_auth_con_getkey: %s", krb5_get_err_text(context, status));
+ return 1;
+ }
+
+ status = krb5_auth_con_setaddrs_from_fd (context,
+ auth_context,
+ &s);
+ if (status) {
+ warnx("krb5_auth_con_setaddrs_from_fd: %s",
+ krb5_get_err_text(context, status));
+ return(1);
+ }
+
+ status = krb5_crypto_init(context, keyblock, 0, &crypto);
+ if(status) {
+ warnx ("krb5_crypto_init: %s", krb5_get_err_text(context, status));
+ return 1;
+ }
+
+ len = strlen(remote_user) + 1;
+ if (net_write (s, remote_user, len) != len) {
+ warn ("write");
+ return 1;
+ }
+ if (do_encrypt && net_write (s, "-x ", 3) != 3) {
+ warn ("write");
+ return 1;
+ }
+ if (net_write (s, cmd, cmd_len) != cmd_len) {
+ warn ("write");
+ return 1;
+ }
+
+ if (do_unique_tkfile) {
+ if (net_write (s, tkfile, strlen(tkfile)) != strlen(tkfile)) {
+ warn ("write");
+ return 1;
+ }
+ }
+ len = strlen(local_user) + 1;
+ if (net_write (s, local_user, len) != len) {
+ warn ("write");
+ return 1;
+ }
+
+ if (!do_forward
+ || krb5_forward_cred (auth_context, s, hostname, do_forwardable)) {
+ /* Empty forwarding info */
+
+ u_char zero[4] = {0, 0, 0, 0};
+ write (s, &zero, 4);
+ }
+ krb5_auth_con_free (context, auth_context);
+ return 0;
+}
+
+static int
+send_broken_auth(int s,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ const char *hostname,
+ const char *remote_user,
+ const char *local_user,
+ size_t cmd_len,
+ const char *cmd)
+{
+ size_t len;
+
+ len = strlen(local_user) + 1;
+ if (net_write (s, local_user, len) != len) {
+ warn ("write");
+ return 1;
+ }
+ len = strlen(remote_user) + 1;
+ if (net_write (s, remote_user, len) != len) {
+ warn ("write");
+ return 1;
+ }
+ if (net_write (s, cmd, cmd_len) != cmd_len) {
+ warn ("write");
+ return 1;
+ }
+ return 0;
+}
+
+static int
+proto (int s, int errsock,
+ const char *hostname, const char *local_user, const char *remote_user,
+ const char *cmd, size_t cmd_len,
+ int (*auth_func)(int s,
+ struct sockaddr *this, struct sockaddr *that,
+ const char *hostname, const char *remote_user,
+ const char *local_user, size_t cmd_len,
+ const char *cmd))
+{
+ int errsock2;
+ char buf[BUFSIZ];
+ char *p;
+ size_t len;
+ char reply;
+ struct sockaddr_storage thisaddr_ss;
+ struct sockaddr *thisaddr = (struct sockaddr *)&thisaddr_ss;
+ struct sockaddr_storage thataddr_ss;
+ struct sockaddr *thataddr = (struct sockaddr *)&thataddr_ss;
+ struct sockaddr_storage erraddr_ss;
+ struct sockaddr *erraddr = (struct sockaddr *)&erraddr_ss;
+ int addrlen;
+ int ret;
+
+ addrlen = sizeof(thisaddr_ss);
+ if (getsockname (s, thisaddr, &addrlen) < 0) {
+ warn ("getsockname(%s)", hostname);
+ return 1;
+ }
+ addrlen = sizeof(thataddr_ss);
+ if (getpeername (s, thataddr, &addrlen) < 0) {
+ warn ("getpeername(%s)", hostname);
+ return 1;
+ }
+
+ if (errsock != -1) {
+
+ addrlen = sizeof(erraddr_ss);
+ if (getsockname (errsock, erraddr, &addrlen) < 0) {
+ warn ("getsockname");
+ return 1;
+ }
+
+ if (listen (errsock, 1) < 0) {
+ warn ("listen");
+ return 1;
+ }
+
+ p = buf;
+ snprintf (p, sizeof(buf), "%u",
+ ntohs(socket_get_port(erraddr)));
+ len = strlen(buf) + 1;
+ if(net_write (s, buf, len) != len) {
+ warn ("write");
+ close (errsock);
+ return 1;
+ }
+
+ errsock2 = accept (errsock, NULL, NULL);
+ if (errsock2 < 0) {
+ warn ("accept");
+ close (errsock);
+ return 1;
+ }
+ close (errsock);
+
+ } else {
+ if (net_write (s, "0", 2) != 2) {
+ warn ("write");
+ return 1;
+ }
+ errsock2 = -1;
+ }
+
+ if ((*auth_func)(s, thisaddr, thataddr, hostname,
+ remote_user, local_user,
+ cmd_len, cmd)) {
+ close (errsock2);
+ return 1;
+ }
+
+ ret = net_read (s, &reply, 1);
+ if (ret < 0) {
+ warn ("read");
+ close (errsock2);
+ return 1;
+ } else if (ret == 0) {
+ warnx ("unexpected EOF from %s", hostname);
+ close (errsock2);
+ return 1;
+ }
+ if (reply != 0) {
+
+ warnx ("Error from rshd at %s:", hostname);
+
+ while ((ret = read (s, buf, sizeof(buf))) > 0)
+ write (STDOUT_FILENO, buf, ret);
+ write (STDOUT_FILENO,"\n",1);
+ close (errsock2);
+ return 1;
+ }
+
+ return loop (s, errsock2);
+}
+
+/*
+ * Return in `res' a copy of the concatenation of `argc, argv' into
+ * malloced space.
+ */
+
+static size_t
+construct_command (char **res, int argc, char **argv)
+{
+ int i;
+ size_t len = 0;
+ char *tmp;
+
+ for (i = 0; i < argc; ++i)
+ len += strlen(argv[i]) + 1;
+ len = max (1, len);
+ tmp = malloc (len);
+ if (tmp == NULL)
+ errx (1, "malloc %u failed", len);
+
+ *tmp = '\0';
+ for (i = 0; i < argc - 1; ++i) {
+ strcat (tmp, argv[i]);
+ strcat (tmp, " ");
+ }
+ if (argc > 0)
+ strcat (tmp, argv[argc-1]);
+ *res = tmp;
+ return len;
+}
+
+static char *
+print_addr (const struct sockaddr_in *sin)
+{
+ char addr_str[256];
+ char *res;
+
+ inet_ntop (AF_INET, &sin->sin_addr, addr_str, sizeof(addr_str));
+ res = strdup(addr_str);
+ if (res == NULL)
+ errx (1, "malloc: out of memory");
+ return res;
+}
+
+static int
+doit_broken (int argc,
+ char **argv,
+ int optind,
+ const char *host,
+ const char *remote_user,
+ const char *local_user,
+ int port,
+ int priv_socket1,
+ int priv_socket2,
+ const char *cmd,
+ size_t cmd_len)
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+
+ if (priv_socket1 < 0) {
+ warnx ("unable to bind reserved port: is rsh setuid root?");
+ return 1;
+ }
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_family = AF_INET;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ error = getaddrinfo (host, portstr, &hints, &ai);
+ if (error) {
+ warnx ("%s: %s", host, gai_strerror(error));
+ return 1;
+ }
+
+ if (connect (priv_socket1, ai->ai_addr, ai->ai_addrlen) < 0) {
+ if (ai->ai_next == NULL) {
+ freeaddrinfo (ai);
+ return 1;
+ }
+
+ close(priv_socket1);
+ close(priv_socket2);
+
+ for (a = ai->ai_next; a != NULL; a = a->ai_next) {
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0)
+ err (1, "fork");
+ else if(pid == 0) {
+ char **new_argv;
+ int i = 0;
+ struct sockaddr_in *sin = (struct sockaddr_in *)a->ai_addr;
+
+ new_argv = malloc((argc + 2) * sizeof(*new_argv));
+ if (new_argv == NULL)
+ errx (1, "malloc: out of memory");
+ new_argv[i] = argv[i];
+ ++i;
+ if (optind == i)
+ new_argv[i++] = print_addr (sin);
+ new_argv[i++] = "-K";
+ for(; i <= argc; ++i)
+ new_argv[i] = argv[i - 1];
+ if (optind > 1)
+ new_argv[optind + 1] = print_addr(sin);
+ new_argv[argc + 1] = NULL;
+ execv(PATH_RSH, new_argv);
+ err(1, "execv(%s)", PATH_RSH);
+ } else {
+ int status;
+
+ freeaddrinfo (ai);
+
+ while(waitpid(pid, &status, 0) < 0)
+ ;
+ if(WIFEXITED(status) && WEXITSTATUS(status) == 0)
+ return 0;
+ }
+ }
+ return 1;
+ } else {
+ int ret;
+
+ freeaddrinfo (ai);
+
+ ret = proto (priv_socket1, priv_socket2,
+ argv[optind],
+ local_user, remote_user,
+ cmd, cmd_len,
+ send_broken_auth);
+ return ret;
+ }
+}
+
+static int
+doit (const char *hostname,
+ const char *remote_user,
+ const char *local_user,
+ int port,
+ const char *cmd,
+ size_t cmd_len,
+ int do_errsock,
+ int (*auth_func)(int s,
+ struct sockaddr *this, struct sockaddr *that,
+ const char *hostname, const char *remote_user,
+ const char *local_user, size_t cmd_len,
+ const char *cmd))
+{
+ struct addrinfo *ai, *a;
+ struct addrinfo hints;
+ int error;
+ char portstr[NI_MAXSERV];
+ int ret;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ snprintf (portstr, sizeof(portstr), "%u", ntohs(port));
+
+ error = getaddrinfo (hostname, portstr, &hints, &ai);
+ if (error) {
+ errx (1, "%s: %s", hostname, gai_strerror(error));
+ return -1;
+ }
+
+ for (a = ai; a != NULL; a = a->ai_next) {
+ int s;
+ int errsock;
+
+ s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (s < 0)
+ continue;
+ if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
+ warn ("connect(%s)", hostname);
+ close (s);
+ continue;
+ }
+ if (do_errsock) {
+ struct addrinfo *ea;
+ struct addrinfo hints;
+
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_socktype = a->ai_socktype;
+ hints.ai_protocol = a->ai_protocol;
+ hints.ai_family = a->ai_family;
+ hints.ai_flags = AI_PASSIVE;
+
+ error = getaddrinfo (NULL, "0", &hints, &ea);
+ if (error)
+ errx (1, "getaddrinfo: %s", gai_strerror(error));
+ errsock = socket (ea->ai_family, ea->ai_socktype, ea->ai_protocol);
+ if (errsock < 0)
+ err (1, "socket");
+ if (bind (errsock, ea->ai_addr, ea->ai_addrlen) < 0)
+ err (1, "bind");
+ freeaddrinfo (ea);
+ } else
+ errsock = -1;
+
+ freeaddrinfo (ai);
+ ret = proto (s, errsock,
+ hostname,
+ local_user, remote_user,
+ cmd, cmd_len, auth_func);
+ close (s);
+ return ret;
+ }
+ warnx ("failed to contact %s", hostname);
+ freeaddrinfo (ai);
+ return -1;
+}
+
+#ifdef KRB4
+static int use_v4 = -1;
+#endif
+static int use_v5 = -1;
+static int use_only_broken = 0;
+static int use_broken = 1;
+static char *port_str;
+static const char *user;
+static int do_version;
+static int do_help;
+static int do_errsock = 1;
+
+struct getargs args[] = {
+#ifdef KRB4
+ { "krb4", '4', arg_flag, &use_v4, "Use Kerberos V4",
+ NULL },
+#endif
+ { "krb5", '5', arg_flag, &use_v5, "Use Kerberos V5",
+ NULL },
+ { "broken", 'K', arg_flag, &use_only_broken, "Use priv port",
+ NULL },
+ { "input", 'n', arg_negative_flag, &input, "Close stdin",
+ NULL },
+ { "encrypt", 'x', arg_flag, &do_encrypt, "Encrypt connection",
+ NULL },
+ { "encrypt", 'z', arg_negative_flag, &do_encrypt,
+ "Don't encrypt connection", NULL },
+ { "forward", 'f', arg_flag, &do_forward, "Forward credentials",
+ NULL },
+ { "forward", 'G', arg_negative_flag,&do_forward, "Forward credentials",
+ NULL },
+ { "forwardable", 'F', arg_flag, &do_forwardable,
+ "Forward forwardable credentials", NULL },
+ { "unique", 'u', arg_flag, &do_unique_tkfile,
+ "Use unique remote tkfile", NULL },
+ { "tkfile", 'U', arg_string, &unique_tkfile,
+ "Use that remote tkfile", NULL },
+ { "port", 'p', arg_string, &port_str, "Use this port",
+ "number-or-service" },
+ { "user", 'l', arg_string, &user, "Run as this user",
+ NULL },
+ { "stderr", 'e', arg_negative_flag, &do_errsock, "don't open stderr"},
+ { "version", 0, arg_flag, &do_version, "Print version",
+ NULL },
+ { "help", 0, arg_flag, &do_help, NULL,
+ NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "host [command]");
+ exit (ret);
+}
+
+/*
+ *
+ */
+
+int
+main(int argc, char **argv)
+{
+ int priv_port1, priv_port2;
+ int priv_socket1, priv_socket2;
+ int port = 0;
+ int optind = 0;
+ int ret = 1;
+ char *cmd;
+ size_t cmd_len;
+ const char *local_user;
+ char *host = NULL;
+ int host_index = -1;
+ int status;
+
+ priv_port1 = priv_port2 = IPPORT_RESERVED-1;
+ priv_socket1 = rresvport(&priv_port1);
+ priv_socket2 = rresvport(&priv_port2);
+ setuid(getuid());
+
+ set_progname (argv[0]);
+
+ if (argc >= 2 && argv[1][0] != '-') {
+ host = argv[host_index = 1];
+ optind = 1;
+ }
+
+ status = krb5_init_context (&context);
+ if (status)
+ errx(1, "krb5_init_context failed: %u", status);
+
+ do_forwardable = krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "forwardable",
+ NULL);
+
+ do_forward = krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "forward",
+ NULL);
+
+ do_encrypt = krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "encrypt",
+ NULL);
+
+ if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optind))
+ usage (1);
+
+ if (do_forwardable)
+ do_forward = 1;
+
+#if defined(KRB4) && defined(KRB5)
+ if(use_v4 == -1 && use_v5 == 1)
+ use_v4 = 0;
+ if(use_v5 == -1 && use_v4 == 1)
+ use_v5 = 0;
+#endif
+
+ if (use_only_broken) {
+#ifdef KRB4
+ use_v4 = 0;
+#endif
+ use_v5 = 0;
+ }
+
+ if (do_help)
+ usage (0);
+
+ if (do_version) {
+ print_version (NULL);
+ return 0;
+ }
+
+ if (do_unique_tkfile && unique_tkfile != NULL)
+ errx (1, "Only one of -u and -U allowed.");
+
+ if (do_unique_tkfile)
+ strcpy(tkfile,"-u ");
+ else if (unique_tkfile != NULL) {
+ if (strchr(unique_tkfile,' ') != NULL) {
+ warnx("Space is not allowed in tkfilename");
+ usage(1);
+ }
+ do_unique_tkfile = 1;
+ snprintf (tkfile, sizeof(tkfile), "-U %s ", unique_tkfile);
+ }
+
+ if (host == NULL) {
+ if (argc - optind < 1)
+ usage (1);
+ else
+ host = argv[host_index = optind++];
+ }
+
+ if (optind == argc) {
+ close (priv_socket1);
+ close (priv_socket2);
+ argv[0] = "rlogin";
+ execvp ("rlogin", argv);
+ err (1, "execvp rlogin");
+ }
+
+ 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);
+ }
+ }
+
+ local_user = get_default_username ();
+ if (local_user == NULL)
+ errx (1, "who are you?");
+
+ if (user == NULL)
+ user = local_user;
+
+ cmd_len = construct_command(&cmd, argc - optind, argv + optind);
+
+ /*
+ * Try all different authentication methods
+ */
+
+ if (ret && use_v5) {
+ int tmp_port;
+
+ if (port)
+ tmp_port = port;
+ else
+ tmp_port = krb5_getportbyname (context, "kshell", "tcp", 544);
+
+ auth_method = AUTH_KRB5;
+ ret = doit (host, user, local_user, tmp_port, cmd, cmd_len,
+ do_errsock,
+ send_krb5_auth);
+ }
+#ifdef KRB4
+ if (ret && use_v4) {
+ int tmp_port;
+
+ if (port)
+ tmp_port = port;
+ else if (do_encrypt)
+ tmp_port = krb5_getportbyname (context, "ekshell", "tcp", 545);
+ else
+ tmp_port = krb5_getportbyname (context, "kshell", "tcp", 544);
+
+ auth_method = AUTH_KRB4;
+ ret = doit (host, user, local_user, tmp_port, cmd, cmd_len,
+ do_errsock,
+ send_krb4_auth);
+ }
+#endif
+ if (ret && use_broken) {
+ int tmp_port;
+
+ if(port)
+ tmp_port = port;
+ else
+ tmp_port = krb5_getportbyname(context, "shell", "tcp", 514);
+ auth_method = AUTH_BROKEN;
+ ret = doit_broken (argc, argv, host_index, host,
+ user, local_user,
+ tmp_port,
+ priv_socket1,
+ do_errsock ? priv_socket2 : -1,
+ cmd, cmd_len);
+ }
+ return ret;
+}
diff --git a/crypto/heimdal/appl/rsh/rsh_locl.h b/crypto/heimdal/appl/rsh/rsh_locl.h
new file mode 100644
index 0000000..ecf0f85
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/rsh_locl.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: rsh_locl.h,v 1.22 1999/12/02 17:04:56 joda Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#include <errno.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <err.h>
+#include <roken.h>
+#include <getarg.h>
+#ifdef KRB4
+#include <krb.h>
+#include <prot.h>
+#endif
+#include <krb5.h>
+#include <kafs.h>
+
+#ifndef _PATH_NOLOGIN
+#define _PATH_NOLOGIN "/etc/nologin"
+#endif
+
+#ifndef _PATH_BSHELL
+#define _PATH_BSHELL "/bin/sh"
+#endif
+
+#ifndef _PATH_DEFPATH
+#define _PATH_DEFPATH "/usr/bin:/bin"
+#endif
+
+/*
+ *
+ */
+
+enum auth_method { AUTH_KRB4, AUTH_KRB5, AUTH_BROKEN };
+
+extern enum auth_method auth_method;
+extern int do_encrypt;
+extern krb5_context context;
+extern krb5_keyblock *keyblock;
+extern krb5_crypto crypto;
+extern des_key_schedule schedule;
+extern des_cblock iv;
+
+#define KCMD_VERSION "KCMDV0.1"
+
+#define USERNAME_SZ 16
+#define COMMAND_SZ 1024
+
+#define RSH_BUFSIZ (16 * 1024)
+
+#define PATH_RSH BINDIR "/rsh"
+
+ssize_t do_read (int fd, void *buf, size_t sz);
+ssize_t do_write (int fd, void *buf, size_t sz);
diff --git a/crypto/heimdal/appl/rsh/rshd.c b/crypto/heimdal/appl/rsh/rshd.c
new file mode 100644
index 0000000..f9b6857
--- /dev/null
+++ b/crypto/heimdal/appl/rsh/rshd.c
@@ -0,0 +1,850 @@
+/*
+ * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "rsh_locl.h"
+RCSID("$Id: rshd.c,v 1.29 1999/12/02 17:04:56 joda Exp $");
+
+enum auth_method auth_method;
+
+krb5_context context;
+krb5_keyblock *keyblock;
+krb5_crypto crypto;
+des_key_schedule schedule;
+des_cblock iv;
+
+krb5_ccache ccache, ccache2;
+int kerberos_status = 0;
+
+int do_encrypt = 0;
+
+static int do_unique_tkfile = 0;
+static char tkfile[MAXPATHLEN] = "";
+
+static int do_inetd = 1;
+static char *port_str;
+static int do_rhosts;
+static int do_kerberos = 0;
+static int do_vacuous = 0;
+static int do_log = 1;
+static int do_newpag = 1;
+static int do_version;
+static int do_help = 0;
+
+static void
+syslog_and_die (const char *m, ...)
+{
+ va_list args;
+
+ va_start(args, m);
+ vsyslog (LOG_ERR, m, args);
+ va_end(args);
+ exit (1);
+}
+
+static void
+fatal (int sock, const char *m, ...)
+{
+ va_list args;
+ char buf[BUFSIZ];
+ size_t len;
+
+ *buf = 1;
+ va_start(args, m);
+ len = vsnprintf (buf + 1, sizeof(buf) - 1, m, args);
+ va_end(args);
+ syslog (LOG_ERR, buf + 1);
+ net_write (sock, buf, len + 1);
+ exit (1);
+}
+
+static void
+read_str (int s, char *str, size_t sz, char *expl)
+{
+ while (sz > 0) {
+ if (net_read (s, str, 1) != 1)
+ syslog_and_die ("read: %m");
+ if (*str == '\0')
+ return;
+ --sz;
+ ++str;
+ }
+ fatal (s, "%s too long", expl);
+}
+
+static int
+recv_bsd_auth (int s, u_char *buf,
+ struct sockaddr_in *thisaddr,
+ struct sockaddr_in *thataddr,
+ char *client_username,
+ char *server_username,
+ char *cmd)
+{
+ struct passwd *pwd;
+
+ read_str (s, client_username, USERNAME_SZ, "local username");
+ read_str (s, server_username, USERNAME_SZ, "remote username");
+ read_str (s, cmd, COMMAND_SZ, "command");
+ pwd = getpwnam(server_username);
+ if (pwd == NULL)
+ fatal(s, "Login incorrect.");
+ if (iruserok(thataddr->sin_addr.s_addr, pwd->pw_uid == 0,
+ client_username, server_username))
+ fatal(s, "Login incorrect.");
+ return 0;
+}
+
+#ifdef KRB4
+static int
+recv_krb4_auth (int s, u_char *buf,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ char *client_username,
+ char *server_username,
+ char *cmd)
+{
+ int status;
+ int32_t options;
+ KTEXT_ST ticket;
+ AUTH_DAT auth;
+ char instance[INST_SZ + 1];
+ char version[KRB_SENDAUTH_VLEN + 1];
+
+ if (memcmp (buf, KRB_SENDAUTH_VERS, 4) != 0)
+ return -1;
+ if (net_read (s, buf + 4, KRB_SENDAUTH_VLEN - 4) !=
+ KRB_SENDAUTH_VLEN - 4)
+ syslog_and_die ("reading auth info: %m");
+ if (memcmp (buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN) != 0)
+ syslog_and_die("unrecognized auth protocol: %.8s", buf);
+
+ options = KOPT_IGNORE_PROTOCOL;
+ if (do_encrypt)
+ options |= KOPT_DO_MUTUAL;
+ k_getsockinst (s, instance, sizeof(instance));
+ status = krb_recvauth (options,
+ s,
+ &ticket,
+ "rcmd",
+ instance,
+ (struct sockaddr_in *)thataddr,
+ (struct sockaddr_in *)thisaddr,
+ &auth,
+ "",
+ schedule,
+ version);
+ if (status != KSUCCESS)
+ syslog_and_die ("recvauth: %s", krb_get_err_text(status));
+ if (strncmp (version, KCMD_VERSION, KRB_SENDAUTH_VLEN) != 0)
+ syslog_and_die ("bad version: %s", version);
+
+ read_str (s, server_username, USERNAME_SZ, "remote username");
+ if (kuserok (&auth, server_username) != 0)
+ fatal (s, "Permission denied");
+ read_str (s, cmd, COMMAND_SZ, "command");
+
+ syslog(LOG_INFO|LOG_AUTH,
+ "kerberos v4 shell from %s on %s as %s, cmd '%.80s'",
+ krb_unparse_name_long(auth.pname, auth.pinst, auth.prealm),
+
+ inet_ntoa(((struct sockaddr_in *)thataddr)->sin_addr),
+ server_username,
+ cmd);
+
+ memcpy (iv, auth.session, sizeof(iv));
+
+ return 0;
+}
+
+#endif /* KRB4 */
+
+static int
+save_krb5_creds (int s,
+ krb5_auth_context auth_context,
+ krb5_principal client)
+
+{
+ int ret;
+ krb5_data remote_cred;
+
+ krb5_data_zero (&remote_cred);
+ ret= krb5_read_message (context, (void *)&s, &remote_cred);
+ if (ret) {
+ krb5_data_free(&remote_cred);
+ return 0;
+ }
+ if (remote_cred.length == 0)
+ return 0;
+
+ ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache);
+ if (ret) {
+ krb5_data_free(&remote_cred);
+ return 0;
+ }
+
+ krb5_cc_initialize(context,ccache,client);
+ ret = krb5_rd_cred(context, auth_context, ccache,&remote_cred);
+ krb5_data_free (&remote_cred);
+ if (ret)
+ return 0;
+ return 1;
+}
+
+static void
+krb5_start_session (void)
+{
+ krb5_error_code ret;
+
+ ret = krb5_cc_resolve (context, tkfile, &ccache2);
+ if (ret) {
+ krb5_cc_destroy(context, ccache);
+ return;
+ }
+
+ ret = krb5_cc_copy_cache (context, ccache, ccache2);
+ if (ret) {
+ krb5_cc_destroy(context, ccache);
+ return ;
+ }
+
+ krb5_cc_close(context, ccache2);
+ krb5_cc_destroy(context, ccache);
+ return;
+}
+
+static int
+recv_krb5_auth (int s, u_char *buf,
+ struct sockaddr *thisaddr,
+ struct sockaddr *thataddr,
+ char *client_username,
+ char *server_username,
+ char *cmd)
+{
+ u_int32_t len;
+ krb5_auth_context auth_context = NULL;
+ krb5_ticket *ticket;
+ krb5_error_code status;
+ krb5_data cksum_data;
+ krb5_principal server;
+
+ 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(s, buf, len) != len)
+ syslog_and_die ("reading auth info: %m");
+ if (len != sizeof(KRB5_SENDAUTH_VERSION)
+ || memcmp (buf, KRB5_SENDAUTH_VERSION, len) != 0)
+ syslog_and_die ("bad sendauth version: %.8s", buf);
+
+ status = krb5_sock_to_principal (context,
+ s,
+ "host",
+ KRB5_NT_SRV_HST,
+ &server);
+ if (status)
+ syslog_and_die ("krb5_sock_to_principal: %s",
+ krb5_get_err_text(context, status));
+
+ status = krb5_recvauth(context,
+ &auth_context,
+ &s,
+ KCMD_VERSION,
+ server,
+ KRB5_RECVAUTH_IGNORE_VERSION,
+ NULL,
+ &ticket);
+ krb5_free_principal (context, server);
+ if (status)
+ syslog_and_die ("krb5_recvauth: %s",
+ krb5_get_err_text(context, status));
+
+ read_str (s, server_username, USERNAME_SZ, "remote username");
+ read_str (s, cmd, COMMAND_SZ, "command");
+ read_str (s, client_username, COMMAND_SZ, "local username");
+
+ status = krb5_auth_con_getkey (context, auth_context, &keyblock);
+ if (status)
+ syslog_and_die ("krb5_auth_con_getkey: %s",
+ krb5_get_err_text(context, status));
+
+ status = krb5_crypto_init(context, keyblock, 0, &crypto);
+ if(status)
+ syslog_and_die("krb5_crypto_init: %s",
+ krb5_get_err_text(context, status));
+
+
+ cksum_data.length = asprintf ((char **)&cksum_data.data,
+ "%u:%s%s",
+ ntohs(socket_get_port (thisaddr)),
+ cmd,
+ server_username);
+
+ status = krb5_verify_authenticator_checksum(context,
+ auth_context,
+ cksum_data.data,
+ cksum_data.length);
+
+ if (status)
+ syslog_and_die ("krb5_verify_authenticator_checksum: %s",
+ krb5_get_err_text(context, status));
+
+ free (cksum_data.data);
+
+ if (strncmp (client_username, "-u ", 3) == 0) {
+ do_unique_tkfile = 1;
+ memmove (client_username, client_username + 3,
+ strlen(client_username) - 2);
+ }
+
+ if (strncmp (client_username, "-U ", 3) == 0) {
+ char *end, *temp_tkfile;
+
+ do_unique_tkfile = 1;
+ if (strncmp (server_username + 3, "FILE:", 5) == 0) {
+ temp_tkfile = tkfile;
+ } else {
+ strcpy (tkfile, "FILE:");
+ temp_tkfile = tkfile + 5;
+ }
+ end = strchr(client_username + 3,' ');
+ strncpy(temp_tkfile, client_username + 3, end - client_username - 3);
+ temp_tkfile[end - client_username - 3] = '\0';
+ memmove (client_username, end +1, strlen(end+1)+1);
+ }
+
+ kerberos_status = save_krb5_creds (s, auth_context, ticket->client);
+
+ if(!krb5_kuserok (context,
+ ticket->client,
+ server_username))
+ fatal (s, "Permission denied");
+
+ if (strncmp (cmd, "-x ", 3) == 0) {
+ do_encrypt = 1;
+ memmove (cmd, cmd + 3, strlen(cmd) - 2);
+ } else {
+ do_encrypt = 0;
+ }
+
+ {
+ char *name;
+
+ if (krb5_unparse_name (context, ticket->client, &name) == 0) {
+ char addr_str[256];
+
+ if (inet_ntop (thataddr->sa_family,
+ socket_get_address (thataddr),
+ addr_str, sizeof(addr_str)) == NULL)
+ strlcpy (addr_str, "unknown address",
+ sizeof(addr_str));
+
+ syslog(LOG_INFO|LOG_AUTH,
+ "kerberos v5 shell from %s on %s as %s, cmd '%.80s'",
+ name,
+ addr_str,
+ server_username,
+ cmd);
+ free (name);
+ }
+ }
+
+ return 0;
+}
+
+static void
+loop (int from0, int to0,
+ int to1, int from1,
+ int to2, int from2)
+{
+ fd_set real_readset;
+ int max_fd;
+ int count = 2;
+
+ FD_ZERO(&real_readset);
+ FD_SET(from0, &real_readset);
+ FD_SET(from1, &real_readset);
+ FD_SET(from2, &real_readset);
+ max_fd = max(from0, max(from1, from2)) + 1;
+ for (;;) {
+ int ret;
+ fd_set readset = real_readset;
+ char buf[RSH_BUFSIZ];
+
+ ret = select (max_fd, &readset, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ syslog_and_die ("select: %m");
+ }
+ if (FD_ISSET(from0, &readset)) {
+ ret = do_read (from0, buf, sizeof(buf));
+ if (ret < 0)
+ syslog_and_die ("read: %m");
+ else if (ret == 0) {
+ close (from0);
+ close (to0);
+ FD_CLR(from0, &real_readset);
+ } else
+ net_write (to0, buf, ret);
+ }
+ if (FD_ISSET(from1, &readset)) {
+ ret = read (from1, buf, sizeof(buf));
+ if (ret < 0)
+ syslog_and_die ("read: %m");
+ else if (ret == 0) {
+ close (from1);
+ close (to1);
+ FD_CLR(from1, &real_readset);
+ if (--count == 0)
+ exit (0);
+ } else
+ do_write (to1, buf, ret);
+ }
+ if (FD_ISSET(from2, &readset)) {
+ ret = read (from2, buf, sizeof(buf));
+ if (ret < 0)
+ syslog_and_die ("read: %m");
+ else if (ret == 0) {
+ close (from2);
+ close (to2);
+ FD_CLR(from2, &real_readset);
+ if (--count == 0)
+ exit (0);
+ } else
+ do_write (to2, buf, ret);
+ }
+ }
+}
+
+/*
+ * Used by `setup_copier' to create some pipe-like means of
+ * communcation. Real pipes would probably be the best thing, but
+ * then the shell doesn't understand it's talking to rshd. If
+ * socketpair doesn't work everywhere, some autoconf magic would have
+ * to be added here.
+ *
+ * If it fails creating the `pipe', it aborts by calling fatal.
+ */
+
+static void
+pipe_a_like (int fd[2])
+{
+ if (socketpair (AF_UNIX, SOCK_STREAM, 0, fd) < 0)
+ fatal (STDOUT_FILENO, "socketpair: %m");
+}
+
+/*
+ * Start a child process and leave the parent copying data to and from it. */
+
+static void
+setup_copier (void)
+{
+ int p0[2], p1[2], p2[2];
+ pid_t pid;
+
+ pipe_a_like(p0);
+ pipe_a_like(p1);
+ pipe_a_like(p2);
+ pid = fork ();
+ if (pid < 0)
+ fatal (STDOUT_FILENO, "fork: %m");
+ if (pid == 0) { /* child */
+ close (p0[1]);
+ close (p1[0]);
+ close (p2[0]);
+ dup2 (p0[0], STDIN_FILENO);
+ dup2 (p1[1], STDOUT_FILENO);
+ dup2 (p2[1], STDERR_FILENO);
+ close (p0[0]);
+ close (p1[1]);
+ close (p2[1]);
+ } else { /* parent */
+ close (p0[0]);
+ close (p1[1]);
+ close (p2[1]);
+
+ if (net_write (STDOUT_FILENO, "", 1) != 1)
+ fatal (STDOUT_FILENO, "write failed");
+
+ loop (STDIN_FILENO, p0[1],
+ STDOUT_FILENO, p1[0],
+ STDERR_FILENO, p2[0]);
+ }
+}
+
+/*
+ * Is `port' a ``reserverd'' port?
+ */
+
+static int
+is_reserved(u_short port)
+{
+ return ntohs(port) < IPPORT_RESERVED;
+}
+
+/*
+ * Set the necessary part of the environment in `env'.
+ */
+
+static void
+setup_environment (char *env[7], struct passwd *pwd)
+{
+ asprintf (&env[0], "USER=%s", pwd->pw_name);
+ asprintf (&env[1], "HOME=%s", pwd->pw_dir);
+ asprintf (&env[2], "SHELL=%s", pwd->pw_shell);
+ asprintf (&env[3], "PATH=%s", _PATH_DEFPATH);
+ asprintf (&env[4], "SSH_CLIENT=only_to_make_bash_happy");
+ if (do_unique_tkfile)
+ asprintf (&env[5], "KRB5CCNAME=%s", tkfile);
+ else env[5] = NULL;
+ env[6] = NULL;
+}
+
+static void
+doit (int do_kerberos, int check_rhosts)
+{
+ u_char buf[BUFSIZ];
+ u_char *p;
+ struct sockaddr_storage thisaddr_ss;
+ struct sockaddr *thisaddr = (struct sockaddr *)&thisaddr_ss;
+ struct sockaddr_storage thataddr_ss;
+ struct sockaddr *thataddr = (struct sockaddr *)&thataddr_ss;
+ struct sockaddr_storage erraddr_ss;
+ struct sockaddr *erraddr = (struct sockaddr *)&erraddr_ss;
+ int addrlen;
+ int port;
+ int errsock = -1;
+ char client_user[COMMAND_SZ], server_user[USERNAME_SZ];
+ char cmd[COMMAND_SZ];
+ struct passwd *pwd;
+ int s = STDIN_FILENO;
+ char *env[7];
+
+ addrlen = sizeof(thisaddr_ss);
+ if (getsockname (s, thisaddr, &addrlen) < 0)
+ syslog_and_die("getsockname: %m");
+ addrlen = sizeof(thataddr_ss);
+ if (getpeername (s, thataddr, &addrlen) < 0)
+ syslog_and_die ("getpeername: %m");
+
+ if (!do_kerberos && !is_reserved(socket_get_port(thataddr)))
+ fatal(s, "Permission denied");
+
+ p = buf;
+ port = 0;
+ for(;;) {
+ if (net_read (s, p, 1) != 1)
+ syslog_and_die ("reading port number: %m");
+ if (*p == '\0')
+ break;
+ else if (isdigit(*p))
+ port = port * 10 + *p - '0';
+ else
+ syslog_and_die ("non-digit in port number: %c", *p);
+ }
+
+ if (!do_kerberos && !is_reserved(htons(port)))
+ fatal(s, "Permission denied");
+
+ if (port) {
+ int priv_port = IPPORT_RESERVED - 1;
+
+ /*
+ * There's no reason to require a ``privileged'' port number
+ * here, but for some reason the brain dead rsh clients
+ * do... :-(
+ */
+
+ erraddr->sa_family = thataddr->sa_family;
+ socket_set_address_and_port (erraddr,
+ socket_get_address (thataddr),
+ htons(port));
+
+ /*
+ * we only do reserved port for IPv4
+ */
+
+ if (erraddr->sa_family == AF_INET)
+ errsock = rresvport (&priv_port);
+ else
+ errsock = socket (erraddr->sa_family, SOCK_STREAM, 0);
+ if (errsock < 0)
+ syslog_and_die ("socket: %m");
+ if (connect (errsock,
+ erraddr,
+ socket_sockaddr_size (erraddr)) < 0)
+ syslog_and_die ("connect: %m");
+ }
+
+ if(do_kerberos) {
+ if (net_read (s, buf, 4) != 4)
+ syslog_and_die ("reading auth info: %m");
+
+#ifdef KRB4
+ if (recv_krb4_auth (s, buf, thisaddr, thataddr,
+ client_user,
+ server_user,
+ cmd) == 0)
+ auth_method = AUTH_KRB4;
+ else
+#endif /* KRB4 */
+ if(recv_krb5_auth (s, buf, thisaddr, thataddr,
+ client_user,
+ server_user,
+ cmd) == 0)
+ auth_method = AUTH_KRB5;
+ else
+ syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
+ buf[0], buf[1], buf[2], buf[3]);
+ } else {
+ if(recv_bsd_auth (s, buf,
+ (struct sockaddr_in *)thisaddr,
+ (struct sockaddr_in *)thataddr,
+ client_user,
+ server_user,
+ cmd) == 0) {
+ auth_method = AUTH_BROKEN;
+ if(do_vacuous) {
+ printf("Remote host requires Kerberos authentication\n");
+ exit(0);
+ }
+ } else
+ syslog_and_die("recv_bsd_auth failed");
+ }
+
+ pwd = getpwnam (server_user);
+ if (pwd == NULL)
+ fatal (s, "Login incorrect.");
+
+ if (*pwd->pw_shell == '\0')
+ pwd->pw_shell = _PATH_BSHELL;
+
+ if (pwd->pw_uid != 0 && access (_PATH_NOLOGIN, F_OK) == 0)
+ fatal (s, "Login disabled.");
+
+#ifdef HAVE_GETSPNAM
+ {
+ struct spwd *sp;
+ long today;
+
+ sp = getspnam(server_user);
+ today = time(0)/(24L * 60 * 60);
+ if (sp->sp_expire > 0)
+ if (today > sp->sp_expire)
+ fatal(s, "Account has expired.");
+ }
+#endif
+
+#ifdef HAVE_SETLOGIN
+ if (setlogin(pwd->pw_name) < 0)
+ syslog(LOG_ERR, "setlogin() failed: %m");
+#endif
+
+#ifdef HAVE_SETPCRED
+ if (setpcred (pwd->pw_name, NULL) == -1)
+ syslog(LOG_ERR, "setpcred() failure: %m");
+#endif /* HAVE_SETPCRED */
+ if (initgroups (pwd->pw_name, pwd->pw_gid) < 0)
+ fatal (s, "Login incorrect.");
+
+ if (setgid(pwd->pw_gid) < 0)
+ fatal (s, "Login incorrect.");
+
+ if (setuid (pwd->pw_uid) < 0)
+ fatal (s, "Login incorrect.");
+
+#ifdef KRB5
+ {
+ int fd;
+
+ if (!do_unique_tkfile)
+ snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_%u",pwd->pw_uid);
+ else if (*tkfile=='\0') {
+ snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_XXXXXX");
+ fd = mkstemp(tkfile+5);
+ close(fd);
+ unlink(tkfile+5);
+ }
+
+ if (kerberos_status)
+ krb5_start_session();
+ }
+#endif
+
+ if (chdir (pwd->pw_dir) < 0)
+ fatal (s, "Remote directory.");
+
+ if (errsock >= 0) {
+ if (dup2 (errsock, STDERR_FILENO) < 0)
+ fatal (s, "Dup2 failed.");
+ close (errsock);
+ }
+
+ setup_environment (env, pwd);
+
+ if (do_encrypt) {
+ setup_copier ();
+ } else {
+ if (net_write (s, "", 1) != 1)
+ fatal (s, "write failed");
+ }
+
+#ifdef KRB4
+ if(k_hasafs()) {
+ char cell[64];
+
+ if(do_newpag)
+ k_setpag();
+ if (k_afs_cell_of_file (pwd->pw_dir, cell, sizeof(cell)) == 0)
+ krb_afslog_uid_home (cell, NULL, pwd->pw_uid, pwd->pw_dir);
+
+ krb_afslog_uid_home(NULL, NULL, pwd->pw_uid, pwd->pw_dir);
+
+#ifdef KRB5
+ /* XXX */
+ {
+ krb5_ccache ccache;
+ krb5_error_code status;
+
+ status = krb5_cc_resolve (context, tkfile, &ccache);
+ if (!status) {
+ krb5_afslog_uid_home(context,ccache,NULL,NULL,
+ pwd->pw_uid, pwd->pw_dir);
+ krb5_cc_close (context, ccache);
+ }
+ }
+#endif /* KRB5 */
+ }
+#endif /* KRB4 */
+ execle (pwd->pw_shell, pwd->pw_shell, "-c", cmd, NULL, env);
+ err(1, "exec %s", pwd->pw_shell);
+}
+
+struct getargs args[] = {
+ { "inetd", 'i', arg_negative_flag, &do_inetd,
+ "Not started from inetd" },
+ { "kerberos", 'k', arg_flag, &do_kerberos,
+ "Implement kerberised services" },
+ { "encrypt", 'x', arg_flag, &do_encrypt,
+ "Implement encrypted service" },
+ { "rhosts", 'l', arg_flag, &do_rhosts,
+ "Check users .rhosts" },
+ { "port", 'p', arg_string, &port_str, "Use this port",
+ "port" },
+ { "vacuous", 'v', arg_flag, &do_vacuous,
+ "Don't accept non-kerberised connections" },
+ { NULL, 'P', arg_negative_flag, &do_newpag,
+ "Don't put process in new PAG" },
+ /* compatibility flag: */
+ { NULL, 'L', arg_flag, &do_log },
+ { "version", 0, arg_flag, &do_version },
+ { "help", 0, arg_flag, &do_help }
+};
+
+static void
+usage (int ret)
+{
+ if(isatty(STDIN_FILENO))
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "");
+ else
+ syslog (LOG_ERR, "Usage: %s [-ikxlvPL] [-p port]", __progname);
+ exit (ret);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+ int port = 0;
+
+ set_progname (argv[0]);
+ roken_openlog ("rshd", LOG_ODELAY | LOG_PID, LOG_AUTH);
+
+ if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optind))
+ usage(1);
+
+ if(do_help)
+ usage (0);
+
+ if (do_version) {
+ print_version(NULL);
+ exit(0);
+ }
+
+#ifdef KRB5
+ krb5_init_context (&context);
+#endif
+
+ 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)
+ syslog_and_die("Bad port `%s'", port_str);
+ port = htons(port);
+ }
+ }
+
+ if (do_encrypt)
+ do_kerberos = 1;
+
+ if (!do_inetd) {
+ if (port == 0) {
+ if (do_kerberos) {
+ if (do_encrypt)
+ port = krb5_getportbyname (context, "ekshell", "tcp", 545);
+ else
+ port = krb5_getportbyname (context, "kshell", "tcp", 544);
+ } else {
+ port = krb5_getportbyname(context, "shell", "tcp", 514);
+ }
+ }
+ mini_inetd (port);
+ }
+
+ signal (SIGPIPE, SIG_IGN);
+
+ doit (do_kerberos, do_rhosts);
+ return 0;
+}
OpenPOWER on IntegriCloud