diff options
author | Mark Murray <markm@FreeBSD.org> | 2000-01-09 20:58:00 +0000 |
---|---|---|
committer | Mark Murray <markm@FreeBSD.org> | 2000-01-09 20:58:00 +0000 |
commit | b528cefc6b8f9670b31a865051741d946cb37085 (patch) | |
tree | 36fa73706fa0587a390c45a3fbf17c9523cb0e35 /crypto/heimdal/appl/rsh |
Import KTH Heimdal, which will be the core of our Kerberos5.vendor/heimdal/0.2m
Userland to follow.
Notes
Notes:
svn path=/vendor-crypto/heimdal/dist/; revision=55682
svn path=/vendor-crypto/heimdal/0.2m/; revision=55684; tag=vendor/heimdal/0.2m
Diffstat (limited to 'crypto/heimdal/appl/rsh')
-rw-r--r-- | crypto/heimdal/appl/rsh/ChangeLog | 237 | ||||
-rw-r--r-- | crypto/heimdal/appl/rsh/Makefile.am | 19 | ||||
-rw-r--r-- | crypto/heimdal/appl/rsh/Makefile.in | 698 | ||||
-rw-r--r-- | crypto/heimdal/appl/rsh/common.c | 124 | ||||
-rw-r--r-- | crypto/heimdal/appl/rsh/rsh.c | 948 | ||||
-rw-r--r-- | crypto/heimdal/appl/rsh/rsh_locl.h | 139 | ||||
-rw-r--r-- | crypto/heimdal/appl/rsh/rshd.c | 850 |
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 000000000000..c07d8d0be9b2 --- /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 000000000000..0875f9ffe7dc --- /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 000000000000..1800c7b81d9c --- /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 000000000000..6614137cf695 --- /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 000000000000..444748ea6f87 --- /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 000000000000..ecf0f85ab6f9 --- /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 000000000000..f9b685768bd6 --- /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; +} |