diff --exclude CVS -ur inetutils/acinclude.m4 feg-inetutils/acinclude.m4
--- inetutils/acinclude.m4	2004-02-03 20:43:10.000000000 +0100
+++ feg-inetutils/acinclude.m4	2004-05-25 16:11:14.000000000 +0200
@@ -22,6 +22,8 @@
 dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 dnl
 
+sinclude(libgnutls-extra.m4)
+
 dnl IU_FLUSHLEFT -- remove all whitespace at the beginning of lines
 dnl This is useful for c-code which may include cpp statements
 dnl
Only in feg-inetutils/: ChangeLog.feg
diff --exclude CVS -ur inetutils/configure.ac feg-inetutils/configure.ac
--- inetutils/configure.ac	2004-02-03 20:43:10.000000000 +0100
+++ feg-inetutils/configure.ac	2004-05-25 16:21:59.000000000 +0200
@@ -1,6 +1,6 @@
 # Configuration for inetutils
 #
-# Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
 #
 # Written by Miles Bader <miles@gnu.ai.mit.edu>
 #
@@ -21,7 +21,7 @@
 
 AC_PREREQ(2.54)
 
-AC_INIT([GNU inetutils], [1.4.2], [bug-inetutils@gnu.org])
+AC_INIT([FEG inetutils], [2.0.0], [feg-inetutils@josefsson.org])
 
 AC_CONFIG_SRCDIR([inetd/inetd.c])
 AM_CONFIG_HEADER([config.h:config.hin])
@@ -33,7 +33,7 @@
 # Include files that we link into our own include directory from headers.
 # Initialize it with the things we always want to use.
 IU_CONFIG_LINKS([crypt.h, arpa/telnet.h, arpa/ftp.h, arpa/tftp.h,
-                 protocols/talkd.h, tftpsubs.h])
+                 protocols/talkd.h, tftpsubs.h, shishi_def.h])
 
 dnl For now, we always use libexecdir; later we may want to vary where the
 dnl daemons go.
@@ -58,6 +58,16 @@
 AC_ARG_WITH(krb5, [  --with-krb5[[=PATH]]      Compile with Kerberos V],
             [KERBEROS_VERSION=5
              KERBEROS_DIR=$withval])
+AC_ARG_WITH(shishi, AC_HELP_STRING([--with-shishi[[=PATH]]],
+				   [Compile with Shishi (Kerberos 5)]),
+            [KERBEROS_VERSION=Shishi
+             KERBEROS_DIR=$withval])
+
+check_gnutls=no
+AC_ARG_WITH(tls, AC_HELP_STRING([--with-tls],
+				   [Compile with GnuTLS support]),
+            check_gnutls=yes)
+
 AC_ARG_WITH(wrap, [  --with-wrap    add tcp wrapper support])
 AC_ARG_WITH(pam,  [  --with-pam    add support for PAM])
 
@@ -99,6 +109,16 @@
 AC_PROG_RANLIB
 AC_PROG_YACC
 
+if test $check_gnutls != no; then
+AM_PATH_LIBGNUTLS_EXTRA( 1.0.11,
+AC_DEFINE(TLS, 1, [Use AUTH TLS])
+, AC_MSG_ERROR([[
+***
+*** libgnutls was not found. You may want to get it from
+*** ftp://ftp.gnutls.org/pub/gnutls/
+]]))
+fi
+
 dnl __P is the standard name for the ansi-or-not-ansi arg-decl macro.
 dnl We define our own version in <config.h> if the system doesn't supply one.
 dnl NOTE: This check has to be done pretty early because we use __P in
@@ -236,6 +256,7 @@
   AH_TEMPLATE(KERBEROS, [Define to one if you have Kerberos])
   AH_TEMPLATE(KRB4, [Define to one if you have Kerberos IV])
   AH_TEMPLATE(KRB5, [Define to one if you have Kerberos V])
+  AH_TEMPLATE(SHISHI, [Define to 1 if you have Shishi])
   AH_TEMPLATE(DES_ENCRYPTION, [FIXME])
   
   if test "$KERBEROS_VERSION" = 4; then
@@ -255,7 +276,7 @@
       test "$enable_encryption" = yes -a "$ac_cv_lib_des_des_key_sched" = yes \
         && AC_DEFINE(DES_ENCRYPTION)
     fi
-  else
+  elif test "$KERBEROS_VERSION" = 5; then
     IU_CHECK_KRB5($KERBEROS_VERSION,$KERBEROS_DIR)
     LIBAUTH=$KRB5_LIBS
     INCAUTH=$KRB_CFLAGS
@@ -269,6 +290,22 @@
          ;;
       esac
     fi
+  else
+    if test x$KERBEROS_DIR != x; then
+      LIBAUTH=-L$KERBEROS_DIR/lib
+      INCAUTH=-I$KERBEROS_DIR/include
+    fi
+    LIBAUTH="$LIBAUTH -lshishi"
+    save_LIBS=$LIBS
+    LIBS="$LIBS $LIBAUTH"
+    save_CPPFLAGS=$CPPFLAGS
+    CPPFLAGS="$CPPFLAGS $INCAUTH"
+    AC_CHECK_HEADER(shishi.h,
+      AC_CHECK_LIB(shishi, shishi_check_version,
+        AC_DEFINE(SHISHI),
+        [INCAUTH= LIBAUTH=]))
+    LIBS=$save_LIBS
+    CPPFLAGS=$save_CPPFLAGS
   fi
 fi
 AC_SUBST(LIBAUTH)
diff --exclude CVS -ur inetutils/.cvsignore feg-inetutils/.cvsignore
--- inetutils/.cvsignore	2002-07-31 23:51:19.000000000 +0200
+++ feg-inetutils/.cvsignore	2004-05-25 20:48:49.000000000 +0200
@@ -12,3 +12,5 @@
 stamp-h.in
 config.hin
 autom4te.cache
+config.h
+stamp*
Only in feg-inetutils/: .cvsusers
diff --exclude CVS -ur inetutils/ftp/ChangeLog feg-inetutils/ftp/ChangeLog
--- inetutils/ftp/ChangeLog	2002-04-29 22:41:25.000000000 +0200
+++ feg-inetutils/ftp/ChangeLog	2004-05-28 19:45:44.000000000 +0200
@@ -1,3 +1,24 @@
+2004-05-27  Nikos Mavroyanopoulos <nmav@gnutls.org>
+
+        * ruserpass.c, ftp.1: Added support for .ftprc
+        file to be used instead of the .netrc. This is because
+        we use some extra TLS options that may confuse other programs.
+        The .netrc file is read as a fallback.
+
+2004-05-25  Nikos Mavroyanopoulos <nmav@gnutls.org>
+
+        * ftp.c: Fixed the data connection abort with
+        some servers.
+        * main.c: Passive mode is enabled by default.
+
+2004-05-24  Nikos Mavroyanopoulos <nmav@gnutls.org>
+
+        * session.h: added
+        * tlsutil.h: added
+        * tlsutil.c: added
+        * ftp.c: Added support for AUTH TLS using GnuTLS,
+        based on the code of Peter Runestig's ftp-tls.
+
 2002-04-29  Alfred M. Szmidt  <ams@kemisten.nu>
 
 	* main.c <version.h>: Include removed.
diff --exclude CVS -ur inetutils/ftp/cmds.c feg-inetutils/ftp/cmds.c
--- inetutils/ftp/cmds.c	2001-12-25 19:05:16.000000000 +0100
+++ feg-inetutils/ftp/cmds.c	2004-05-26 19:49:53.000000000 +0200
@@ -50,6 +50,9 @@
 #include <netinet/in.h>
 #include <arpa/ftp.h>
 
+#include <pwd.h>
+#include <signal.h>
+
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
@@ -73,6 +76,7 @@
    system headers on some platforms. */
 #include <glob.h>
 
+#include "session.h"
 #include "ftp_var.h"
 
 /* Returns true if STR is entirely lower case.  */
@@ -121,6 +125,7 @@
 	return str;
 }
 
+
 jmp_buf	jabort;
 char   *mname;
 char   *home = "/";
@@ -197,6 +202,16 @@
 		port = htons(port);
 	}
 	host = hookup(argv[1], port);
+#ifdef TLS
+        tls_hostname = strdup(argv[1]);
+
+	if (tls_init()) {
+		warnx("tls_init() error");
+		exit(1); /* exit on TLS init error */
+	}
+
+#endif /* TLS */
+
 	if (host) {
 		int overbose;
 
@@ -210,6 +225,35 @@
 		(void) strcpy(modename, "stream"), mode = MODE_S;
 		(void) strcpy(structname, "file"), stru = STRU_F;
 		(void) strcpy(bytename, "8"), bytesize = 8;
+
+#ifdef TLS
+		if (tls_on_ctrl || require_tls) {
+		    if (command("AUTH TLS") == COMPLETE) {
+			extern FILE *cout, *cin;
+			extern int tls_private(int on);
+			/* if SSL_connect() fails, we might get SIGPIPE within it */
+			my_sig_t oldsig = signal(SIGPIPE, SIG_IGN);
+			/* disconnect if tls_connect_ctrl() fails */
+			if (tls_connect_ctrl(fileno(cin), fileno(cout))) {
+			    /* keep ignoring SIGPIPE over disconnect() */
+			    disconnect(0, NULL);
+			    fprintf(stdout,
+			        "Failed TLS negotiation on control channel, disconnected\n");
+			    signal(SIGPIPE, oldsig);
+			    return;
+			}
+			signal(SIGPIPE, oldsig);
+			if (tls_on_data)
+			    tls_on_data = tls_private(tls_on_data);
+		    } else {
+		        warnx("Host does not support TLS authentication");
+		        if (require_tls)
+		        	quit(0,0);
+			tls_on_data = 0;
+		    }
+	        }
+#endif /* TLS */
+
 		if (autologin)
 			(void) login(argv[1]);
 
@@ -269,6 +313,102 @@
 	}
 }
 
+/* Functions to retrieve the username and the password from the
+ * user.
+ */
+/* If authenticated with TLS SRP then this should be non-null.
+ */
+
+const char* get_username( const char* host) 
+{
+char *myname = getlogin();
+static char tmp[80], *ruser = 0;
+const char* user;
+
+#ifdef TLS
+	if (srp_username)
+		return srp_username;
+#endif
+
+	if (ruserpass((char*)host, &ruser, NULL, NULL) < 0) {
+		return NULL;
+	}
+	if (ruser) return ruser;
+
+	if (myname == NULL) {
+		struct passwd *pp = getpwuid(getuid());
+
+		if (pp != NULL)
+			myname = pp->pw_name;
+	}
+
+
+	if (myname)
+		printf("Name (%s:%s): ", host, myname);
+	else
+		printf("Name (%s): ", host);
+
+	if (fgets(tmp, sizeof(tmp) - 1, stdin)) {
+		/* If they press Ctrl-d immediately, it's empty.  */
+		tmp[strlen(tmp) - 1] = '\0';
+	} else
+		*tmp = '\0';
+	if (*tmp == '\0')
+		user = myname;
+	else
+		user = tmp;
+		
+	return user;
+}
+
+/* srp should be non zero if this function is called
+ * for SRP authentication.
+ */
+char* get_password( const char* host, int srp)
+{
+char* pass = 0;
+static char xxx[] = "XXXX";
+	/* we shouldn't need that in real TLS-SRP
+	 * servers, but anyway.
+	 */
+#ifdef TLS
+	/* If SRP has been negotiated then it's no good
+	 * giving our password to the server. SRP was used
+	 * to avoid sending it, anyway.
+	 */
+	if (srp_username && srp == 0)
+		return xxx;
+#endif
+
+	if (ruserpass((char*)host, NULL, &pass, NULL) < 0) {
+		return NULL;
+	}
+	if (pass) return pass;
+
+	return getpass("Password:");
+}
+
+/* Overwrites the given password.
+ */
+void delete_password( char* pass)
+{
+	if (pass != NULL)
+		memset( pass, 'X', strlen(pass));
+}
+
+const char* get_account( const char* host, const char* msg)
+{
+char* acct = 0;
+
+	if (ruserpass((char*)host, NULL, NULL, &acct) < 0) {
+		return NULL;
+	}
+	if (acct) return acct;
+
+	return getpass(msg);
+}
+
+
 struct	types {
 	char	*t_name;
 	char	*t_mode;
@@ -1016,6 +1156,15 @@
 	else {
 		printf("Nmap: off\n");
 	}
+#ifdef TLS
+	{
+	char c[60] = "not connected";
+	extern FILE *cin;
+	if (connected && cin)
+	    snprintf(c, sizeof(c), "%s", tls_get_cipher_info_string(fileno(cin)));
+	fprintf(stdout, "Private: %s, control connection %s\n", onoff(tls_on_data), c);
+	}
+#endif /* TLS */
 	printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
 		onoff(hash), onoff(sendport));
 	if (macnum > 0) {
@@ -1093,6 +1242,83 @@
 	code = verbose;
 }
 
+#ifdef TLS
+/*
+ * Toggle a variable
+ */
+static int
+togglevar(argc, argv, var, mesg)
+	int   argc;
+	char *argv[];
+	int  *var;
+	const char *mesg;
+{
+	if (argc < 2) {
+		*var = !*var;
+	} else if (argc == 2 && strcasecmp(argv[1], "on") == 0) {
+		*var = 1;
+	} else if (argc == 2 && strcasecmp(argv[1], "off") == 0) {
+		*var = 0;
+	} else {
+		fprintf(stdout, "usage: %s [ on | off ]\n", argv[0]);
+		return (-1);
+	}
+	if (mesg)
+		fprintf(stdout, "%s %s.\n", mesg, onoff(*var));
+	return (*var);
+}
+
+int tls_private(int on)
+{
+    int r = on;
+    
+    if (command("PBSZ 0") == COMPLETE) {
+	if (on) {
+	    if (command("PROT P") != COMPLETE)
+		r = 0;
+	}
+	else
+	    command("PROT C");
+    } else
+	r = 0;
+    return r;
+}
+
+/*
+ * Turn on TLS on data channel
+ */
+/*VARARGS*/
+void
+setprivate(argc, argv)
+    int argc;
+    char *argv[];
+{
+    extern FILE *cin;
+    
+    if (connected && cin && !tls_active(fileno(cin)) && !tls_on_data)
+	fprintf(stdout, "Can't set Private, control channel is clear.\n");
+    else {
+	int r;
+	r = code = togglevar(argc, argv, &tls_on_data, "Private mode");
+	/* toggle it again if PBSZ/PROT fails */
+	if (connected && r != tls_private(tls_on_data))
+	    code = togglevar(argc, argv, &tls_on_data, "Private mode");
+    }
+}
+
+/*
+ * Turn on TLS on control channel
+ */
+/*VARARGS*/
+void
+setprotect(argc, argv)
+    int argc;
+    char *argv[];
+{
+	code = togglevar(argc, argv, &tls_on_ctrl, "TLS mode");
+}
+#endif /* TLS */
+
 /*
  * Toggle PORT cmd use before each data connection.
  */
@@ -1720,6 +1946,9 @@
 	if (connected) {
 		disconnect(0, 0);
 	}
+#ifdef TLS
+	tls_cleanup();
+#endif /* TLS */
 	exit(0);
 }
 
@@ -1736,8 +1965,11 @@
 		return;
 	(void) command("QUIT");
 	if (cout) {
-		(void) fclose(cout);
+		(void) session_fclose(cout);
 	}
+#ifdef TLS
+	tls_shutdown(-1, 0);
+#endif /* TLS */
 	cout = NULL;
 	connected = 0;
 	data = -1;
diff --exclude CVS -ur inetutils/ftp/cmdtab.c feg-inetutils/ftp/cmdtab.c
--- inetutils/ftp/cmdtab.c	2000-07-06 06:21:07.000000000 +0200
+++ feg-inetutils/ftp/cmdtab.c	2004-05-24 22:57:07.000000000 +0200
@@ -79,7 +79,13 @@
 char	nmaphelp[] =	"set templates for default file name mapping";
 char	ntranshelp[] =	"set translation table for default file name mapping";
 char	porthelp[] =	"toggle use of PORT cmd for each data connection";
+#ifdef TLS
+char	privatehelp[] = "toggle use of TLS on data channel";
+#endif /* TLS */
 char	prompthelp[] =	"force interactive prompting on multiple commands";
+#ifdef TLS
+char    protecthelp[] = "toggle use of TLS on control channel";
+#endif /* TLS */
 char	proxyhelp[] =	"issue command on alternate connection";
 char	pwdhelp[] =	"print working directory on remote machine";
 char	quithelp[] =	"terminate ftp session and exit";
@@ -152,7 +158,13 @@
 	{ "ntrans",	ntranshelp,	0,	0,	1,	setntrans },
 	{ "open",	connecthelp,	0,	0,	1,	setpeer },
 	{ "passive",	passivehelp,	0,	0,	0,	setpassive },
+#ifdef TLS
+	{ "private",	privatehelp,	0, 	0, 	0,	setprivate },
+#endif /* TLS */
 	{ "prompt",	prompthelp,	0,	0,	0,	setprompt },
+#ifdef TLS
+        { "protect",    protecthelp,    0, 	0, 	0,      setprotect },
+#endif /* TLS */
 	{ "proxy",	proxyhelp,	0,	0,	1,	doproxy },
 	{ "sendport",	porthelp,	0,	0,	0,	setport },
 	{ "put",	sendhelp,	1,	1,	1,	put },
diff --exclude CVS -ur inetutils/ftp/extern.h feg-inetutils/ftp/extern.h
--- inetutils/ftp/extern.h	2000-08-09 07:44:23.000000000 +0200
+++ feg-inetutils/ftp/extern.h	2004-05-26 19:49:53.000000000 +0200
@@ -32,7 +32,7 @@
 struct timeval;
 struct fd_set;
 
-void    abort_remote __P((FILE *));
+void    abort_remote __P((FILE *, int));
 void    abortpt __P(());
 void    abortrecv __P(());
 void    abortsend __P(());
@@ -118,6 +118,10 @@
 void	setpassive __P((int, char **));
 void	setpeer __P((int, char **));
 void	setport __P((int, char **));
+#ifdef TLS
+void	setprivate(int, char **);
+void	setprotect(int, char **);
+#endif /* TLS */
 void	setprompt __P((int, char **));
 void	setrunique __P((int, char **));
 void	setstruct __P((int, char **));
@@ -134,7 +138,14 @@
 void	syst __P((int, char **));
 void    tvsub __P((struct timeval *, struct timeval *, struct timeval *));
 void	user __P((int, char **));
+char* get_password( const char* host, int srp);
+void delete_password( char* pass);
+const char* get_account( const char* host, const char* msg);
+const char* get_username( const char* host);
 
+#ifdef TLS
+extern char* srp_username;
+#endif
 extern jmp_buf	abortprox;
 extern int	abrtflag;
 extern struct	cmd cmdtab[];
diff --exclude CVS -ur inetutils/ftp/ftp.1 feg-inetutils/ftp/ftp.1
--- inetutils/ftp/ftp.1	2000-07-08 03:00:53.000000000 +0200
+++ feg-inetutils/ftp/ftp.1	2004-05-28 19:45:53.000000000 +0200
@@ -27,7 +27,7 @@
 .\"
 .\"	@(#)ftp.1	8.3 (Berkeley) 10/9/94
 .\"
-.Dd October 9, 1994
+.Dd May 25, 2004
 .Dt FTP 1
 .Os BSD 4.2
 .Sh NAME
@@ -42,6 +42,8 @@
 .Op Fl i
 .Op Fl n
 .Op Fl g
+.Op Fl A
+.Op Fl z tlsoption
 .Op Ar host
 .Sh DESCRIPTION
 .Nm Ftp
@@ -59,6 +61,8 @@
 .Nm ftp
 to show all responses from the remote server, as well
 as report on data transfer statistics.
+.It Fl A
+will use active mode ftp (passive is the default)
 .It Fl n
 Restrains
 .Nm ftp
@@ -66,8 +70,8 @@
 If auto-login is enabled,
 .Nm ftp
 will check the
-.Pa .netrc
-(see below) file in the user's home directory for an entry describing
+.Pa .ftprc or .netrc
+(see below) files in the user's home directory for an entry describing
 an account on the remote machine.
 If no entry exists,
 .Nm ftp
@@ -81,6 +85,32 @@
 Enables debugging.
 .It Fl g
 Disables file name globbing.
+
+.It Fl z Ic noprotect
+Disable AUTH TLS by default.
+.It Fl z Ic private
+Use TLS on data channel by default.
+.It Fl z Ic certsok
+Don't do any verification on the server's certificate.
+.It Fl z Ic nosrp
+Disable the TLS SRP ciphersuites.
+.It Fl z Ic requiretls
+Fail if TLS cannot be negotiated.
+.It Fl z Ic CAfile=\fIFILE\fR
+Use CA certificate(s) in \fIFILE\fR.
+.It Fl z Ic crlfile=\fIFILE\fR
+Use Certificate Revocation List in \fIFILE\fR.
+.It Fl z Ic cert=\fIFILE\fR
+Use certificate in \fIFILE\fR.
+.It Fl z Ic key=\fIFILE\fR
+Use private key in \fIFILE\fR.
+.It Fl z Ic pgpring=\fIFILE\fR
+Use OpenPGP keyring in \fIFILE\fR.
+.It Fl z Ic pgpcert=\fIFILE\fR
+Use OpenPGP certificate in \fIFILE\fR.
+.It Fl z Ic pgpkey=\fIFILE\fR
+Use OpenPGP private key in \fIFILE\fR.
+
 .El
 .Pp
 The client host with which
@@ -140,14 +170,13 @@
 .Ic type
 to network
 .Tn ASCII .
-This is the default type.
 .It Ic bell
 Arrange that a bell be sounded after each file transfer
 command is completed.
 .It Ic binary
 Set the file transfer
 .Ic type
-to support binary image transfer.
+to support binary transfer. This is the default type.
 .It Ic bye
 Terminate the
 .Tn FTP
@@ -601,7 +630,7 @@
 server (see below).
 .It Ic passive
 Toggle passive mode.  If passive mode is turned on
-(default is off), the ftp client will
+(default is on), the ftp client will
 send a
 .Dv PASV
 command for all data connections instead of the usual
@@ -620,6 +649,8 @@
 (Note that though ftp servers are required to support the
 .Dv PASV
 command by RFC 1123, some do not.)
+.It Ic private
+Toggle TLS use on the data channel with the \fBPBSZ\fR / \fBPROT\fR command sequence.
 .It Ic prompt
 Toggle interactive prompting.
 Interactive prompting
@@ -632,6 +663,10 @@
 will transfer all files, and any
 .Ic mdelete
 will delete all files.
+.It Ic protect
+Toggle use of TLS on the control channel by the \fBAUTH TLS\fR command. Note
+that this doesn't change the TLS status on any current connected control
+channel.
 .It Ic proxy Ar ftp-command
 Execute an ftp command on a secondary control connection.
 This command allows simultaneous connection to two remote ftp
@@ -1005,14 +1040,14 @@
 affect a file transfer.
 The
 .Ic type
-may be one of \*(Lqascii\*(Rq, \*(Lqimage\*(Rq (binary),
+may be one of \*(Lqascii\*(Rq, \*(Lqbinary\*(Rq (image),
 \*(Lqebcdic\*(Rq, and \*(Lqlocal byte size\*(Rq (for
 .Tn PDP Ns -10's
 and
 .Tn PDP Ns -20's
 mostly).
 .Nm Ftp
-supports the ascii and image types of file transfer,
+supports the ascii and binary types of file transfer,
 plus local byte size 8 for
 .Ic tenex
 mode transfers.
@@ -1024,12 +1059,16 @@
 .Ic form ,
 and
 .Ic struct  .
-.Sh THE .netrc FILE
+.Sh THE .ftprc and .netrc FILES
 The
-.Pa .netrc
-file contains login and initialization information
+.Pa .ftprc and .netrc
+files contains login and initialization information
 used by the auto-login process.
-It resides in the user's home directory.
+It resides in the user's home directory. This client will prefer
+.Pa .ftprc
+if present and read the
+.Pa .netrc
+as a fallback.
 The following tokens are recognized; they may be separated by spaces,
 tabs, or new-lines:
 .Bl -tag -width password
@@ -1037,7 +1076,7 @@
 Identify a remote machine
 .Ar name .
 The auto-login process searches the
-.Pa .netrc
+.Pa .ftprc
 file for a
 .Ic machine
 token that matches the remote machine specified on the
@@ -1046,7 +1085,7 @@
 .Ic open
 command argument.
 Once a match is made, the subsequent
-.Pa .netrc
+.Pa .ftprc
 tokens are processed,
 stopping when the end of file is reached or another
 .Ic machine
@@ -1073,7 +1112,7 @@
 .Ar automatic
 anonymous ftp login to
 machines not specified in
-.Pa .netrc .
+.Pa .ftprc .
 This can be overridden
 by using the
 .Fl n
@@ -1089,13 +1128,13 @@
 specified string if the remote server requires a password as part
 of the login process.
 Note that if this token is present in the
-.Pa .netrc
+.Pa .ftprc
 file for any user other
 than
 .Ar anonymous  ,
 .Nm ftp
 will abort the auto-login process if the
-.Pa .netrc
+.Pa .ftprc
 is readable by
 anyone besides the user.
 .It Ic account Ar string
@@ -1113,13 +1152,31 @@
 command functions.
 A macro is defined with the specified name; its contents begin with the
 next
-.Pa .netrc
+.Pa .ftprc
 line and continue until a null line (consecutive new-line
 characters) is encountered.
 If a macro named
 .Ic init
 is defined, it is automatically executed as the last step in the
 auto-login process.
+.It Ic private 
+Use TLS on data channel by default.
+.It Ic requiretls
+Use TLS on control channel or fail.
+.It Ic ca Ar file
+Defines a file to be used to read X.509 trusted authorities from.
+.It Ic crl Ar file
+Defines a file to be used to read X.509 certificate revocation lists from.
+.It Ic certificate Ar file
+Defines a file to be used to read the user's X.509 certificate.
+.It Ic key Ar file
+Defines a file to be used to read the user's X.509 key.
+.It Ic pgpcertificate Ar file
+Defines a file to be used to read the user's OpenPGP certificate.
+.It Ic pgpkey Ar file
+Defines a file to be used to read the user's OpenPGP key.
+.It Ic pgpring Ar file
+Defines a file to be used to read the user's OpenPGP trusted key ring.
 .El
 .Sh ENVIRONMENT
 .Nm Ftp
@@ -1127,8 +1184,8 @@
 .Bl -tag -width Fl
 .It Ev HOME
 For default location of a
-.Pa .netrc
-file, if one exists.
+.Pa .ftprc or .netrc
+files, if they exist.
 .It Ev SHELL
 For default shell.
 .El
@@ -1152,4 +1209,4 @@
 to and from
 .Bx 4.2
 servers using the ascii type.
-Avoid this problem by using the binary image type.
+Avoid this problem by using the binary type.
diff --exclude CVS -ur inetutils/ftp/ftp.c feg-inetutils/ftp/ftp.c
--- inetutils/ftp/ftp.c	2002-05-14 17:13:56.000000000 +0200
+++ feg-inetutils/ftp/ftp.c	2004-05-26 19:49:53.000000000 +0200
@@ -83,6 +83,7 @@
 #endif
 
 #include "ftp_var.h"
+#include "session.h"
 
 #if !HAVE_DECL_FCLOSE
 /* Some systems don't declare fclose in <stdio.h>, so do it ourselves.  */
@@ -106,7 +107,6 @@
 struct	sockaddr_in myctladdr;
 off_t	restart_point = 0;
 
-
 FILE	*cin, *cout;
 
 char *
@@ -236,50 +236,27 @@
 }
 
 int
-login(host)
-	char *host;
+login(char *host)
 {
 	char tmp[80];
 	char *user, *pass, *acct;
 	int n, aflag = 0;
 
 	user = pass = acct = 0;
-	if (ruserpass(host, &user, &pass, &acct) < 0) {
-		code = -1;
-		return (0);
-	}
-	while (user == NULL) {
-		char *myname = getlogin();
-
-		if (myname == NULL) {
-			struct passwd *pp = getpwuid(getuid());
 
-			if (pp != NULL)
-				myname = pp->pw_name;
-		}
-		if (myname)
-			printf("Name (%s:%s): ", host, myname);
-		else
-			printf("Name (%s): ", host);
-		if (fgets(tmp, sizeof(tmp) - 1, stdin)) {
-			/* If they press Ctrl-d immediately, it's empty.  */
-			tmp[strlen(tmp) - 1] = '\0';
-		} else
-			*tmp = '\0';
-		if (*tmp == '\0')
-			user = myname;
-		else
-			user = tmp;
+	while (user == NULL) {
+		user = (char*) get_username( host);
 	}
 	n = command("USER %s", user);
 	if (n == CONTINUE) {
 		if (pass == NULL)
-			pass = getpass("Password:");
+			pass = get_password(host, 0);
 		n = command("PASS %s", pass);
+		delete_password( pass);
 	}
 	if (n == CONTINUE) {
 		aflag++;
-		acct = getpass("Account:");
+		acct = (char*) get_account(host, "Account:");
 		n = command("ACCT %s", acct);
 	}
 	if (n != COMPLETE) {
@@ -365,10 +342,10 @@
 	va_start(ap);
 	fmt = va_arg(ap, char *);
 #endif
-	vfprintf(cout, fmt, ap);
+	session_vfprintf(cout, fmt, ap);
 	va_end(ap);
-	fprintf(cout, "\r\n");
-	(void) fflush(cout);
+	session_fprintf(cout, "\r\n");
+	(void) session_fflush(cout);
 	cpend = 1;
 	r = getreply(!strcmp(fmt, "QUIT"));
 	if (abrtflag && oldintr != SIG_IGN)
@@ -380,8 +357,7 @@
 char reply_string[BUFSIZ];		/* last line of previous reply */
 
 int
-getreply(expecteof)
-	int expecteof;
+getreply(int expecteof)
 {
 	int c, n;
 	int dig;
@@ -394,20 +370,20 @@
 	for (;;) {
 		dig = n = code = 0;
 		cp = reply_string;
-		while ((c = getc(cin)) != '\n') {
+		while ((c = session_fgetc(cin)) != '\n') {
 			if (c == IAC) {     /* handle telnet commands */
-				switch (c = getc(cin)) {
+				switch (c = session_fgetc(cin)) {
 				case WILL:
 				case WONT:
-					c = getc(cin);
-					fprintf(cout, "%c%c%c", IAC, DONT, c);
-					(void) fflush(cout);
+					c = session_fgetc(cin);
+					session_fprintf(cout, "%c%c%c", IAC, DONT, c);
+					(void) session_fflush(cout);
 					break;
 				case DO:
 				case DONT:
-					c = getc(cin);
-					fprintf(cout, "%c%c%c", IAC, WONT, c);
-					(void) fflush(cout);
+					c = session_fgetc(cin);
+					session_fprintf(cout, "%c%c%c", IAC, WONT, c);
+					(void) session_fflush(cout);
 					break;
 				default:
 					break;
@@ -542,7 +518,7 @@
 			(void) getreply(0);
 		}
 		if (data >= 0) {
-			(void) close(data);
+			(void) session_close(data);
 			data = -1;
 		}
 		if (oldintr)
@@ -657,7 +633,7 @@
 		while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
 			bytes += c;
 			for (bufp = buf; c > 0; c -= d, bufp += d)
-				if ((d = write(fileno(dout), bufp, c)) <= 0)
+				if ((d = session_write(fileno(dout), bufp, c)) <= 0)
 					break;
 			if (hash) {
 				while (bytes >= local_hashbytes) {
@@ -683,7 +659,7 @@
 		break;
 
 	case TYPE_A:
-		while ((c = getc(fin)) != EOF) {
+		while ((c = fgetc(fin)) != EOF) {
 			if (c == '\n') {
 				while (hash && (bytes >= local_hashbytes)) {
 					(void) putchar('#');
@@ -692,10 +668,10 @@
 				}
 				if (ferror(dout))
 					break;
-				(void) putc('\r', dout);
+				(void) session_putc('\r', dout);
 				bytes++;
 			}
-			(void) putc(c, dout);
+			(void) session_putc(c, dout);
 			bytes++;
 	/*		if (c == '\r') {			  	*/
 	/*		(void)	putc('\0', dout);  // this violates rfc */
@@ -719,7 +695,7 @@
 	}
 	if (closefunc != NULL)
 		(*closefunc)(fin);
-	(void) fclose(dout);
+	(void) session_fclose(dout);
 	(void) gettimeofday(&stop, (struct timezone *)0);
 	(void) getreply(0);
 	(void) signal(SIGINT, oldintr);
@@ -737,11 +713,11 @@
 		return;
 	}
 	if (data >= 0) {
-		(void) close(data);
+		(void) session_close(data);
 		data = -1;
 	}
 	if (dout)
-		(void) fclose(dout);
+		(void) session_fclose(dout);
 	(void) getreply(0);
 	code = -1;
 	if (closefunc != NULL && fin != NULL)
@@ -800,7 +776,7 @@
 			(void) getreply(0);
 		}
 		if (data >= 0) {
-			(void) close(data);
+			(void) session_close(data);
 			data = -1;
 		}
 		if (oldintr)
@@ -891,7 +867,7 @@
 			return;
 		}
 		errno = d = 0;
-		while ((c = read(fileno(din), buf, bufsize)) > 0) {
+		while ((c = session_read(fileno(din), buf, bufsize)) > 0) {
 			if ((d = write(fileno(fout), buf, c)) != c)
 				break;
 			bytes += c;
@@ -930,7 +906,7 @@
 				goto done;
 			n = restart_point;
 			for (i = 0; i++ < n;) {
-				if ((ch = getc(fout)) == EOF)
+				if ((ch = fgetc(fout)) == EOF)
 					goto done;
 				if (ch == '\n')
 					i++;
@@ -943,7 +919,7 @@
 				return;
 			}
 		}
-		while ((c = getc(din)) != EOF) {
+		while ((c = session_fgetc(din)) != EOF) {
 			if (c == '\n')
 				bare_lfs++;
 			while (c == '\r') {
@@ -953,7 +929,7 @@
 					local_hashbytes += hashbytes;
 				}
 				bytes++;
-				if ((c = getc(din)) != '\n' || tcrflag) {
+				if ((c = session_fgetc(din)) != '\n' || tcrflag) {
 					if (ferror(fout))
 						goto break2;
 					(void) putc('\r', fout);
@@ -994,7 +970,7 @@
 	(void) signal(SIGINT, oldintr);
 	if (oldintp)
 		(void) signal(SIGPIPE, oldintp);
-	(void) fclose(din);
+	(void) session_fclose(din);
 	(void) gettimeofday(&stop, (struct timezone *)0);
 	(void) getreply(0);
 	if (bytes > 0 && is_retr)
@@ -1013,16 +989,13 @@
 		return;
 	}
 
-	abort_remote(din);
+	abort_remote(din, 1);
 	code = -1;
-	if (data >= 0) {
-		(void) close(data);
-		data = -1;
-	}
+
 	if (closefunc != NULL && fout != NULL)
 		(*closefunc)(fout);
 	if (din)
-		(void) fclose(din);
+		(void) session_fclose(din);
 	(void) gettimeofday(&stop, (struct timezone *)0);
 	if (bytes > 0)
 		ptransfer("received", bytes, &start, &stop);
@@ -1100,7 +1073,7 @@
 	if (sendport)
 		data_addr.sin_port = 0;	/* let system pick one */
 	if (data != -1)
-		(void) close(data);
+		(void) session_close(data);
 	data = socket(AF_INET, SOCK_STREAM, 0);
 	if (data < 0) {
 		warn("socket");
@@ -1151,7 +1124,7 @@
 #endif
 	return (0);
 bad:
-	(void) close(data), data = -1;
+	(void) session_close(data), data = -1;
 	if (tmpno)
 		sendport = 1;
 	return (1);
@@ -1164,22 +1137,51 @@
 	struct sockaddr_in from;
 	int s, fromlen = sizeof (from), tos;
 
-	if (passivemode)
+	if (passivemode) {
+#ifdef TLS
+		if (tls_on_data) {
+		    /* disconnect if tls_connect_data() fails */
+		    if (tls_connect_data(data)) {
+			my_sig_t oldsig = signal(SIGPIPE, SIG_IGN);
+			disconnect(0, NULL);
+			fprintf(stdout,
+		            "Failed TLS negotiation on data channel, disconnected\n");
+			signal(SIGPIPE, oldsig);
+			return NULL;
+		    }
+		}
+#endif /* TLS */
 		return (fdopen(data, lmode));
+	}
 
 	s = accept(data, (struct sockaddr *) &from, &fromlen);
 	if (s < 0) {
 		warn("accept");
-		(void) close(data), data = -1;
+		(void) session_close(data), data = -1;
 		return (NULL);
 	}
-	(void) close(data);
+	(void) session_close(data);
 	data = s;
 #if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_THROUGHPUT)
 	tos = IPTOS_THROUGHPUT;
 	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
 		warn("setsockopt TOS (ignored)");
 #endif
+
+#ifdef TLS
+	if (tls_on_data) {
+	    /* disconnect if tls_connect_data() fails */
+	    if (tls_connect_data(data)) {
+		my_sig_t oldsig = signal(SIGPIPE, SIG_IGN);
+		disconnect(0, NULL);
+		fprintf(stdout,
+	            "Failed TLS negotiation on data channel, disconnected\n");
+		signal(SIGPIPE, oldsig);
+		return NULL;
+	    }
+	}
+#endif /* TLS */
+
 	return (fdopen(data, lmode));
 }
 
@@ -1420,7 +1422,7 @@
 		if (command("%s %s", cmd2, local) != PRELIM) {
 			pswitch(0);
 			if (cpend)
-				abort_remote((FILE *) NULL);
+				abort_remote((FILE *) NULL, 0);
 		}
 		pswitch(1);
 		if (ptabflg)
@@ -1429,13 +1431,13 @@
 		return;
 	}
 	if (cpend)
-		abort_remote((FILE *) NULL);
+		abort_remote((FILE *) NULL, 0);
 	pswitch(!proxy);
 	if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */
 		if (command("%s %s", cmd2, local) != PRELIM) {
 			pswitch(0);
 			if (cpend)
-				abort_remote((FILE *) NULL);
+				abort_remote((FILE *) NULL, 0);
 			pswitch(1);
 			if (ptabflg)
 				code = -1;
@@ -1444,7 +1446,7 @@
 		}
 	}
 	if (cpend)
-		abort_remote((FILE *) NULL);
+		abort_remote((FILE *) NULL, 0);
 	pswitch(!proxy);
 	if (cpend) {
 		FD_ZERO(&mask);
@@ -1542,8 +1544,7 @@
 }
 
 void
-abort_remote(din)
-	FILE *din;
+abort_remote( FILE *din, int close_data)
 {
 	char buf[BUFSIZ];
 	int nfnd;
@@ -1554,10 +1555,10 @@
 	 * after urgent byte rather than before as is protocol now
 	 */
 	sprintf(buf, "%c%c%c", IAC, IP, IAC);
-	if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
+	if (session_send(fileno(cout), buf, 3, MSG_OOB) != 3)
 		warn("abort");
-	fprintf(cout,"%cABOR\r\n", DM);
-	(void) fflush(cout);
+	session_fprintf(cout,"%cABOR\r\n", DM);
+	(void) session_fflush(cout);
 	FD_ZERO(&mask);
 	FD_SET(fileno(cin), &mask);
 	if (din) {
@@ -1571,10 +1572,19 @@
 			code = -1;
 		lostpeer();
 	}
+
 	if (din && FD_ISSET(fileno(din), &mask)) {
-		while (read(fileno(din), buf, BUFSIZ) > 0)
+		while (session_read(fileno(din), buf, BUFSIZ) > 0)
 			/* LOOP */;
 	}
+
+	if (close_data && data >= 0) {
+		/* close the data connection.
+		 */
+		(void) session_close(data);
+		data = -1;
+	}
+
 	if (getreply(0) == ERROR && code == 552) {
 		/* 552 needed for nic style abort */
 		(void) getreply(0);
diff --exclude CVS -ur inetutils/ftp/ftp_var.h feg-inetutils/ftp/ftp_var.h
--- inetutils/ftp/ftp_var.h	2000-07-08 03:00:53.000000000 +0200
+++ feg-inetutils/ftp/ftp_var.h	2004-05-28 19:45:53.000000000 +0200
@@ -33,6 +33,7 @@
  * FTP global variables.
  */
 
+#include <config.h>
 #include <sys/param.h>
 #include <setjmp.h>
 
@@ -129,3 +130,13 @@
 FTP_EXTERN int macnum;			/* number of defined macros */
 FTP_EXTERN struct macel macros[16];
 FTP_EXTERN char macbuf[4096];
+
+FTP_EXTERN char* netrc_file;
+
+#ifdef TLS
+FTP_EXTERN int require_tls;
+FTP_EXTERN int tls_on_data;
+#endif
+
+/* sig_t isn't what we expect on all platforms so we use a custom one */
+typedef void (*my_sig_t)__P((int));
diff --exclude CVS -ur inetutils/ftp/main.c feg-inetutils/ftp/main.c
--- inetutils/ftp/main.c	2002-04-29 22:40:30.000000000 +0200
+++ feg-inetutils/ftp/main.c	2004-05-28 19:45:54.000000000 +0200
@@ -58,6 +58,7 @@
 /* Define macro to nothing so declarations in ftp_var.h become definitions. */
 #define FTP_EXTERN
 #include "ftp_var.h"
+#include "session.h"
 
 /* basename (argv[0]).  NetBSD, linux, & gnu libc all define it.  */
 extern char *__progname;
@@ -78,6 +79,7 @@
       fprintf (stdout, "Usage: %s [OPTION...] [HOST [PORT]]\n", __progname);
       puts ("Remote file transfer.\n\n\
   -d, --debug                Turn on debugging mode\n\
+  -A, --active               Turn on active mode ftp\n\
   -g, --no-glob              Turn off file name globbing\n\
   -i, --no-prompt            Don't prompt during multiple-file transfers\n\
   -n, --no-login             Don't automatically login to the remove system\n\
@@ -85,26 +87,48 @@
   -p, --prompt[=PROMPT]      Print a command-line prompt (optionally PROMPT),\n\
                              even if not on a tty\n\
   -v, --verbose              Be verbose\n\
-      --help                 Give this help list\n\
-  -V, --version              Print program version");
+  -h, --help                 Give this help list\n\
+  -V, --version              Print program version"
+#ifdef TLS
+"\n\nTLS options:\n"
+"  -z noprotect               Don't use AUTH TLS by default\n"
+"  -z private                 Use TLS on data channel by default\n"
+"  -z requiretls              Use TLS on control channel or fail\n"
+"  -z compress                Use compression on the TLS channel\n"
+"  -z nosrp                   Don't use the SRP ciphersuites\n"
+"  -z certsok                 Don't do any verification on the server's cert\n"
+"  -z cert=FILE               Use certificate in FILE\n"
+"  -z key=FILE                Use private key in FILE\n"
+"  -z ca=FILE                 Use CA certificate(s) in FILE\n"
+"  -z crl=FILE                Use Certificate Revocation List in FILE\n"
+"  -z pgpcert=FILE            Use OpenPGP key in FILE\n"
+"  -z pgpkey=FILE             Use OpenPGP private key in FILE\n"
+"  -z pgpring=FILE            Use an OpenPGP keyring in FILE\n"
+#endif /* !TLS */
+  
+);
 
       fprintf (stdout, "\nSubmit bug reports to %s.\n", PACKAGE_BUGREPORT);
     }
   exit (err);
 }
 
-static const char *short_options = "dginp::tv";
+static const char *short_options = "dginp::thvz:";
 static struct option long_options[] =
 {
   { "trace", no_argument, 0, 't' },
   { "verbose", no_argument, 0, 'v' },
   { "no-login", no_argument, 0, 'n' },
   { "no-prompt", no_argument, 0, 'i' },
+  { "active", no_argument, 0, 'A' },
   { "debug", no_argument, 0, 'd' },
   { "no-glob", no_argument, 0, 'g' },
-  { "help", no_argument, 0, '&' },
+  { "help", no_argument, 0, 'h' },
   { "prompt", optional_argument, 0, 'p' },
   { "version", no_argument, 0, 'V' },
+#ifdef TLS
+  { "tlsopt", 1, 0, 'z' },
+#endif
   { 0 }
 };
 
@@ -125,6 +149,12 @@
   doglob = 1;
   interactive = 1;
   autologin = 1;
+  passivemode = 1; /* passive mode is activated by default */
+#ifdef TLS
+  require_tls = -1; /* uninitialized */
+  tls_on_data = -1;
+#endif
+  netrc_file = NULL; /* auto detect which file to use */
 
   while ((ch = getopt_long (argc, argv, short_options, long_options, 0))
 	 != EOF)
@@ -143,6 +173,10 @@
 	interactive = 0;
 	break;
 
+      case 'A': /* No passive mode.  */
+	passivemode = 0;
+	break;
+
       case 'n': /* No automatic login.  */
 	autologin = 0;
 	break;
@@ -159,13 +193,19 @@
 	prompt = optarg ? optarg : DEFAULT_PROMPT;
 	break;
 
-      case '&': /* Usage.  */
+      case 'h': /* Usage.  */
 	usage (0);
 	/* Not reached.  */
 
       case 'V': /* Version.  */
 	printf ("ftp (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
 	exit (0);
+#ifdef TLS
+      case 'z':
+	if (tls_optarg(optarg))
+		usage(0);
+	break;
+#endif  /* TLS */
 
       case '?':
       default:
@@ -187,7 +227,6 @@
 
   cpend = 0;	/* no pending replies */
   proxy = 0;	/* proxy not active */
-  passivemode = 0; /* passive mode not active */
   crflag = 1;	/* strip c.r. on ascii gets */
   sendport = -1;	/* not using ports */
   /*
@@ -207,6 +246,7 @@
 	  home = buf;
 	}
     }
+
   if (argc > 0)
     {
       char *xargv[5];
@@ -248,29 +288,59 @@
     {
       if (cout != NULL)
 	{
-	  (void) shutdown (fileno (cout), 1+1);
-	  (void) fclose (cout);
+	  if (sig) {
+	  	/* we do not use the tls functions if we are called as a signal
+	  	 * handler.
+	  	 */
+	  	 (void) shutdown (fileno (cout), 1+1);
+	  	 (void) fclose (cout);
+	  } else {
+	  	(void) session_shutdown (fileno (cout), 1+1);
+	  	(void) session_fclose (cout);
+	  }
 	  cout = NULL;
 	}
       if (data >= 0)
 	{
-	  (void) shutdown (data, 1+1);
-	  (void) close (data);
+	  if (sig) {
+	     (void) shutdown (data, 1+1);
+	     (void) close (data);
+	  } else {
+	     (void) session_shutdown (data, 1+1);
+	     (void) session_close (data);
+	  }
 	  data = -1;
 	}
       connected = 0;
     }
+    /* we must be sure the SSL struct pointers are free'd and cleared,
+     * so we might connect again */
+#ifdef TLS
+     else if (sig == 0)
+	tls_free_ssls();
+#endif
+
   pswitch (1);
   if (connected)
     {
       if (cout != NULL)
 	{
-	  (void) shutdown (fileno(cout), 1+1);
-	  (void) fclose (cout);
+	  if (sig) {
+	     (void) shutdown (fileno(cout), 1+1);
+	     (void) fclose (cout);
+          } else {
+	     (void) session_shutdown (fileno(cout), 1+1);
+	     (void) session_fclose (cout);
+	  }
 	  cout = NULL;
 	}
       connected = 0;
     }
+#ifdef TLS
+      else if (sig == 0)
+	tls_free_ssls();
+#endif /* TLS */
+
   proxflag = 0;
   pswitch (0);
 }
@@ -314,7 +384,7 @@
 	  free (line);
 	  line = 0;
 	}
-      line = readline (prompt);
+      line = (char*) readline (prompt);
       if (!line)
 	quit (0, 0);
       if (line && *line)
diff --exclude CVS -ur inetutils/ftp/Makefile.am feg-inetutils/ftp/Makefile.am
--- inetutils/ftp/Makefile.am	2002-04-28 18:55:32.000000000 +0200
+++ feg-inetutils/ftp/Makefile.am	2004-06-12 23:31:43.000000000 +0200
@@ -4,17 +4,18 @@
 
 EXTRA_PROGRAMS = ftp
 
-ftp_SOURCES = cmds.c cmdtab.c domacro.c ftp.c main.c ruserpass.c
+ftp_SOURCES = cmds.c cmdtab.c domacro.c ftp.c main.c ruserpass.c \
+	tlsutil.h tlsutil.c tlsnetrc.c
 
-noinst_HEADERS = extern.h ftp_var.h
+noinst_HEADERS = extern.h ftp_var.h session.h tlsnetrc.h
 
 man_MANS = ftp.1
 
 @PATHDEFS_MAKE@
 
 INCLUDES = $(PATHDEF_TMP) $(PATHDEF_BSHELL) -I$(top_builddir)/include
-
+AM_CFLAGS = $(LIBGNUTLS_EXTRA_CFLAGS)
 READLINE=@LIBREADLINE@ @LIBTERMCAP@
-LDADD = -L../libinetutils -linetutils $(LIBGLOB) $(READLINE)
+LDADD = -L../libinetutils -linetutils $(LIBGLOB) $(READLINE) $(LIBGNUTLS_EXTRA_LIBS) 
 
 EXTRA_DIST = $(man_MANS)
diff --exclude CVS -ur inetutils/ftp/ruserpass.c feg-inetutils/ftp/ruserpass.c
--- inetutils/ftp/ruserpass.c	2000-08-07 08:17:46.000000000 +0200
+++ feg-inetutils/ftp/ruserpass.c	2004-05-28 19:45:54.000000000 +0200
@@ -52,36 +52,17 @@
 #include <err.h>
 
 #include "ftp_var.h"
+#include "tlsnetrc.h"
 
 extern char *localhost __P((void));
 extern char *xstrdup __P((const char *));
 extern char *xmalloc __P((size_t));
 
-static	int token __P((void));
-static	FILE *cfile;
-
 /* protect agains os headers */
-#undef	DEFAULT
-#define	DEFAULT	1
-#undef	LOGIN
-#define	LOGIN	2
-#undef	PASSWD
-#define	PASSWD	3
-#undef	ACCOUNT
-#define	ACCOUNT 4
-#undef  MACDEF
-#define MACDEF  5
-#undef	ID
-#define	ID	10
-#undef	MACHINE
-#define	MACHINE	11
-
-static char tokval[100];
-
-static struct toktab {
-  char *tokstr;
-  int tval;
-} toktab[]= {
+
+char tokval[100];
+
+toktab_st toktab[]= {
   { "default",	DEFAULT },
   { "login",	LOGIN },
   { "password",	PASSWD },
@@ -89,38 +70,90 @@
   { "account",	ACCOUNT },
   { "machine",	MACHINE },
   { "macdef",	MACDEF },
+  { "ca",	CAFILE },
+  { "crl",	CRLFILE},
+  { "key",	KEY },
+  { "certificate",	CERT },
+  { "pgpcertificate",	PGPCERT },
+  { "pgpkey",	PGPKEY },
+  { "pgpring",	PGPRING },
+  { "requiretls", REQUIRETLS },
+  { "private", PRIVATE },
   { NULL,		0 }
 };
 
-int
-ruserpass(char *host, char **aname, char **apass, char **aacct)
+/* returns true if the given token is in toktab
+ */
+int token_in_tab( const char* token)
 {
-  char *hdir, buf[BUFSIZ], *tmp;
-  char *myname = 0, *mydomain;
-  int t, i, c, usedefault = 0;
-  struct stat stb;
+toktab_st * t;
+
+  for (t = toktab; t->tokstr; t++)
+    if (!strcmp(t->tokstr, token))
+      return 1;
+  
+  return 0;
+}
+
+FILE* netrc_open( char** myname, char** mydomain)
+{
+char *hdir, buf[BUFSIZ];
+FILE* cfile;
+
+  if (netrc_file == NULL)
+  	netrc_file = ".ftprc";
 
   hdir = getenv("HOME");
   if (hdir == NULL)
     hdir = ".";
-  snprintf (buf, sizeof buf, "%s/.netrc", hdir);
+  snprintf (buf, sizeof buf, "%s/%s", hdir, netrc_file);
+
   cfile = fopen(buf, "r");
   if (cfile == NULL)
     {
+      
       if (errno != ENOENT)
-	warn("%s", buf);
-      return (0);
+         warn("%s", buf);
+
+      netrc_file = ".netrc";
+      snprintf (buf, sizeof buf, "%s/%s", hdir, netrc_file);
+      cfile = fopen(buf, "r");
+      
+      if (cfile == NULL) {
+         if (errno != ENOENT)
+  	   warn("%s", buf);
+         return (0);
+      }
     }
+  if (cfile != NULL && verbose > 1)
+     printf("Reading %s file\n", netrc_file);
+
+  *myname = localhost ();
+  if (*myname == NULL)
+	*myname = xstrdup ("");
+  
+  *mydomain = strchr(*myname, '.');
+  if (*mydomain == NULL)
+	    *mydomain = xstrdup ("");
+
+  return cfile;
+
+}
+
+int
+ruserpass(char *host, char **aname, char **apass, char **aacct)
+{
+  char *tmp;
+  char *myname = 0, *mydomain = 0;
+  int t, i, c, usedefault = 0;
+  struct stat stb;
+  FILE* cfile;
+
+  cfile = netrc_open( &myname, &mydomain);
+  if (!cfile) goto bad;
 
-  myname = localhost ();
-  if (! myname)
-    myname = xstrdup ("");
-
-  mydomain = strchr(myname, '.');
-  if (mydomain == NULL)
-    mydomain = xstrdup ("");
  next:
-  while ((t = token()))
+  while ((t = token(cfile))) {
     switch(t)
       {
       case DEFAULT:
@@ -130,7 +163,7 @@
       case MACHINE:
 	if (!usedefault)
 	  {
-	    if (token() != ID)
+	    if (token(cfile) != ID)
 	      continue;
 	    /*
 	     * Allow match either for user's input host name
@@ -153,32 +186,32 @@
 	    continue;
 	  }
       match:
-	while ((t = token()) && t != MACHINE && t != DEFAULT)
+	while ((t = token(cfile)) && t != MACHINE && t != DEFAULT) {
 	  switch(t)
 	    {
 	    case LOGIN:
-	      if (token())
-		if (*aname == 0)
+	      if (token(cfile))
+		if (aname != NULL && *aname == 0)
 		  {
 		    *aname = xmalloc((unsigned) strlen(tokval) + 1);
 		    (void) strcpy(*aname, tokval);
 		  }
 		else
 		  {
-		    if (strcmp(*aname, tokval))
+		    if (aname != NULL && strcmp(*aname, tokval))
 		      goto next;
 		  }
 	      break;
 	    case PASSWD:
-	      if ((*aname == NULL || strcmp(*aname, "anonymous"))
-		  && fstat(fileno(cfile), &stb) >= 0
-		  && (stb.st_mode & 077) != 0)
-		{
-		  warnx("Error: .netrc file is readable by others.");
-		  warnx("Remove password or make file unreadable by others.");
-		  goto bad;
-		}
-	      if (token() && *apass == 0)
+	      if ((aname == NULL || *aname == NULL || strcmp(*aname, "anonymous"))
+		    && fstat(fileno(cfile), &stb) >= 0
+		    && (stb.st_mode & 077) != 0)
+		  {
+		    warnx("Error: %s file is readable by others.", netrc_file);
+		    warnx("Remove password or make file unreadable by others.");
+		    goto bad;
+		  }
+	      if (token(cfile) && apass != NULL && *apass == 0)
 		{
 		  *apass = xmalloc((unsigned) strlen(tokval) + 1);
 		  (void) strcpy(*apass, tokval);
@@ -188,11 +221,11 @@
 	      if (fstat(fileno(cfile), &stb) >= 0
 		  && (stb.st_mode & 077) != 0)
 		{
-		  warnx("Error: .netrc file is readable by others.");
+		  warnx("Error: %s file is readable by others.", netrc_file);
 		  warnx("Remove account or make file unreadable by others.");
 		  goto bad;
 		}
-	      if (token() && *aacct == 0)
+	      if (token(cfile) && aacct != NULL && *aacct == 0)
 		{
 		  *aacct = xmalloc((unsigned) strlen(tokval) + 1);
 		  (void) strcpy(*aacct, tokval);
@@ -270,29 +303,34 @@
 		}
 	      break;
 	    default:
-	      warnx("Unknown .netrc keyword %s", tokval);
+	      if (token_in_tab( tokval)==0)
+	         warnx("Unknown %s keyword %s", tokval, netrc_file);
+	      else
+	         token(cfile); /* read the value and ignore it */
+
 	      break;
 	    }
+	}
 	goto done;
       }
+  }
  done:
   (void) fclose(cfile);
   if (myname)
     free (myname);
   return (0);
  bad:
-  (void) fclose(cfile);
+  if (cfile) fclose(cfile);
   if (myname)
     free (myname);
   return (-1);
 }
 
-static int
-token(void)
+int token(FILE* cfile)
 {
   char *cp;
   int c;
-  struct toktab *t;
+  toktab_st *t;
 
   if (feof(cfile) || ferror(cfile))
     return (0);
Only in feg-inetutils/ftp: session.h
Only in feg-inetutils/ftp: tlsnetrc.c
Only in feg-inetutils/ftp: tlsnetrc.h
Only in feg-inetutils/ftp: tlsutil.c
Only in feg-inetutils/ftp: tlsutil.h
diff --exclude CVS -ur inetutils/headers/Makefile.am feg-inetutils/headers/Makefile.am
--- inetutils/headers/Makefile.am	2004-02-03 20:43:24.000000000 +0100
+++ feg-inetutils/headers/Makefile.am	2004-05-24 22:50:06.000000000 +0200
@@ -1,5 +1,5 @@
 EXTRA_DIST = crypt.h err.h getopt.h obstack.h osockaddr.h paths.h poll.h \
-        syslog-int.h tftpsubs.h confpaths.h.in stamp-h.in
+        syslog-int.h tftpsubs.h confpaths.h.in stamp-h.in shishi_def.h
 
 header_dirs = arpa protocols
 
Only in feg-inetutils/headers: shishi_def.h
Only in feg-inetutils/: libgnutls-extra.m4
diff --exclude CVS -ur inetutils/libinetutils/kcmd.c feg-inetutils/libinetutils/kcmd.c
--- inetutils/libinetutils/kcmd.c	2000-07-06 06:21:07.000000000 +0200
+++ feg-inetutils/libinetutils/kcmd.c	2004-05-24 22:50:06.000000000 +0200
@@ -36,7 +36,7 @@
 #include <config.h>
 #endif
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 
 #include <sys/param.h>
 #include <sys/file.h>
@@ -46,9 +46,14 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+#if defined(KERBEROS)
 #include <kerberosIV/des.h>
 #include <kerberosIV/krb.h>
 #include <kerberosIV/kparse.h>
+#elif defined(SHISHI)
+#include <shishi.h>
+#include "shishi_def.h"
+#endif
 
 #include <ctype.h>
 #include <errno.h>
@@ -66,22 +71,44 @@
 
 #define	START_PORT	5120	 /* arbitrary */
 
+#ifdef SHISHI
+#endif
+
 int	getport __P((int *));
 
+#if defined (KERBEROS)
 int
 kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm,
     cred, schedule, msg_data, laddr, faddr, authopts)
+#elif defined(SHISHI)
+int
+kcmd(h,sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
+     key, laddr, faddr, authopts)
+        Shishi **h;
+#endif
 	int *sock;
 	char **ahost;
 	u_short rport;
-	char *locuser, *remuser, *cmd;
+	char *locuser;
+#if defined (SHISHI)
+	char **remuser;
+#else
+	char *remuser;
+#endif
+	char *cmd;
 	int *fd2p;
+#if defined(KERBEROS)
 	KTEXT ticket;
+#endif
 	char *service;
 	char *realm;
+#if defined(KERBEROS)
 	CREDENTIALS *cred;
 	Key_schedule schedule;
 	MSG_DAT *msg_data;
+#elif defined(SHISHI)
+	Shishi_key **key;
+#endif
 	struct sockaddr_in *laddr, *faddr;
 	long authopts;
 {
@@ -98,6 +125,9 @@
 	int rc;
 	char *host_save;
 	int status;
+#if defined(SHISHI)
+	int zero = 0;
+#endif
 
 	pid = getpid();
 	hp = gethostbyname(*ahost);
@@ -136,6 +166,7 @@
 		bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
 #endif
 		sin.sin_port = rport;
+		
 		if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
 			break;
 		(void) close(s);
@@ -171,6 +202,7 @@
 		if (errno != ECONNREFUSED)
 			perror(hp->h_name);
 		sigsetmask(oldmask);
+		
 		return (-1);
 	}
 	lport--;
@@ -220,6 +252,7 @@
 	/* (void) write(s, locuser, strlen(locuser)+1); */
 
 	/* set up the needed stuff for mutual auth, but only if necessary */
+#ifdef KERBEROS
 	if (authopts & KOPT_DO_MUTUAL) {
 		int sin_len;
 		*faddr = sin;
@@ -231,7 +264,7 @@
 			goto bad2;
 		}
 	}
-#ifdef KERBEROS
+
 	if ((status = krb_sendauth(authopts, s, ticket, service, *ahost,
 			       realm, (unsigned long) getpid(), msg_data,
 			       cred, schedule,
@@ -239,11 +272,32 @@
 			       faddr,
 			       "KCMDV0.1")) != KSUCCESS)
 		goto bad2;
-#endif /* KERBEROS */
+#elif defined(SHISHI)
+	if (authopts & SHISHI_APOPTIONS_MUTUAL_REQUIRED) {
+		int sin_len;
+		*faddr = sin;
+
+		sin_len = sizeof(struct sockaddr_in);
+		if (getsockname(s, (struct sockaddr *)laddr, &sin_len) < 0) {
+			perror("kcmd(getsockname)");
+			status = -1;
+			goto bad2;
+		}
+	}
+
+	if ((status = shishi_auth(h, 0, remuser, *ahost, s, cmd, rport, key, realm)) != SHISHI_OK)
+	  goto bad2;
 
-	(void) write(s, remuser, strlen(remuser)+1);
+#endif /* SHISHI */
+
+	(void) write(s, *remuser, strlen(*remuser)+1);
 	(void) write(s, cmd, strlen(cmd)+1);
 
+#ifdef SHISHI
+	(void) write(s, *remuser, strlen(*remuser)+1);
+	(void) write(s, &zero, sizeof (int));
+#endif 
+
 	if ((rc = read(s, &c, 1)) != 1) {
 		if (rc == -1)
 			perror(*ahost);
@@ -263,7 +317,11 @@
 	}
 	sigsetmask(oldmask);
 	*sock = s;
+#if defined(KERBEROS)
 	return (KSUCCESS);
+#elif defined(SHISHI)
+	return (SHISHI_OK);
+#endif
 bad2:
 	if (lport)
 		(void) close(*fd2p);
diff --exclude CVS -ur inetutils/libinetutils/krcmd.c feg-inetutils/libinetutils/krcmd.c
--- inetutils/libinetutils/krcmd.c	2000-07-06 06:21:07.000000000 +0200
+++ feg-inetutils/libinetutils/krcmd.c	2004-05-24 22:50:06.000000000 +0200
@@ -44,7 +44,7 @@
 #include <config.h>
 #endif
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 #include <sys/types.h>
 #ifdef ENCRYPTION
 #include <sys/socket.h>
@@ -52,16 +52,27 @@
 
 #include <netinet/in.h>
 
+#ifdef KERBEROS
 #include <kerberosIV/des.h>
 #include <kerberosIV/krb.h>
+#elif defined(SHISHI)
+#include <shishi.h>
+#include "shishi_def.h"
+#endif
 
 #include <stdio.h>
 
 #define	SERVICE_NAME	"rcmd"
 
+#if defined(SHISHI)
+int	kcmd __P((Shishi **,int *, char **, u_short, char *, char **, char *, int *,
+	    char *, char *, Shishi_key **, struct sockaddr_in *, 
+	    struct sockaddr_in *, long));
+#else
 int	kcmd __P((int *, char **, u_short, char *, char *, char *, int *,
 	    KTEXT, char *, char *, CREDENTIALS *, Key_schedule, MSG_DAT *,
 	    struct sockaddr_in *, struct sockaddr_in *, long));
+#endif
 
 /*
  * krcmd: simplified version of Athena's "kcmd"
@@ -69,6 +80,46 @@
  *	if fd2p is non-NULL, another socket is filled in for it
  */
 
+#if defined(SHISHI)
+int
+krcmd(h, ahost, rport, remuser, cmd, fd2p, realm)
+        Shishi  **h;
+        char	**ahost;
+	u_short	rport;
+	char	**remuser, *cmd;
+	int	*fd2p;
+	char	*realm;
+{
+	int		sock = -1, err = 0;
+	long		authopts = 0L;
+
+	err = kcmd(
+		h,
+		&sock,
+		ahost,
+		rport,
+		NULL,	/* locuser not used */
+		remuser,
+		cmd,
+		fd2p,
+		SERVICE_NAME,
+		realm,
+		(Shishi_key **) NULL,		/* key schedule not used */
+		(struct sockaddr_in *) NULL,	/* local addr not used */
+		(struct sockaddr_in *) NULL,	/* foreign addr not used */
+		authopts
+	);
+	
+	if (err > SHISHI_OK) {
+	  fprintf(stderr, "krcmd: %s\n", "error");
+		return(-1);
+	}
+	if (err < 0)
+		return(-1);
+	return(sock);
+}
+
+#elif defined(KERBEROS)
 int
 krcmd(ahost, rport, remuser, cmd, fd2p, realm)
 	char	**ahost;
@@ -108,8 +159,53 @@
 		return(-1);
 	return(sock);
 }
+#endif
 
 #ifdef ENCRYPTION
+
+#if defined(SHISHI)
+int
+krcmd_mutual(h, ahost, rport, remuser, cmd, fd2p, realm, key)
+        Shishi          **h;
+        char		**ahost;
+	u_short		rport;
+	char		**remuser, *cmd;
+	int		*fd2p;
+	char		*realm;
+	Shishi_key	**key;
+{
+	int		sock = -1, err = 0;
+	struct sockaddr_in	laddr, faddr;
+	long authopts = SHISHI_APOPTIONS_MUTUAL_REQUIRED;
+
+	err = kcmd(
+		h,
+		&sock,
+		ahost,
+		rport,
+		NULL,	/* locuser not used */
+		remuser,
+		cmd,
+		fd2p,
+		SERVICE_NAME,
+		realm,
+		key,		/* filled in */
+		&laddr,		/* filled in */
+		&faddr,		/* filled in */
+		authopts
+	);
+
+	if (err > SHISHI_OK) {
+	  fprintf(stderr, "krcmd_mutual: %s\n", "error");
+		return(-1);
+	}
+
+	if (err < 0)
+		return (-1);
+	return(sock);
+}
+
+#elif defined(KERBEROS)
 int
 krcmd_mutual(ahost, rport, remuser, cmd, fd2p, realm, cred, sched)
 	char		**ahost;
@@ -156,3 +252,4 @@
 }
 #endif /* CRYPT */
 #endif /* KERBEROS */
+#endif /* KERBEROS */
diff --exclude CVS -ur inetutils/libinetutils/Makefile.am feg-inetutils/libinetutils/Makefile.am
--- inetutils/libinetutils/Makefile.am	2003-04-05 18:43:08.000000000 +0200
+++ feg-inetutils/libinetutils/Makefile.am	2004-05-24 22:50:06.000000000 +0200
@@ -4,7 +4,7 @@
 
 libinetutils_a_SOURCES = argcv.c cleansess.c daemon.c des_rw.c kcmd.c	\
 	krcmd.c localhost.c logwtmpko.c setsig.c tftpsubs.c ttymsg.c	\
-	xmalloc.c xstrdup.c xgetcwd.c utmp_init.c utmp_logout.c
+	xmalloc.c xstrdup.c xgetcwd.c utmp_init.c utmp_logout.c shishi.c
 
 #	memcmp.c memcpy.c memmove.c memset.c
 
Only in feg-inetutils/libinetutils: shishi.c
diff --exclude CVS -ur inetutils/libtelnet/auth.c feg-inetutils/libtelnet/auth.c
--- inetutils/libtelnet/auth.c	2002-12-06 17:10:07.000000000 +0100
+++ feg-inetutils/libtelnet/auth.c	2004-05-21 21:24:25.000000000 +0200
@@ -126,6 +126,24 @@
 				spx_status,
 				spx_printsub },
 #endif
+#ifdef	SHISHI
+	{ AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
+	  krb5shishi_init,
+	  krb5shishi_send,
+	  krb5shishi_is,
+	  krb5shishi_reply,
+	  krb5shishi_status,
+	  krb5shishi_printsub,
+	  krb5shishi_cleanup },
+	{ AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
+	  krb5shishi_init,
+	  krb5shishi_send,
+	  krb5shishi_is,
+	  krb5shishi_reply,
+	  krb5shishi_status,
+	  krb5shishi_printsub,
+	  krb5shishi_cleanup },
+#endif
 #ifdef	KRB5
 # ifdef	ENCRYPTION
 	{ AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
@@ -610,6 +628,8 @@
 	TN_Authenticator *ap;
 	int result;
 {
+	if (ap && ap->cleanup)
+		(*ap->cleanup) (ap);
 	if (!(authenticated = ap))
 		authenticated = &NoAuth;
 	validuser = result;
diff --exclude CVS -ur inetutils/libtelnet/auth.h feg-inetutils/libtelnet/auth.h
--- inetutils/libtelnet/auth.h	2002-12-06 17:09:06.000000000 +0100
+++ feg-inetutils/libtelnet/auth.h	2004-05-21 21:24:16.000000000 +0200
@@ -75,6 +75,7 @@
 	void	(*reply) P((struct XauthP *, unsigned char *, int));
 	int	(*status) P((struct XauthP *, char *, int));
 	void	(*printsub) P((unsigned char *, int, unsigned char *, int));
+	void	(*cleanup) P((struct XauthP *));
 } TN_Authenticator;
 
 #include "auth-proto.h"
diff --exclude CVS -ur inetutils/libtelnet/auth-proto.h feg-inetutils/libtelnet/auth-proto.h
--- inetutils/libtelnet/auth-proto.h	2002-12-06 17:09:06.000000000 +0100
+++ feg-inetutils/libtelnet/auth-proto.h	2004-05-21 21:24:10.000000000 +0200
@@ -89,4 +89,14 @@
 int kerberos5_status P((TN_Authenticator *, char *, int));
 void kerberos5_printsub P((unsigned char *, int, unsigned char *, int));
 #endif
+
+#ifdef	SHISHI
+int krb5shishi_init P((TN_Authenticator *, int));
+int krb5shishi_send P((TN_Authenticator *));
+void krb5shishi_is P((TN_Authenticator *, unsigned char *, int));
+void krb5shishi_reply P((TN_Authenticator *, unsigned char *, int));
+int krb5shishi_status P((TN_Authenticator *, char *, int));
+void krb5shishi_printsub P((unsigned char *, int, unsigned char *, int));
+void krb5shishi_cleanup P((TN_Authenticator *));
+#endif
 #endif
diff --exclude CVS -ur inetutils/libtelnet/enc_des.c feg-inetutils/libtelnet/enc_des.c
--- inetutils/libtelnet/enc_des.c	2000-07-06 06:21:08.000000000 +0200
+++ feg-inetutils/libtelnet/enc_des.c	2004-05-24 22:50:06.000000000 +0200
@@ -37,7 +37,11 @@
 
 #ifdef	ENCRYPTION
 # ifdef	AUTHENTICATION
-#  ifdef DES_ENCRYPTION
+#  if defined (DES_ENCRYPTION) || defined (SHISHI)
+#ifdef SHISHI
+#include <shishi.h>
+extern Shishi * shishi_handle;
+#endif
 #include <arpa/telnet.h>
 #include <stdio.h>
 #ifdef HAVE_STDLIB_H
@@ -74,7 +78,7 @@
 		Block		str_output;
 		Block		str_feed;
 		Block		str_iv;
-		Block		str_ikey;
+	        Block		str_ikey;
 		Schedule	str_sched;
 		int		str_index;
 		int		str_flagshift;
@@ -119,7 +123,18 @@
 void fb64_stream_key P((Block, struct stinfo *));
 int fb64_keyid P((int, unsigned char *, int *, struct fb *));
 
-	void
+#ifdef SHISHI
+void shishi_des_ecb_encrypt (Shishi * h, const char key[8], const char * in, char * out)
+{
+  char * tmp;
+  
+  shishi_des (h, 0, key, NULL, NULL, in, 8, &tmp);
+  memcpy (out, tmp, 8);
+  free (tmp);
+}
+#endif
+
+void
 cfb64_init(server)
 	int server;
 {
@@ -215,9 +230,16 @@
 		/*
 		 * Create a random feed and send it over.
 		 */
+#ifdef SHISHI
+		if (shishi_randomize (shishi_handle, 0,
+				      fbp->temp_feed, 8) != SHISHI_OK)
+		  return(FAILED);
+		
+#else
 		des_new_random_key(fbp->temp_feed);
 		des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
 				fbp->krbdes_sched, 1);
+#endif
 		p = fbp->fb_feed + 3;
 		*p++ = ENCRYPT_IS;
 		p++;
@@ -417,6 +439,7 @@
 {
 
 	if (!key || key->type != SK_DES) {
+	  /* FIXME: Support RFC 2952 approach instead of giving up here. */
 		if (encrypt_debug_mode)
 			printf("Can't set krbdes's session key (%d != %d)\r\n",
 				key ? key->type : -1, SK_DES);
@@ -428,10 +451,14 @@
 	fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]);
 
 	if (fbp->once == 0) {
+#ifndef SHISHI
 		des_set_random_generator_seed(fbp->krbdes_key);
+#endif
 		fbp->once = 1;
 	}
+#ifndef SHISHI
 	des_key_sched(fbp->krbdes_key, fbp->krbdes_sched);
+#endif
 	/*
 	 * Now look to see if krbdes_start() was was waiting for
 	 * the key to show up.  If so, go ahead an call it now
@@ -552,7 +579,9 @@
 	memmove((void *)stp->str_iv, (void *)seed, sizeof(Block));
 	memmove((void *)stp->str_output, (void *)seed, sizeof(Block));
 
+#ifndef SHISHI
 	des_key_sched(stp->str_ikey, stp->str_sched);
+#endif
 
 	stp->str_index = sizeof(Block);
 }
@@ -563,8 +592,9 @@
 	register struct stinfo *stp;
 {
 	memmove((void *)stp->str_ikey, (void *)key, sizeof(Block));
+#ifndef SHISHI
 	des_key_sched(key, stp->str_sched);
-
+#endif
 	memmove((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block));
 
 	stp->str_index = sizeof(Block);
@@ -604,7 +634,12 @@
 	while (c-- > 0) {
 		if (index == sizeof(Block)) {
 			Block b;
+#ifdef SHISHI
+			shishi_des_ecb_encrypt (shishi_handle, fb[CFB].krbdes_key,
+						stp->str_output, b);
+#else
 			des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1);
+#endif
 			memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
 			index = 0;
 		}
@@ -638,7 +673,12 @@
 	index = stp->str_index++;
 	if (index == sizeof(Block)) {
 		Block b;
+#ifdef SHISHI
+		shishi_des_ecb_encrypt (shishi_handle, fb[CFB].krbdes_key,
+					stp->str_output, b);
+#else
 		des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1);
+#endif
 		memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
 		stp->str_index = 1;	/* Next time will be 1 */
 		index = 0;		/* But now use 0 */
@@ -680,7 +720,12 @@
 	while (c-- > 0) {
 		if (index == sizeof(Block)) {
 			Block b;
+#ifdef SHISHI
+			shishi_des_ecb_encrypt (shishi_handle, fb[OFB].krbdes_key,
+						stp->str_feed, b);
+#else
 			des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1);
+#endif
 			memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
 			index = 0;
 		}
@@ -711,7 +756,12 @@
 	index = stp->str_index++;
 	if (index == sizeof(Block)) {
 		Block b;
+#ifdef SHISHI
+		shishi_des_ecb_encrypt (shishi_handle, fb[OFB].krbdes_key,
+					stp->str_feed, b);
+#else
 		des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1);
+#endif
 		memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
 		stp->str_index = 1;	/* Next time will be 1 */
 		index = 0;		/* But now use 0 */
diff --exclude CVS -ur inetutils/libtelnet/encrypt.c feg-inetutils/libtelnet/encrypt.c
--- inetutils/libtelnet/encrypt.c	2000-07-06 06:21:08.000000000 +0200
+++ feg-inetutils/libtelnet/encrypt.c	2004-05-21 21:23:46.000000000 +0200
@@ -104,7 +104,7 @@
 static long remote_supports_decrypt = 0;
 
 static Encryptions encryptions[] = {
-#ifdef	DES_ENCRYPTION
+#if defined (DES_ENCRYPTION) || defined (SHISHI)
     { "DES_CFB64",	ENCTYPE_DES_CFB64,
 			cfb64_encrypt,
 			cfb64_decrypt,
diff --exclude CVS -ur inetutils/libtelnet/encrypt.h feg-inetutils/libtelnet/encrypt.h
--- inetutils/libtelnet/encrypt.h	2000-07-06 06:21:08.000000000 +0200
+++ feg-inetutils/libtelnet/encrypt.h	2004-05-21 21:23:38.000000000 +0200
@@ -94,6 +94,7 @@
 } Encryptions;
 
 #define	SK_DES		1	/* Matched Kerberos v5 KEYTYPE_DES */
+#define	SK_OTHER	2	/* Non-DES key. */
 
 #include "enc-proto.h"
 
diff --exclude CVS -ur inetutils/libtelnet/Makefile.am feg-inetutils/libtelnet/Makefile.am
--- inetutils/libtelnet/Makefile.am	2002-04-08 16:02:39.000000000 +0200
+++ feg-inetutils/libtelnet/Makefile.am	2004-05-21 21:21:46.000000000 +0200
@@ -4,6 +4,6 @@
 
 noinst_LIBRARIES = libtelnet.a
 
-libtelnet_a_SOURCES = auth.c enc_des.c encrypt.c forward.c genget.c getent.c kerberos.c kerberos5.c misc.c read_passwd.c
+libtelnet_a_SOURCES = auth.c enc_des.c encrypt.c forward.c genget.c getent.c kerberos.c kerberos5.c misc.c read_passwd.c shishi.c
 
 noinst_HEADERS = auth-proto.h auth.h enc-proto.h encrypt.h key-proto.h misc-proto.h misc.h
Only in feg-inetutils/libtelnet: shishi.c
diff --exclude CVS -ur inetutils/Makefile.am feg-inetutils/Makefile.am
--- inetutils/Makefile.am	2004-02-03 20:43:09.000000000 +0100
+++ feg-inetutils/Makefile.am	2004-06-12 23:31:56.000000000 +0200
@@ -1,6 +1,7 @@
 AUTOMAKE_OPTIONS = 1.8
 
-EXTRA_DIST = README-alpha paths ChangeLog.0
+EXTRA_DIST = README-alpha paths ChangeLog.0 \
+	README.feg NEWS.feg ChangeLog.feg
 
 SUBDIRS = headers libinetutils libtelnet glob \
 	inetd telnetd libls ftpd rshd rlogind uucpd rexecd syslogd tftpd \
Only in feg-inetutils/: Makefile.feg
Only in feg-inetutils/: NEWS.feg
Only in feg-inetutils/: README.feg
diff --exclude CVS -ur inetutils/rlogin/rlogin.c feg-inetutils/rlogin/rlogin.c
--- inetutils/rlogin/rlogin.c	2003-04-05 18:58:47.000000000 +0200
+++ feg-inetutils/rlogin/rlogin.c	2004-05-24 22:50:06.000000000 +0200
@@ -96,15 +96,35 @@
 #include <varargs.h>
 #endif
 
-#ifdef KERBEROS
-#include <kerberosIV/des.h>
-#include <kerberosIV/krb.h>
+#ifdef SHISHI
+#define REALM_SZ 1040
+#endif
 
+#if defined(KERBEROS) || defined(SHISHI)
+int use_kerberos = 1, doencrypt;
+# ifdef KERBEROS
+# include <kerberosIV/des.h>
+# include <kerberosIV/krb.h>
+char dest_realm_buf[REALM_SZ], *dest_realm = NULL;
 CREDENTIALS cred;
 Key_schedule schedule;
-int use_kerberos = 1, doencrypt;
+
+# elif defined(SHISHI)
+# include <shishi.h>
+# include "shishi_def.h"
 char dest_realm_buf[REALM_SZ], *dest_realm = NULL;
+
+Shishi * handle;
+Shishi_key * key;
+shishi_ivector iv1, iv2;
+shishi_ivector * ivtab[2];
+
+int keytype;
+int keylen;
+int rc;
+int wlen;
 #endif
+#endif /* KERBEROS */
 
 /*
   The TIOCPKT_* macros may not be implemented in the pty driver.
@@ -140,7 +160,7 @@
    terminal.  */
 #define SPEED_NOTATTY	(-1)
 
-int eight, rem;
+int eight=0, rem;
 
 int noescape;
 u_char escapechar = '~';
@@ -170,7 +190,11 @@
 void  lostpeer    __P ((int));
 void  mode        __P ((int));
 void  msg         __P ((const char *));
+#ifdef SHISHI
+void  oob         __P ((char));
+#else
 void  oob         __P ((int));
+#endif
 int   reader      __P ((sigset_t *));
 void  sendwindow  __P ((void));
 void  setsignal   __P ((int));
@@ -182,13 +206,13 @@
 void  writer      __P ((void));
 void  writeroob   __P ((int));
 
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 void  warning    __P ((const char *, ...));
 #endif
 
 extern sig_t setsig __P ((int, sig_t));
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 #define	OPTIONS	"8EKde:k:l:xhV"
 #else
 #define	OPTIONS	"8EKde:l:hV"
@@ -202,7 +226,7 @@
   { "no-escape", no_argument, 0, 'E' },
   { "8-bit", no_argument, 0, '8' },
   { "kerberos", no_argument, 0, 'K' },
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   { "realm", required_argument, 0, 'k' },
   { "encrypt", no_argument, 0, 'x' },
 #endif
@@ -261,7 +285,7 @@
 	  break;
 
 	case 'K':
-#ifdef KERBEROS
+#if defined (KERBEROS) || defined(SHISHI)
 	  use_kerberos = 0;
 #endif
 	  break;
@@ -277,7 +301,7 @@
 	  escapechar = getescape (optarg);
 	  break;
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 	case 'k':
 	  strncpy (dest_realm_buf, optarg, sizeof dest_realm_buf);
 	  /* Make sure it's null termintated.  */
@@ -293,10 +317,12 @@
 	  break;
 
 #ifdef ENCRYPTION
-# ifdef KERBEROS
+# if defined(KERBEROS) || defined (SHISHI)
 	case 'x':
 	  doencrypt = 1;
+# if defined(KERBEROS)
 	  des_set_key (cred.session, schedule);
+#endif
 	  break;
 # endif
 #endif
@@ -344,12 +370,10 @@
 	if (*host == '\0')
 	  usage (1);
       }
-    if (!user)
-      user = pw->pw_name;
   }
 
   sp = NULL;
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   if (use_kerberos)
     {
       sp = getservbyname ((doencrypt ? "eklogin" : "klogin"), "tcp");
@@ -361,7 +385,7 @@
 	}
     }
 #endif
-
+  
   /* Get the port number for the rlogin service.  */
   if (sp == NULL)
     sp = getservbyname ("login", "tcp");
@@ -405,8 +429,8 @@
    */
   setsig (SIGURG, copytochild);
   setsig (SIGUSR1, writeroob);
-
-#ifdef KERBEROS
+  
+#if defined (KERBEROS) || defined(SHISHI)
  try_connect:
   if (use_kerberos)
     {
@@ -417,18 +441,80 @@
       if (hp != NULL && !(host = strdup (hp->h_name)))
 	errx (1, "%s", strerror (ENOMEM));
 
+#if defined (KERBEROS) 
       rem = KSUCCESS;
       errno = 0;
       if (dest_realm == NULL)
 	dest_realm = krb_realmofhost (host);
+#elif defined (SHISHI)
+      rem = SHISHI_OK;
+      errno = 0;
+#endif
 
 # ifdef ENCRYPTION
       if (doencrypt)
+#if defined(SHISHI)
+	{
+	  int i;
+	  
+	  rem = krcmd_mutual (&handle, &host, sp->s_port, &user, term, 0,
+			      dest_realm, &key);
+	  if (rem > 0)
+	    {
+	      keytype = shishi_key_type (key);
+	      keylen = shishi_cipher_blocksize (keytype);		
+      
+	      ivtab[0] = &iv1;
+	      ivtab[1] = &iv2;
+	      
+	      for (i=0; i<2; i++)
+		{
+		  ivtab[i]->ivlen = keylen;
+
+		  switch (keytype)
+		    {
+		    case SHISHI_DES_CBC_CRC:
+		    case SHISHI_DES_CBC_MD4:
+		    case SHISHI_DES_CBC_MD5:
+		    case SHISHI_DES_CBC_NONE:
+		    case SHISHI_DES3_CBC_HMAC_SHA1_KD:
+		      ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES;
+		      ivtab[i]->iv = malloc (ivtab[i]->ivlen);
+		      memset (ivtab[i]->iv, !i, ivtab[i]->ivlen);
+		      ivtab[i]->ctx = shishi_crypto (handle, key, ivtab[i]->keyusage, shishi_key_type (key),
+						     ivtab[i]->iv, ivtab[i]->ivlen);
+		      break;
+		    case SHISHI_ARCFOUR_HMAC:
+		    case SHISHI_ARCFOUR_HMAC_EXP:
+		      ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4*i;
+		      ivtab[i]->ctx = shishi_crypto (handle, key, ivtab[i]->keyusage, shishi_key_type (key),
+						     NULL, 0);
+		      break;
+		    default :  
+		      ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4*i;
+		      ivtab[i]->iv = malloc (ivtab[i]->ivlen);
+		      memset (ivtab[i]->iv, 0, ivtab[i]->ivlen);
+		      ivtab[i]->ctx = shishi_crypto (handle, key, ivtab[i]->keyusage, shishi_key_type (key),
+						     ivtab[i]->iv, ivtab[i]->ivlen);
+		    } 
+		}
+	    }
+	}
+
+      else
+#else
 	rem = krcmd_mutual (&host, sp->s_port, user, term, 0,
 			    dest_realm, &cred, schedule);
       else
+#endif
 #endif /* CRYPT */
-	rem = krcmd (&host, sp->s_port, user, term, 0, dest_realm);
+	
+	rem = krcmd (
+#if defined (SHISHI)
+		     &handle, &host, sp->s_port, &user, term, 0, dest_realm);
+#else
+	             &host, sp->s_port, user, term, 0, dest_realm);
+#endif
       if (rem < 0)
 	{
 	  use_kerberos = 0;
@@ -442,16 +528,22 @@
 	  goto try_connect;
 	}
     }
+  
   else
     {
 # ifdef ENCRYPTION
       if (doencrypt)
 	errx (1, "the -x flag requires Kerberos authentication.");
 #endif /* CRYPT */
+      if (!user)
+	user = pw->pw_name;
+  
       rem = rcmd (&host, sp->s_port, pw->pw_name, user, term, 0);
     }
 #else
-
+  if (!user)
+      user = pw->pw_name;
+  
   rem = rcmd (&host, sp->s_port, pw->pw_name, user, term, 0);
 
 #endif /* KERBEROS */
@@ -598,7 +690,7 @@
     }
   if (child == 0)
     {
-      mode (1);
+      mode (1);      
       if (reader (smask) == 0)
 	{
 	  /* If the reader () return 0, the socket to the server returned an
@@ -635,6 +727,24 @@
      on its end of the network connection.  This should cause the server to
      log you out on the remote system.  */
   msg ("closed connection.");
+
+#ifdef SHISHI
+  if (use_kerberos)
+    {
+      shishi_done (handle);
+#ifdef ENCRYPTION
+      if (doencrypt)
+	{
+	  shishi_key_done (key);
+	  shishi_crypto_close (iv1.ctx);
+	  shishi_crypto_close (iv2.ctx);
+	  free (iv1.iv);
+	  free (iv2.iv);
+	}
+#endif
+    }
+#endif
+  
   done (0);
 }
 
@@ -783,6 +893,10 @@
 	      if (doencrypt)
 		des_write (rem, (char *)&escapechar, 1);
 	      else
+#elif defined(SHISHI)
+	      if (doencrypt)
+		writeenc (handle, rem, (char *)&escapechar, 1, &wlen, &iv2, key, 2);
+	      else
 #endif
 #endif
 		write (rem, &escapechar, 1);
@@ -798,6 +912,16 @@
 	      break;
 	    }
 	} else
+#elif defined(SHISHI)
+      if (doencrypt)
+	{
+          writeenc (handle, rem, &c, 1, &wlen, &iv2, key, 2);
+	  if (wlen == 0)
+	    {
+	      msg ("line gone");
+	      break;
+	    }
+	} else
 #endif
 #endif
 	  if (write (rem, &c, 1) == 0)
@@ -886,6 +1010,10 @@
   if(doencrypt)
     des_write (rem, obuf, sizeof obuf);
   else
+#elif defined(SHISHI)
+  if(doencrypt)
+    writeenc (handle, rem, obuf, sizeof obuf, &wlen, &iv2, key, 2);
+  else
 #endif
 #endif
     write (rem, obuf, sizeof obuf);
@@ -902,16 +1030,26 @@
 int rcvcnt, rcvstate;
 char rcvbuf[8 * 1024];
 
+#if defined(SHISHI)
+void
+oob (char mark)
+{
+  int signo;
+#else
 void
 oob (int signo)
 {
+  char mark;
+#endif
   struct termios tt;
   int atmark, n, out, rcvd;
-  char waste[BUFSIZ], mark;
+  char waste[BUFSIZ];
 
   (void)signo;
   out = O_RDWR;
   rcvd = 0;
+  
+#ifndef SHISHI
   while (recv (rem, &mark, 1, MSG_OOB) < 0)
     {
       switch (errno)
@@ -940,6 +1078,7 @@
 	  return;
 	}
     }
+#endif
   if (mark & TIOCPKT_WINDOW)
     {
       /* Let server know about window size changes */
@@ -1016,17 +1155,26 @@
 
   setsig (SIGTTOU, SIG_IGN);
   setsig (SIGURG, oob);
-
+  
   ppid = getppid ();
   fcntl (rem, F_SETOWN, pid);
   setjmp (rcvtop);
   sigprocmask (SIG_SETMASK, smask, (sigset_t *) 0);
   bufp = rcvbuf;
+  
   for (;;)
     {
+#ifdef SHISHI
+      if ((rcvcnt >= 5) && (bufp[0] == '\377') && (bufp[1] == '\377'))
+	if ((bufp[2] == 'o') && (bufp[3] == 'o'))
+	  {
+	    oob (bufp[4]);
+	    bufp += 5;
+	  }
+#endif
       while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0)
 	{
-	  rcvstate = WRITING;
+	  rcvstate = WRITING; 
 	  n = write (STDOUT_FILENO, bufp, remaining);
 	  if (n < 0)
 	    {
@@ -1045,6 +1193,10 @@
       if (doencrypt)
 	rcvcnt = des_read (rem, rcvbuf, sizeof rcvbuf);
       else
+#elif defined(SHISHI)
+      if (doencrypt)
+	readenc (handle, rem, rcvbuf, &rcvcnt, &iv1, key, 2);
+      else
 #endif
 #endif
 	rcvcnt = read (rem, rcvbuf, sizeof rcvbuf);
@@ -1058,9 +1210,7 @@
 	  return -1;
 	}
     }
-}
-
-void
+}void
 mode (int f)
 {
   struct termios tt;
@@ -1114,7 +1264,7 @@
   fprintf (stderr, "rlogin: %s\r\n", str);
 }
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 /* VARARGS */
 void
 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
@@ -1146,7 +1296,7 @@
     {
       fprintf (stderr,
 	       "Usage: rlogin [ -%s]%s[-e char] [ -l username ] [username@]host\n",
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 # ifdef ENCRYPTION
 	       "8EKx", " [-k realm] "
 # else
@@ -1174,7 +1324,7 @@
                     which is ``~'' by default");
   puts ("\
   -l, --user USER   run as USER on the remote system");
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
       puts ("\
   -K, --kerberos    turns off all Kerberos authentication");
       puts ("\
diff --exclude CVS -ur inetutils/rlogind/rlogind.c feg-inetutils/rlogind/rlogind.c
--- inetutils/rlogind/rlogind.c	2003-04-05 19:03:39.000000000 +0200
+++ feg-inetutils/rlogind/rlogind.c	2004-05-24 22:50:06.000000000 +0200
@@ -101,21 +101,28 @@
 #define TTYDEF_LFLAG	(ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
 #endif
 
+#define AUTH_KERBEROS_SHISHI 1
 #define AUTH_KERBEROS_4 4
 #define AUTH_KERBEROS_5 5
 
-#ifdef KERBEROS
-# define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"
+#if defined(KERBEROS) || defined(SHISHI)
 # ifdef	KRB4
+# define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"
 #  include <kerberosIV/des.h>
 #  include <kerberosIV/krb.h>
 #  define kerberos_error_string(c) krb_err_txt[c]
 #  define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_4
 # elif defined(KRB5)
+# define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"
 #  include <krb5.h>
 #  include <kerberosIV/krb.h>
 #  define kerberos_error_string(c) error_message (c)
 #  define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_5
+# elif defined(SHISHI)
+# define SECURE_MESSAGE "This rlogin session is using encryption for all transmissions.\r\n"
+#  include <shishi.h>
+#  include "shishi_def.h"
+#  define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_SHISHI
 # endif
 #endif /* KERBEROS */
 
@@ -130,6 +137,7 @@
 
 extern int __check_rhosts_file;
 
+#ifndef SHISHI
 struct auth_data
 {
   struct sockaddr_in from;
@@ -148,6 +156,7 @@
 #endif
 #endif
 };
+#endif
 
 static const char *short_options = "aD::d::hk::L:lnp:orxV";
 static struct option long_options[] =
@@ -171,7 +180,7 @@
 int allow_root = 0;
 int verify_hostname = 0;
 int keepalive = 1;
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 int kerberos = 0;
 #ifdef ENCRYPTION
 int encrypt_io = 0;
@@ -199,7 +208,7 @@
 int do_rlogin __P ((int infd, struct auth_data *ap));
 int do_krb_login __P ((int infd, struct auth_data *ap, const char **msg));
 void getstr __P ((int infd, char **ptr, const char *prefix));
-void protocol __P ((int f, int p));
+void protocol __P ((int f, int p, struct auth_data *ap));
 int control __P ((int pty, char *cp, size_t n));
 RETSIGTYPE cleanup __P ((int signo));
 void fatal __P ((int f, const char *msg, int syserr));
@@ -220,26 +229,40 @@
 #define MODE_INETD 0
 #define MODE_DAEMON 1
 
-#if defined(KERBEROS) && defined(ENCRYPTION)
+#if defined(KERBEROS) && defined (ENCRYPTION)
 # define ENCRYPT_IO encrypt_io
 # define IF_ENCRYPT(stmt) if (encrypt_io) stmt
 # define IF_NOT_ENCRYPT(stmt) if (!encrypt_io) stmt
-# define ENC_READ(c, fd, buf, size) \
+# define ENC_READ(c, fd, buf, size, ap) \
  if (encrypt_io) \
      c = des_read(fd, buf, size); \
  else \
      c = read(fd, buf, size);
-# define ENC_WRITE(c, fd, buf, size) \
+# define EN_WRITE(c, fd, buf, size, ap) \
  if (encrypt_io) \
      c = des_write(fd, buf, size); \
  else \
      c = write(fd, buf, size);
+#elif defined(SHISHI) && defined (ENCRYPTION)
+# define ENCRYPT_IO encrypt_io
+# define IF_ENCRYPT(stmt) if (encrypt_io) stmt
+# define IF_NOT_ENCRYPT(stmt) if (!encrypt_io) stmt
+# define ENC_READ(c, fd, buf, size, ap) \
+ if (encrypt_io) \
+     readenc (ap->h, fd, buf, &c, &ap->iv1, ap->enckey, ap->protocol); \
+ else \
+     c = read(fd, buf, size);
+# define ENC_WRITE(c, fd, buf, size, ap) \
+ if (encrypt_io) \
+     writeenc (ap->h, fd, buf, size, &c, &ap->iv2, ap->enckey, ap->protocol); \
+ else \
+     c = write(fd, buf, size);
 #else
 # define ENCRYPT_IO 0
 # define IF_ENCRYPT(stmt)
 # define IF_NOT_ENCRYPT(stmt) stmt
-# define ENC_READ(c, fd, buf, size) c = read (fd, buf, size)
-# define ENC_WRITE(c, fd, buf, size) c = write (fd, buf, size)
+# define ENC_READ(c, fd, buf, size, ap) c = read (fd, buf, size)
+# define ENC_WRITE(c, fd, buf, size, ap) c = write (fd, buf, size)
 #endif
 
 int
@@ -284,7 +307,7 @@
 	  keepalive = 0;
 	  break;
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 	case 'k':
 	  if (optarg)
 	    {
@@ -339,7 +362,7 @@
 
   if (!local_domain_name)
     {
-      char *p = localhost ();
+      char *p = (char *)localhost ();
 
       if (!p)
 	{
@@ -363,6 +386,7 @@
   else
     exit (rlogind_mainloop (fileno (stdin), fileno (stdout)));
 
+  
   /* To pacify lint */
   return 0;
 }
@@ -470,6 +494,9 @@
   struct hostent *hp;
   char *hostname;
   int authenticated = 0;
+#ifdef SHISHI
+  int len, c;
+#endif
 
   confirmed = 0;
 
@@ -506,7 +533,7 @@
 	}
     }
 
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   if (kerberos)
     {
       const char *err_msg;
@@ -566,9 +593,12 @@
       write (fd, "", 1);
       confirmed = 1;		/* we sent the null! */
     }
-
+#ifdef SHISHI
+  len = sizeof (SECURE_MESSAGE) - 1;
+  IF_ENCRYPT (writeenc (ap->h, fd, SECURE_MESSAGE, len, &c, &ap->iv2, ap->enckey, ap->protocol));
+#else
   IF_ENCRYPT (des_write (fd, SECURE_MESSAGE, sizeof (SECURE_MESSAGE) - 1));
-
+#endif
   return authenticated;
 }
 
@@ -728,9 +758,30 @@
   ioctl (master, TIOCPKT, &true);
   netf = infd; /* Needed for cleanup() */
   signal (SIGCHLD, cleanup);
-  protocol (infd, master);
+  protocol (infd, master, &auth_data);
   signal (SIGCHLD, SIG_IGN);
   cleanup (0);
+
+#ifdef SHISHI
+  if (kerberos)
+    {
+      int i;
+      
+      shishi_done (auth_data.h);
+#ifdef ENCRYPTION
+      if (encrypt_io)
+	{
+	  shishi_key_done (auth_data.enckey);
+	  for (i = 0; i < 2; i++)
+	    {
+	      shishi_crypto_close (auth_data.ivtab[i]->ctx);
+	      free (auth_data.ivtab[i]->iv);
+	    }	  
+	}
+#endif
+    }
+#endif
+
   return 0;
 }
 
@@ -765,7 +816,7 @@
   return rc;
 }
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 int
 do_krb_login (int infd, struct auth_data *ap, const char **err_msg)
 {
@@ -776,14 +827,24 @@
   if (kerberos == AUTH_KERBEROS_5)
     rc = do_krb5_login (infd, ap, err_msg);
   else
+#elif defined(SHISHI)
+    if (kerberos == AUTH_KERBEROS_SHISHI)
+      rc = do_shishi_login (infd, ap, err_msg);
+    else
+#else
+      rc = do_krb4_login (infd, ap, err_msg);
 #endif
-    rc = do_krb4_login (infd, ap, err_msg);
-  
+
   if (rc && !err_msg)
+#if defined(SHISHI)
+    *err_msg = shishi_strerror (rc);
+#else
     *err_msg = kerberos_error_string (rc);
+#endif
   return rc;
 }
 
+#ifdef KRB4
 int
 do_krb4_login (int infd, struct auth_data *ap, const char **err_msg)
 {
@@ -859,6 +920,7 @@
 
   return 0;
 }
+#endif
 
 #ifdef KRB5
 int
@@ -958,6 +1020,151 @@
 }
 
 #endif
+
+#ifdef SHISHI
+int
+do_shishi_login (int infd, struct auth_data *ad, const char **err_msg)
+{
+  int rc;
+  int error = 0;
+  int keylen, keytype;
+  struct passwd *pwd = NULL;
+  int cksumtype, cksumlen = 30;
+  char cksum[30];
+  char * compcksum;
+  size_t compcksumlen;
+  char cksumdata[100];
+  struct sockaddr_in sock;
+  size_t socklen = sizeof (struct sockaddr_in);    
+  
+#ifdef ENCRYPTION  
+  rc = get_auth (infd, &ad->h, &ad->ap, &ad->enckey, err_msg, &ad->protocol,
+		 &cksumtype, cksum, &cksumlen);
+#else
+  rc = get_auth (infd, &ad->h, &ad->ap, NULL, err_msg, &ad->protocol,
+		 &cksumtype, cksum, &cksumlen);
+#endif
+  if (rc != SHISHI_OK)
+    return rc;
+
+#ifdef ENCRYPTION
+  /* init IV */
+  if (encrypt_io)
+    {
+      int i;
+      char *iv;
+
+      ad->ivtab[0] = &ad->iv1;
+      ad->ivtab[1] = &ad->iv2;
+
+      keytype = shishi_key_type (ad->enckey);
+      keylen = shishi_cipher_blocksize (keytype);		
+
+      for (i=0; i<2; i++)
+	{
+	  ad->ivtab[i]->ivlen = keylen;
+
+	  switch (keytype)
+	    {
+	    case SHISHI_DES_CBC_CRC:
+	    case SHISHI_DES_CBC_MD4:
+	    case SHISHI_DES_CBC_MD5:
+	    case SHISHI_DES_CBC_NONE:
+	    case SHISHI_DES3_CBC_HMAC_SHA1_KD:
+	      ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES;
+	      ad->ivtab[i]->iv = malloc (ad->ivtab[i]->ivlen);
+	      memset (ad->ivtab[i]->iv, i, ad->ivtab[i]->ivlen);
+	      ad->ivtab[i]->ctx = shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, shishi_key_type (ad->enckey),
+						 ad->ivtab[i]->iv, ad->ivtab[i]->ivlen);
+	      break;
+	    case SHISHI_ARCFOUR_HMAC:
+	    case SHISHI_ARCFOUR_HMAC_EXP:
+	      ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 6 - 4*i;
+	      ad->ivtab[i]->ctx = shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, shishi_key_type (ad->enckey),
+						 NULL, 0);
+	      break;
+	    default :  
+	      ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 6 - 4*i;
+	      ad->ivtab[i]->iv = malloc (ad->ivtab[i]->ivlen);
+	      memset (ad->ivtab[i]->iv, 0, ad->ivtab[i]->ivlen);
+	      if (ad->protocol == 2)
+		ad->ivtab[i]->ctx = shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, shishi_key_type (ad->enckey),
+						   ad->ivtab[i]->iv, ad->ivtab[i]->ivlen);
+	    }	    
+	}
+    }
+#endif
+
+  getstr (infd, &ad->lusername, NULL);
+  getstr (infd, &ad->term, "TERM=");
+  getstr (infd, &ad->rusername, NULL);
+  
+  rc = read (infd, &error, sizeof (int));
+  if ((rc != sizeof (int)) && rc)
+    {
+      free (pwd);
+      return 1;
+    }
+
+  /*
+    getpwnam crash !!!!
+
+  pwd = getpwnam (ad->lusername);
+  if (pwd == NULL)
+    {
+      *err_msg = "getpwnam failed";
+      syslog (LOG_ERR, "getpwnam failed: %m");
+      return 1;
+    }
+  
+  syslog (LOG_INFO | LOG_AUTH,
+	  "%sKerberos V login from %s on %s\n",
+	  (pwd->pw_uid == 0) ? "ROOT " : "",
+	  ad->lusername, ad->hostname);
+  
+  */
+  
+  free (pwd);
+  
+  syslog (LOG_INFO | LOG_AUTH,
+	  "Kerberos V login from %s on %s\n",
+	  ad->lusername, ad->hostname);
+  
+  /* verify checksum */
+
+ if (getsockname (infd, (struct sockaddr *)&sock, &socklen) < 0)
+    {
+      syslog (LOG_ERR, "Can't get sock name");
+      fatal (infd, "Can't get sockname", 1);
+    }
+
+  snprintf (cksumdata, 100, "%u:%s%s", ntohs(sock.sin_port), ad->term + 5, ad->lusername);  
+  rc = shishi_checksum (ad->h, ad->enckey, 0, cksumtype, cksumdata,
+			strlen (cksumdata), &compcksum, &compcksumlen);
+  if ((rc != SHISHI_OK) || (compcksumlen != cksumlen) || (memcmp (compcksum, cksum, cksumlen) != 0))
+    {
+      /* err_msg crash ? */
+      /* *err_msg = "checksum verify failed"; */
+      syslog (LOG_ERR, "checksum verify failed: %s", shishi_error (ad->h));
+      free (compcksum);
+      return 1;
+    }
+
+  free (compcksum);
+
+  rc = shishi_authorized_p (ad->h, shishi_ap_tkt (ad->ap), ad->lusername);
+  if (!rc)
+    {
+      syslog (LOG_ERR, "User is not authorized to log in as: %s", ad->lusername);
+      shishi_ap_done (ad->ap);
+      return 1;
+    }
+
+  shishi_ap_done (ad->ap);
+
+  return SHISHI_OK;
+}
+#endif
 #endif
 
 #define BUFFER_SIZE 128
@@ -1018,9 +1225,12 @@
 
 char magic[2] = {0377, 0377};
 char oobdata[] = {TIOCPKT_WINDOW}; /* May be modified by protocol/control */
+#ifdef SHISHI
+char oobdata_new[] = {0377, 0377, 'o', 'o', TIOCPKT_WINDOW};
+#endif
 
 void
-protocol (int f, int p)
+protocol (int f, int p, struct auth_data *ap)
 {
   char fibuf[1024], *pbp = NULL, *fbp = NULL;
   int pcc = 0, fcc = 0;
@@ -1036,6 +1246,13 @@
    * (our controlling tty is the master pty).
    */
   signal (SIGTTOU, SIG_IGN);
+#ifdef SHISHI
+  if (kerberos && (ap->protocol == 2))
+    {
+      ENC_WRITE (n, f, oobdata_new, 5, ap);
+    }
+  else
+#endif
   send (f, oobdata, 1, MSG_OOB);	/* indicate new rlogin */
   if (f > p)
     nfd = f + 1;
@@ -1107,7 +1324,7 @@
 
       if (FD_ISSET (f, &ibits))
 	{
-	  ENC_READ (fcc, f, fibuf, sizeof (fibuf));
+	  ENC_READ (fcc, f, fibuf, sizeof (fibuf), ap);
 
 	  if (fcc < 0 && errno == EWOULDBLOCK)
 	    fcc = 0;
@@ -1115,7 +1332,7 @@
 	    {
 	      register char *cp;
 	      int left;
-
+	      
 	      if (fcc <= 0)
 		break;
 	      fbp = fibuf;
@@ -1186,7 +1403,7 @@
 
       if ((FD_ISSET (f, &obits)) && pcc > 0)
 	{
-	  ENC_WRITE (cc, f, pbp, pcc);
+	  ENC_WRITE (cc, f, pbp, pcc, ap);
 
 	  if (cc < 0 && errno == EWOULDBLOCK)
 	    {
@@ -1304,8 +1521,8 @@
 "   -l, --no-rhosts         Ignore .rhosts file\n"
 "   -L, --local-domain=NAME Set local domain name\n"
 "   -n, --no-keepalive      Do not set SO_KEEPALIVE\n"
-#ifdef KERBEROS
-"   -k, --kerberos          Use kerberos IV authentication\n"
+#if defined(KERBEROS) || defined(SHISHI)
+"   -k, --kerberos          Use kerberos IV/V authentication\n"
 #ifdef ENCRYPTION
 "   -x, --encrypt           Use DES encryption\n"
 #endif /* ENCRYPTION */
diff --exclude CVS -ur inetutils/rsh/rsh.c feg-inetutils/rsh/rsh.c
--- inetutils/rsh/rsh.c	2003-04-05 18:58:47.000000000 +0200
+++ feg-inetutils/rsh/rsh.c	2004-05-24 22:50:06.000000000 +0200
@@ -70,16 +70,36 @@
 # include <sys/select.h>
 #endif
 
-#ifdef KERBEROS
-#include <kerberosIV/des.h>
-#include <kerberosIV/krb.h>
+#ifdef SHISHI
+#define REALM_SZ 1040
+#endif
 
+#if defined(KERBEROS) || defined(SHISHI)
+int use_kerberos = 1, doencrypt;
+# ifdef KERBEROS
+# include <kerberosIV/des.h>
+# include <kerberosIV/krb.h>
+char dest_realm_buf[REALM_SZ], *dest_realm = NULL;
 CREDENTIALS cred;
 Key_schedule schedule;
-int use_kerberos = 1, doencrypt;
-char dest_realm_buf[REALM_SZ], *dest_realm;
 extern char *krb_realmofhost();
+
+# elif defined(SHISHI)
+# include <shishi.h>
+# include "shishi_def.h"
+char dest_realm_buf[REALM_SZ], *dest_realm = NULL;
+
+Shishi * h;
+Shishi_key * enckey;
+shishi_ivector iv1, iv2, iv3, iv4;
+shishi_ivector * ivtab[4];
+
+int keytype;
+int keylen;
+int rc;
+int wlen;
 #endif
+#endif /* KERBEROS */
 
 /*
  * rsh - remote shell
@@ -95,7 +115,7 @@
 /* basename (argv[0]).  NetBSD, linux, & gnu libc all define it.  */
 extern  char *__progname;
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 #ifdef ENCRYPTION
 #define	OPTIONS	"8Kdek:l:nxVh"
 #else
@@ -113,7 +133,7 @@
   { "8-bit", no_argument, 0, '8' },
   { "kerberos", no_argument, 0, 'K' },
   { "no-input", no_argument, 0, 'n' },
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   { "realm", required_argument, 0, 'k' },
   { "encrypt", no_argument, 0, 'x' },
 #endif
@@ -128,7 +148,7 @@
   fprintf (stream,
 	  "Usage: %s [-nd%s]%s[-l USER] [USER@]HOST [COMMAND [ARG...]]\n",
 	   __progname,
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 #ifdef ENCRYPTION
 	    "x", " [-k REALM] "
 #else
@@ -160,7 +180,7 @@
                     which is ``~'' by default");
   puts ("\
   -l, --user USER   run as USER on the remote system");
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   puts ("\
   -K, --kerberos    turns off all Kerberos authentication");
   puts ("\
@@ -250,12 +270,12 @@
 	  break;
 
 	case 'K':
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 	  use_kerberos = 0;
 #endif
 	  break;
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 	case 'k':
 	  strncpy (dest_realm_buf, optarg, sizeof dest_realm_buf);
 	  dest_realm_buf [REALM_SZ - 1] = '\0';
@@ -265,7 +285,9 @@
 # ifdef ENCRYPTION
 	case 'x':
 	  doencrypt = 1;
+#ifdef KERBEROS
 	  des_set_key (cred.session, schedule);
+#endif
 	  break;
 # endif
 #endif
@@ -329,11 +351,9 @@
 	if (*host == '\0')
 	  usage ();
       }
-    if (!user)
-      user = pw->pw_name;
   }
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 #ifdef ENCRYPTION
   /* -x turns off -n */
   if (doencrypt)
@@ -355,13 +375,24 @@
 		   doencrypt ? "ekshell" : "kshell");
 	}
     }
+#elif defined(SHISHI)
+  if (use_kerberos)
+    {
+      sp = getservbyname ("kshell", "tcp");
+      if (sp == NULL)
+	{
+	  use_kerberos = 0;
+	  warning ("can't get entry for %s/tcp service",
+		   "kshell");
+	}
+    }
 #endif
   if (sp == NULL)
     sp = getservbyname("shell", "tcp");
   if (sp == NULL)
     errx (1, "shell/tcp: unknown service");
 
-#ifdef KERBEROS
+#if defined (KERBEROS) || defined(SHISHI)
  try_connect:
   if (use_kerberos)
     {
@@ -372,19 +403,86 @@
       if (hp != NULL && !(host = strdup (hp->h_name)))
 	err (1, NULL);
 
+#if defined (KERBEROS) 
       rem = KSUCCESS;
       errno = 0;
       if (dest_realm == NULL)
 	dest_realm = krb_realmofhost (host);
+#elif defined (SHISHI)
+      rem = SHISHI_OK;
+      errno = 0;
+#endif
 
 #ifdef ENCRYPTION
       if (doencrypt)
-	rem = krcmd_mutual (&host, sp->s_port, user, args,
-			    &rfd2, dest_realm, &cred, schedule);
+#if defined(SHISHI)
+	{
+	  int i;
+	  char * term;
+	  
+	  term = (char *)xmalloc (strlen(args)+4);
+	  strcpy (term, "-x ");
+	  strcat (term, args);
+	  
+	  rem = krcmd_mutual (&h, &host, sp->s_port, &user, term, &rfd2,
+			      dest_realm, &enckey);
+	  if (rem > 0)
+	    {
+	      keytype = shishi_key_type (enckey);
+	      keylen = shishi_cipher_blocksize (keytype);		
+      
+	      ivtab[0] = &iv1;
+	      ivtab[1] = &iv2;
+	      ivtab[2] = &iv3;
+	      ivtab[3] = &iv4;
+
+	      for (i=0; i<4; i++)
+		{
+		  ivtab[i]->ivlen = keylen;
+	     
+		  switch (keytype)
+		    {
+		    case SHISHI_DES_CBC_CRC:
+		    case SHISHI_DES_CBC_MD4:
+		    case SHISHI_DES_CBC_MD5:
+		    case SHISHI_DES_CBC_NONE:
+		    case SHISHI_DES3_CBC_HMAC_SHA1_KD:
+		      ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES;
+		      ivtab[i]->iv = malloc (ivtab[i]->ivlen);
+		      memset (ivtab[i]->iv, 2*i + 1*(i<2) - 4*(i>=2), ivtab[i]->ivlen);
+		      ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),
+						     ivtab[i]->iv, ivtab[i]->ivlen);
+		      break;
+		    case SHISHI_ARCFOUR_HMAC:
+		    case SHISHI_ARCFOUR_HMAC_EXP:
+		      ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4*i;
+		      ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),
+						     NULL, 0);
+		      break;
+		    default :  
+		      ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4*i;
+		      ivtab[i]->iv = malloc (ivtab[i]->ivlen);
+		      memset (ivtab[i]->iv, 0, ivtab[i]->ivlen);
+		      ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),
+						     ivtab[i]->iv, ivtab[i]->ivlen);
+		    }
+		}
+	    }
+	  free (term);
+	}
+      else
+#else
+	rem = krcmd_mutual (&host, sp->s_port, user, args, &rfd2,
+			    dest_realm, &cred, schedule);
       else
 #endif
-	rem = krcmd (&host, sp->s_port, user, args, &rfd2,
-		     dest_realm);
+#endif
+	rem = krcmd (
+#if defined (SHISHI)
+		     &h, &host, sp->s_port, &user, args, &rfd2, dest_realm);
+#else
+	             &host, sp->s_port, user, args, &rfd2, dest_realm);
+#endif
       if (rem < 0)
 	{
 	  use_kerberos = 0;
@@ -400,11 +498,15 @@
     }
   else
     {
+      if (!user)
+	  user = pw->pw_name;
       if (doencrypt)
 	errx (1, "the -x flag requires Kerberos authentication");
       rem = rcmd (&host, sp->s_port, pw->pw_name, user, args, &rfd2);
     }
 #else
+  if (!user)
+     user = pw->pw_name;
   rem = rcmd (&host, sp->s_port, pw->pw_name, user, args, &rfd2);
 #endif
 
@@ -451,7 +553,7 @@
 	err (1, "fork");
     }
 
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 #ifdef ENCRYPTION
   if (!doencrypt)
 #endif
@@ -464,6 +566,27 @@
 
   talk (nflag, &osigs, pid, rem);
 
+
+#ifdef SHISHI
+  if (use_kerberos)
+    {
+      int i;
+      
+      shishi_done (h);
+#ifdef ENCRYPTION
+      if (doencrypt)
+	{
+	  shishi_key_done (enckey);
+	  for (i = 0; i < 4; i++)
+	    {
+	      shishi_crypto_close (ivtab[i]->ctx);
+	      free (ivtab[i]->iv);
+	    }	  
+	}
+#endif
+    }
+#endif
+
   if (!nflag)
     kill (pid, SIGKILL);
   return 0;
@@ -497,11 +620,15 @@
 	}
       if (!FD_ISSET (rem, &rembits))
 	goto rewrite;
-#ifdef KERBEROS
 #ifdef ENCRYPTION
+#ifdef KERBEROS
       if (doencrypt)
 	wc = des_write (rem, bp, cc);
-      else
+	else
+#elif defined(SHISHI)
+	if (doencrypt)
+     writeenc (h, rem, bp, cc, &wc, &iv3, enckey, 2);
+     else
 #endif
 #endif
 	wc = write (rem, bp, cc);
@@ -550,6 +677,10 @@
 	    cc = des_read (rfd2, buf, sizeof buf);
 	  else
 #endif
+#elif defined(SHISHI) && defined(ENCRYPTION)
+	    if (doencrypt)
+	      readenc (h, rfd2, buf, &cc, &iv2, enckey, 2);
+	  else
 #endif
 	    cc = read (rfd2, buf, sizeof buf);
 	  if (cc <= 0)
@@ -569,6 +700,10 @@
 	    cc = des_read (rem, buf, sizeof buf);
 	  else
 #endif
+#elif defined(SHISHI) && defined(ENCRYPTION)
+	    if (doencrypt)
+	      readenc (h, rem, buf, &cc, &iv1, enckey, 2);
+	  else
 #endif
 	    cc = read (rem, buf, sizeof buf);
 	  if (cc <= 0)
@@ -586,6 +721,7 @@
 sendsig (int sig)
 {
   char signo;
+  int n;
 
   signo = sig;
 #ifdef KERBEROS
@@ -594,11 +730,16 @@
     des_write (rfd2, &signo, 1);
   else
 #endif
+#elif defined(SHISHI) && defined (ENCRYPTION)
+	if (doencrypt)
+     writeenc (h, rfd2, &signo, 1, &n, &iv4, enckey, 2);
+     else
 #endif
+
     write (rfd2, &signo, 1);
 }
 
-#ifdef KERBEROS
+#if defined (KERBEROS) || defined(SHISHI)
 /* VARARGS */
 void
 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
diff --exclude CVS -ur inetutils/rshd/rshd.c feg-inetutils/rshd/rshd.c
--- inetutils/rshd/rshd.c	2002-09-09 11:31:55.000000000 +0200
+++ feg-inetutils/rshd/rshd.c	2004-05-24 22:50:06.000000000 +0200
@@ -111,16 +111,27 @@
 void	 usage __P ((void));
 void     help __P ((void));
 
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
+#ifdef KERBEROS
 # include <kerberosIV/des.h>
 # include <kerberosIV/krb.h>
+Key_schedule	schedule;
+char	authbuf[sizeof(AUTH_DAT)];
+char	tickbuf[sizeof(KTEXT_ST)];
+#elif defined(SHISHI)
+# include <shishi.h>
+# include "shishi_def.h"
+Shishi * h;
+Shishi_ap * ap;
+Shishi_key * enckey;
+shishi_ivector iv1, iv2, iv3, iv4;
+shishi_ivector *ivtab[4];
+int protocol;
+#endif
 # define	VERSION_SIZE	9
 # define SECURE_MESSAGE  "This rsh session is using DES encryption for all transmissions.\r\n"
 # define	OPTIONS		"alnkvxLVh"
-char	authbuf[sizeof(AUTH_DAT)];
-char	tickbuf[sizeof(KTEXT_ST)];
 int	doencrypt, use_kerberos, vacuous;
-Key_schedule	schedule;
 #else
 # define	OPTIONS	"alnLVh"
 #endif
@@ -167,7 +178,7 @@
 	  keepalive = 0; /* don't enable SO_KEEPALIVE */
 	  break;
 
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 	case 'k':
 	  use_kerberos = 1;
 	  break;
@@ -211,7 +222,7 @@
       exit (1);
     }
 
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   if (use_kerberos && vacuous)
     {
       syslog (LOG_ERR, "only one of -k and -v allowed");
@@ -293,6 +304,13 @@
   fd_set		wready, writeto;
 
   fromaddr = *fromp;
+#elif defined SHISHI
+  int n;
+  int		pv1[2], pv2[2];
+  fd_set		wready, writeto;
+  int keytype, keylen;
+  int cksumtype, cksumlen = 30;
+  char cksum[30];
 #endif
 
   signal(SIGINT, SIG_DFL);
@@ -353,7 +371,7 @@
   /* Need host byte ordered port# to compare */
   fromp->sin_port = ntohs((u_short)fromp->sin_port);
   /* Verify that the client's address was bound to a reserved port */
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   if (!use_kerberos)
 #endif
     if (fromp->sin_port >= IPPORT_RESERVED
@@ -406,7 +424,7 @@
 	  syslog (LOG_ERR, "can't get stderr port: %m");
 	  exit (1);
 	}
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
       if (!use_kerberos)
 #endif
 	if (port >= IPPORT_RESERVED || port < IPPORT_RESERVED/2)
@@ -419,6 +437,8 @@
        * client's, just change the port# to the one specified
        * by the clent as the secondary port.
        */
+      syslog (LOG_ERR, "2nd port not reserved %d\n", port);
+
       fromp->sin_port = htons (port);
       if (connect (s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0)
 	{
@@ -427,7 +447,7 @@
 	}
     }
 
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   if (vacuous)
     {
       error ("rshd: remote host requires Kerberos authentication\n");
@@ -458,7 +478,7 @@
        * address corresponds to the name.
        */
       hostname = strdup (hp->h_name);
-#ifdef	KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
       if (!use_kerberos)
 #endif
 	if (check_all || local_domain (hp->h_name))
@@ -544,13 +564,134 @@
 	}
     }
   else
+#elif defined (SHISHI)
+    if (use_kerberos)
+      {
+	int rc;
+	char * err_msg = NULL;
+
+	rc = get_auth (STDIN_FILENO, &h, &ap, &enckey, &err_msg, &protocol,
+		       &cksumtype, cksum, &cksumlen);
+	if (rc != SHISHI_OK)
+	{
+	  error ("Kerberos authentication failure: %s\n", err_msg);
+	  free (err_msg);
+	  exit (1);
+	}
+      }
+  else
 #endif
-    remuser = getstr ("remuser");
+      remuser = getstr ("remuser");
 
   /* Read three strings from the client. */
   locuser = getstr ("locuser");
   cmdbuf = getstr ("command");
 
+#ifdef SHISHI
+ {
+   int error;
+   int rc;
+   char * compcksum;
+   size_t compcksumlen;
+   char cksumdata[100];
+   struct sockaddr_in sock;
+   size_t socklen;    
+
+#ifdef ENCRYPTION
+   if (strlen (cmdbuf) >= 3)
+     if (!strncmp (cmdbuf, "-x ", 3))
+       {
+	 doencrypt = 1;
+	 int i;
+
+	 ivtab[0] = &iv1;
+	 ivtab[1] = &iv2;
+	 ivtab[2] = &iv3;
+	 ivtab[3] = &iv4;
+
+	 keytype = shishi_key_type (enckey);
+	 keylen = shishi_cipher_blocksize (keytype);		
+
+	 for (i=0; i<4; i++)
+	   {
+	     ivtab[i]->ivlen = keylen;
+
+	     switch (keytype)
+	       {
+	       case SHISHI_DES_CBC_CRC:
+	       case SHISHI_DES_CBC_MD4:
+	       case SHISHI_DES_CBC_MD5:
+	       case SHISHI_DES_CBC_NONE:
+	       case SHISHI_DES3_CBC_HMAC_SHA1_KD:
+		 ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES;
+		 ivtab[i]->iv = malloc (ivtab[i]->ivlen);
+		 memset (ivtab[i]->iv, 2*i -3*(i>=2), ivtab[i]->ivlen);
+		 ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),
+						ivtab[i]->iv, ivtab[i]->ivlen);
+		 break;
+	       case SHISHI_ARCFOUR_HMAC:
+	       case SHISHI_ARCFOUR_HMAC_EXP:
+		 ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 4*(i<2) + 2 + 2*(i%2);
+		 ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),
+						NULL, 0);
+		 break;
+	       default :  
+		 ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 4*(i<2) + 2 + 2*(i%2);
+		 ivtab[i]->iv = malloc (ivtab[i]->ivlen);
+		 memset (ivtab[i]->iv, 0, ivtab[i]->ivlen);
+		 if (protocol == 2)
+		   ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),
+						  ivtab[i]->iv, ivtab[i]->ivlen);
+	       }
+	   }
+
+       }
+#endif
+
+   remuser = getstr ("remuser");
+   rc = read (STDIN_FILENO, &error, sizeof (int));
+   if ((rc != sizeof (int)) && rc)
+     {
+       //error ("Kerberos authentication failure: %s\n", err_msg);
+       exit (1);
+     }
+
+   /* verify checksum */
+   
+   /* Doesn't give socket port ? 
+   if (getsockname (STDIN_FILENO, (struct sockaddr *)&sock, &socklen) < 0)
+     {
+       syslog (LOG_ERR, "Can't get sock name");
+       exit (1);
+     }
+   */
+   snprintf (cksumdata, 100, "544:%s%s", /*ntohs(sock.sin_port),*/ cmdbuf, locuser);  
+   rc = shishi_checksum (h, enckey, 0, cksumtype, cksumdata,
+			 strlen (cksumdata), &compcksum, &compcksumlen);
+   if ((rc != SHISHI_OK) || (compcksumlen != cksumlen) || (memcmp (compcksum, cksum, cksumlen) != 0))
+     {
+       /* err_msg crash ? */
+       /* *err_msg = "checksum verify failed"; */
+       syslog (LOG_ERR, "checksum verify failed: %s", shishi_error (h));
+       free (compcksum);
+       exit (1);       
+     }
+
+   rc = shishi_authorized_p (h, shishi_ap_tkt (ap), locuser);
+   if (!rc)
+     {
+       syslog (LOG_ERR, "User is not authorized to log in as: %s", locuser);
+       shishi_ap_done (ap);
+       exit (1);
+     }
+
+   free (compcksum);
+
+   shishi_ap_done (ap);
+
+ }
+#endif
+
   /* Look up locuser in the passerd file.  The locuser has\* to be a
    * valid account on this system.
    */
@@ -580,6 +721,21 @@
 	}
     }
   else
+#elif defined(SHISHI)
+  if (use_kerberos)
+    {/*
+      if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0')
+	{
+	  if (kuserok (kdata, locuser) != 0)
+	    {
+	      syslog (LOG_INFO|LOG_AUTH, "Kerberos rsh denied to %s.%s@%s",
+		      kdata->pname, kdata->pinst, kdata->prealm);
+	      error ("Permission denied.\n");
+	      exit (1);
+	    }
+	    }*/
+    }
+  else
 #endif
     if (errorstr || pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0'
 	&& (iruserok (fromp->sin_addr.s_addr, pwd->pw_uid == 0,
@@ -635,7 +791,7 @@
 	  exit (1);
 	}
 #ifdef ENCRYPTION
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
       if (doencrypt)
 	{
 	  if (pipe (pv1) < 0)
@@ -665,7 +821,7 @@
 	   *         signal.
 	   */
 #ifdef ENCRYPTION
-#ifdef KERBEROS
+#if defined(KERBEROS)
 	  if (doencrypt)
 	    {
 	      static char msg[] = SECURE_MESSAGE;
@@ -674,6 +830,13 @@
 	      des_write (s, msg, sizeof(msg) - 1);
 	    }
 	  else
+#elif defined(SHISHI)
+	  if (doencrypt)
+	    {
+	      close (pv1[1]);
+	      close (pv2[1]);
+	    }
+	  else
 #endif
 #endif
 	    {
@@ -694,7 +857,7 @@
 	  else
 	    nfd = s;
 #ifdef ENCRYPTION
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 	  if (doencrypt)
 	    {
 	      FD_ZERO (&writeto);
@@ -714,10 +877,14 @@
 	    {
 	      ready = readfrom;
 #ifdef ENCRYPTION
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 	      if (doencrypt)
 		{
-		  wready = writeto;
+#ifdef SHISHI
+		  wready = readfrom;
+#else
+                  wready = writeto;
+#endif
 		  if (select (nfd, &ready, &wready, (fd_set *) 0,
 			      (struct timeval *) 0) < 0)
 		    break;
@@ -737,6 +904,10 @@
 		  if (doencrypt)
 		    ret = des_read (s, &sig, 1);
 		  else
+#elif defined(SHISHI)
+		    if (doencrypt)
+		      readenc (h, s, &sig, &ret, &iv2, enckey, protocol);
+		  else
 #endif
 #endif
 		    ret = read (s, &sig, 1);
@@ -761,13 +932,17 @@
 		      if (doencrypt)
 			des_write (s, buf, cc);
 		      else
+#elif defined(SHISHI)
+			if (doencrypt)
+			  writeenc (h, s, buf, cc, &n, &iv4, enckey, protocol);
+		      else
 #endif
 #endif
 			write (s, buf, cc);
 		    }
 		}
 #ifdef ENCRYPTION
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 	      if (doencrypt && FD_ISSET(pv1[0], &ready))
 		{
 		  errno = 0;
@@ -778,13 +953,21 @@
 		      FD_CLR (pv1[0], &readfrom);
 		    }
 		  else
+#ifdef SHISHI
+		    writeenc (h, STDOUT_FILENO, buf, cc, &n, &iv3, enckey, protocol);
+#else
 		    des_write (STDOUT_FILENO, buf, cc);
+#endif
 		}
 
 	      if (doencrypt && FD_ISSET(pv2[0], &wready))
 		{
 		  errno = 0;
+#ifdef SHISHI
+		  readenc (h, STDIN_FILENO, buf, &cc, &iv1, enckey, protocol);
+#else
 		  cc = des_read (STDIN_FILENO, buf, sizeof buf);
+#endif
 		  if (cc <= 0)
 		    {
 		      shutdown (pv2[0], 1+1);
@@ -797,7 +980,7 @@
 #endif
 	    } while (FD_ISSET (s, &readfrom) ||
 #ifdef ENCRYPTION
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
 		     (doencrypt && FD_ISSET (pv1[0], &readfrom)) ||
 #endif
 #endif
@@ -819,7 +1002,7 @@
       close(s); /* control process handles this fd */
       close (pv[0]); /* close read end of pipe */
 #ifdef ENCRYPTION
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
       if (doencrypt)
 	{
 	  close (pv1[0]); close (pv2[0]);
@@ -830,6 +1013,28 @@
 	}
 #endif
 #endif
+
+#if defined(SHISHI)
+  if (use_kerberos)
+    {
+      int i;
+      
+      shishi_done (h);
+#ifdef ENCRYPTION
+      if (doencrypt)
+	{
+	  shishi_key_done (enckey);
+	  for (i = 0; i < 4; i++)
+	    {
+	      shishi_crypto_close (ivtab[i]->ctx);
+	      free (ivtab[i]->iv);
+	    }	  
+	}
+#endif
+    }
+
+#endif
+
       dup2 (pv[1], STDERR_FILENO); /* stderr of shell has to go
 				      pipe to control process */
       close (pv[1]);
@@ -891,7 +1096,12 @@
 	syslog (LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'",
 		remuser, hostname, locuser, cmdbuf);
     }
-  execl (pwd->pw_shell, cp, "-c", cmdbuf, 0);
+#ifdef SHISHI
+  if (doencrypt)
+    execl (pwd->pw_shell, cp, "-c", cmdbuf+3, 0);
+  else
+#endif
+    execl (pwd->pw_shell, cp, "-c", cmdbuf, 0);
   perror (pwd->pw_shell);
   exit (1);
 }
@@ -1042,7 +1252,7 @@
    -L, --log-session       Set local domain name");
   puts ("\
    -n, --no-keepalive      Do not set SO_KEEPALIVE");
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(SHISHI)
   puts ("\
    -k, --kerberos          Use kerberos IV authentication");
 #ifdef ENCRYPTION
