OS/390 openssh

Martin Kraemer Martin.Kraemer at Fujitsu-Siemens.com
Wed Oct 8 19:47:48 EST 2003


Hello Steve, Hello OpenSSH-portable developers,

I am building OpenSSH for our (EBCDIC-based) BS2000 mainframe
operating system, and I noticed you do the same for OS/390.

Because my initial ssh port was based on IBM's OSS port (ssh-1.2.2
or some such), I thought it was fair enough to help with a little
co-operation; we might come up with a unified EBCDIC patch which could
be contributed to the maintainers of the OpenSSH-portable version.

Please find appended the latest diff which we apply to the openssh
portable tree (in this case, 3.7.1p2), and which makes ssh, sshd,
scp, ssh-agent & co work successfully on our BS2000.

At least some of it may be useful to you, although the sftp problems
you mention have not been addressed by us yet either.

OpenSSH-portable developers: do you think this could be added as
a new platform to the portable version? What should be changed to
allow its addition?
I *tried* to make it not-too-ugly, at least... ;-)

Cheers,

   Martin Kraemer
-- 
<Martin.Kraemer at Fujitsu-Siemens.com>         |     Fujitsu Siemens
Fon: +49-89-636-46021, FAX: +49-89-636-47655 | 81730  Munich,  Germany
-------------- next part --------------
diff -bur openssh-3.7.1p2.orig/auth.c openssh-3.7.1p2/auth.c
--- openssh-3.7.1p2.orig/auth.c	Tue Sep  2 23:32:46 2003
+++ openssh-3.7.1p2/auth.c	Tue Oct  7 10:58:33 2003
@@ -300,8 +300,17 @@
 
 #ifdef CUSTOM_FAILED_LOGIN
 	if (authenticated == 0 && strcmp(method, "password") == 0)
+        {
+#if #system(bs2000)
+		record_failed_login_attempt(authctxt->user,
+					    "FAILED LOGIN ATTEMPT FOR USER",
+					    get_remote_ipaddr(),
+					    get_remote_port());
+#else
 		record_failed_login(authctxt->user, "ssh");
 #endif
+	}
+#endif
 }
 
 /*
@@ -524,8 +533,12 @@
 		logit("Illegal user %.100s from %.100s",
 		    user, get_remote_ipaddr());
 #ifdef CUSTOM_FAILED_LOGIN
+#if #system(bs2000)
+		record_failed_login_attempt(user, "ILLEGAL USER", get_remote_ipaddr(), get_remote_port());
+#else
 		record_failed_login(user, "ssh");
 #endif
+#endif
 		return (NULL);
 	}
 	if (!allowed_user(pw))
@@ -610,3 +623,23 @@
 
 	return (&fake);
 }
+
+#if #system(bs2000) && defined(CUSTOM_FAILED_LOGIN)
+#include <bs2cmd.h>
+/*
+ * record_failed_login_attempt: "attempted login failed" interface function
+ */
+void
+record_failed_login_attempt(const char *user, const char *reason, const char *ipaddr, int port)
+{
+  char buf[1024];
+  char cmd[1024];
+  bs2cmd_rc rc;
+  int flags = BS2CMD_FLAG_STRIP;
+
+  snprintf(buf, sizeof buf, "/TYPE  %%  OPENSSH  %s '%s' FROM '[%s]:%d'",
+	   reason, user, ipaddr, port);
+  strnvis(cmd, buf, sizeof(buf), VIS_SAFE|VIS_OCTAL);
+  (void) bs2cmd(cmd, &rc, BS2CMD_DEFAULT, flags);
+}
+#endif
diff -bur openssh-3.7.1p2.orig/auth-passwd.c openssh-3.7.1p2/auth-passwd.c
--- openssh-3.7.1p2.orig/auth-passwd.c	Thu Sep 18 10:26:48 2003
+++ openssh-3.7.1p2/auth-passwd.c	Tue Oct  7 08:21:59 2003
@@ -50,6 +50,18 @@
 
 extern ServerOptions options;
 
+#if #system(bs2000)
+static void str_pad(char *dest, size_t size, char ch)
+{
+    int i = strlen(dest); /* Leave space for trailing '\0' */
+    
+    while (i < size-1)
+	dest[i++] = ch;
+
+    dest[size-1] = '\0';	/* Guarantee for trailing '\0' */
+}
+#endif /*system(bs2000)*/
+
 /*
  * Tries to authenticate the user using password.  Returns true if
  * authentication succeeds.
@@ -72,6 +84,55 @@
 
 #if defined(HAVE_OSF_SIA)
 	return auth_sia_password(authctxt, password) && ok;
+#elif defined(__MVS__)
+        {
+                int rc;
+                rc = __passwd(pw->pw_name, password, NULL);
+                if(rc)
+                    debug("__passwd: %.100s", strerror(errno));
+                return ok && rc == 0;
+        }
+#elif #system(bs2000)
+	{
+		typedef struct {           
+		    char    *username;     
+		    char    *password;     
+		    char    *pw_expdate;   
+		    char    *logon_expdate;
+		    char    *account;      
+		}  _checkuser_struct;      
+		extern int _checkuser(_checkuser_struct *);
+		_checkuser_struct auth_user;
+		char            logon[9];
+		char            passw[9];
+		char            passw_expdate[11];
+		char            logon_expdate[11];
+		char            account_buffer[9];
+		int             ok_pw;
+
+		/* in: */
+		strncpy(logon, pw->pw_name, sizeof logon);
+		strupper(logon, NULL);
+		str_pad(logon, sizeof logon, ' ');
+		auth_user.username = logon;
+		strncpy(passw, password, sizeof passw);
+		strupper(passw, NULL);
+		str_pad(passw, sizeof passw, ' ');
+		auth_user.password = passw;
+		/* out: */
+		auth_user.pw_expdate = passw_expdate;
+		auth_user.logon_expdate = logon_expdate;
+		auth_user.account = account_buffer;
+
+		ok_pw = (_checkuser (&auth_user) == 0);
+
+		if (!ok_pw)
+			debug("Password authentication of user %.100s "
+			      "using BS2000 _checkuser() failed: %.100s",
+			      logon, strerror(errno));
+		return ok && ok_pw;
+	}
+	/*end #system(bs2000) */
 #else
 # ifdef KRB5
 	if (options.kerberos_authentication == 1) {
diff -bur openssh-3.7.1p2.orig/authfd.c openssh-3.7.1p2/authfd.c
--- openssh-3.7.1p2.orig/authfd.c	Thu Jul  3 05:46:56 2003
+++ openssh-3.7.1p2/authfd.c	Tue Oct  7 08:21:59 2003
@@ -336,7 +336,7 @@
 			    BN_num_bits(key->rsa->n), bits);
 		break;
 	case 2:
-		blob = buffer_get_string(&auth->identities, &blen);
+		blob = buffer_get_binary(&auth->identities, &blen);
 		*comment = buffer_get_string(&auth->identities, NULL);
 		key = key_from_blob(blob, blen);
 		xfree(blob);
@@ -430,8 +430,8 @@
 
 	buffer_init(&msg);
 	buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
-	buffer_put_string(&msg, blob, blen);
-	buffer_put_string(&msg, data, datalen);
+	buffer_put_binary(&msg, blob, blen);
+	buffer_put_binary(&msg, data, datalen);
 	buffer_put_int(&msg, flags);
 	xfree(blob);
 
@@ -446,7 +446,7 @@
 		fatal("Bad authentication response: %d", type);
 	} else {
 		ret = 0;
-		*sigp = buffer_get_string(&msg, lenp);
+		*sigp = buffer_get_binary(&msg, lenp);
 	}
 	buffer_free(&msg);
 	return ret;
@@ -573,7 +573,7 @@
 	} else if (key->type == KEY_DSA || key->type == KEY_RSA) {
 		key_to_blob(key, &blob, &blen);
 		buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
-		buffer_put_string(&msg, blob, blen);
+		buffer_put_binary(&msg, blob, blen);
 		xfree(blob);
 	} else {
 		buffer_free(&msg);
diff -bur openssh-3.7.1p2.orig/auth2-hostbased.c openssh-3.7.1p2/auth2-hostbased.c
--- openssh-3.7.1p2.orig/auth2-hostbased.c	Sat Jun 28 04:38:02 2003
+++ openssh-3.7.1p2/auth2-hostbased.c	Tue Oct  7 08:21:59 2003
@@ -60,10 +60,10 @@
 		return 0;
 	}
 	pkalg = packet_get_string(&alen);
-	pkblob = packet_get_string(&blen);
+	pkblob = packet_get_binary(&blen);
 	chost = packet_get_string(NULL);
 	cuser = packet_get_string(NULL);
-	sig = packet_get_string(&slen);
+	sig = packet_get_binary(&slen);
 
 	debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
 	    cuser, chost, pkalg, slen);
@@ -101,7 +101,7 @@
 	buffer_put_cstring(&b, service);
 	buffer_put_cstring(&b, "hostbased");
 	buffer_put_string(&b, pkalg, alen);
-	buffer_put_string(&b, pkblob, blen);
+	buffer_put_binary(&b, pkblob, blen);
 	buffer_put_cstring(&b, chost);
 	buffer_put_cstring(&b, cuser);
 #ifdef DEBUG_PK
diff -bur openssh-3.7.1p2.orig/auth2-pubkey.c openssh-3.7.1p2/auth2-pubkey.c
--- openssh-3.7.1p2.orig/auth2-pubkey.c	Sat Jun 28 04:38:02 2003
+++ openssh-3.7.1p2/auth2-pubkey.c	Tue Oct  7 08:21:59 2003
@@ -65,7 +65,7 @@
 	if (datafellows & SSH_BUG_PKAUTH) {
 		debug2("userauth_pubkey: SSH_BUG_PKAUTH");
 		/* no explicit pkalg given */
-		pkblob = packet_get_string(&blen);
+		pkblob = packet_get_binary(&blen);
 		buffer_init(&b);
 		buffer_append(&b, pkblob, blen);
 		/* so we have to extract the pkalg from the pkblob */
@@ -73,7 +73,7 @@
 		buffer_free(&b);
 	} else {
 		pkalg = packet_get_string(&alen);
-		pkblob = packet_get_string(&blen);
+		pkblob = packet_get_binary(&blen);
 	}
 	pktype = key_type_from_name(pkalg);
 	if (pktype == KEY_UNSPEC) {
@@ -93,13 +93,13 @@
 		goto done;
 	}
 	if (have_sig) {
-		sig = packet_get_string(&slen);
+		sig = packet_get_binary(&slen);
 		packet_check_eom();
 		buffer_init(&b);
 		if (datafellows & SSH_OLD_SESSIONID) {
 			buffer_append(&b, session_id2, session_id2_len);
 		} else {
-			buffer_put_string(&b, session_id2, session_id2_len);
+			buffer_put_binary(&b, session_id2, session_id2_len);
 		}
 		/* reconstruct packet */
 		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
@@ -115,7 +115,7 @@
 			buffer_put_char(&b, have_sig);
 			buffer_put_cstring(&b, pkalg);
 		}
-		buffer_put_string(&b, pkblob, blen);
+		buffer_put_binary(&b, pkblob, blen);
 #ifdef DEBUG_PK
 		buffer_dump(&b);
 #endif
@@ -142,7 +142,7 @@
 		if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
 			packet_start(SSH2_MSG_USERAUTH_PK_OK);
 			packet_put_string(pkalg, alen);
-			packet_put_string(pkblob, blen);
+			packet_put_binary(pkblob, blen);
 			packet_send();
 			packet_write_wait();
 			authctxt->postponed = 1;
diff -bur openssh-3.7.1p2.orig/bufaux.c openssh-3.7.1p2/bufaux.c
--- openssh-3.7.1p2.orig/bufaux.c	Wed May 14 05:40:07 2003
+++ openssh-3.7.1p2/bufaux.c	Tue Oct  7 08:22:00 2003
@@ -126,7 +126,7 @@
 				carry = !++uc[i];
 		}
 	}
-	buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
+	buffer_put_binary(buffer, buf+hasnohigh, bytes-hasnohigh);
 	memset(buf, 0, bytes);
 	xfree(buf);
 }
@@ -136,7 +136,7 @@
 buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
 {
 	u_int len;
-	u_char *bin = buffer_get_string(buffer, &len);
+	u_char *bin = buffer_get_binary(buffer, &len);
 
 	if (len > 8 * 1024)
 		fatal("buffer_get_bignum2: cannot handle BN of size %d", len);
@@ -212,6 +212,36 @@
  * will be stored there.  A null character will be automatically appended
  * to the returned string, and is not counted in length.
  */
+#ifdef CHARSET_EBCDIC
+void *
+buffer_get_binary(Buffer *buffer, u_int *length_ptr)
+{
+	u_char *value;
+	u_int len;
+
+	/* Get the length. */
+	len = buffer_get_int(buffer);
+	if (len > 256 * 1024)
+		fatal("buffer_get_binary: bad length %d", len);
+	/* Allocate space for the object.  Add one byte for a null character. */
+	value = xmalloc(len + 1);
+	/* Get the string. */
+	buffer_get(buffer, value, len);
+	/* Append a null character to make processing easier. */
+	value[len] = 0;
+	/* Optionally return the length of the string. */
+	if (length_ptr)
+		*length_ptr = len;
+	return value;
+}
+void
+buffer_put_binary(Buffer *buffer, const void *buf, u_int len)
+{
+	buffer_put_int(buffer, len);
+	buffer_append(buffer, buf, len);
+}
+#endif
+
 void *
 buffer_get_string(Buffer *buffer, u_int *length_ptr)
 {
@@ -228,6 +258,9 @@
 	buffer_get(buffer, value, len);
 	/* Append a null character to make processing easier. */
 	value[len] = 0;
+#ifdef CHARSET_EBCDIC
+	__atoe_l(value,len);
+#endif
 	/* Optionally return the length of the string. */
 	if (length_ptr)
 		*length_ptr = len;
@@ -241,6 +274,17 @@
 buffer_put_string(Buffer *buffer, const void *buf, u_int len)
 {
 	buffer_put_int(buffer, len);
+#ifdef CHARSET_EBCDIC
+        if (len > 0)
+        {
+            char *cp = xmalloc(len);
+            memcpy (cp, buf, len);
+            __etoa_l(cp, len);
+            buffer_append(buffer, cp, len);
+            xfree(cp);
+	}
+	else
+#endif
 	buffer_append(buffer, buf, len);
 }
 void
diff -bur openssh-3.7.1p2.orig/bufaux.h openssh-3.7.1p2/bufaux.h
--- openssh-3.7.1p2.orig/bufaux.h	Sun Apr 27 20:01:37 2003
+++ openssh-3.7.1p2/bufaux.h	Tue Oct  7 08:22:00 2003
@@ -35,6 +35,13 @@
 int     buffer_get_char(Buffer *);
 void    buffer_put_char(Buffer *, int);
 
+#ifdef CHARSET_EBCDIC
+void   *buffer_get_binary(Buffer *, u_int *);
+void    buffer_put_binary(Buffer *, const void *, u_int);
+#else
+#define buffer_get_binary(_buf,_len) buffer_get_string(_buf,_len)
+#define buffer_put_binary(_buf,_data,_len) buffer_put_string(_buf,_data,_len)
+#endif
 void   *buffer_get_string(Buffer *, u_int *);
 void    buffer_put_string(Buffer *, const void *, u_int);
 void	buffer_put_cstring(Buffer *, const char *);
diff -bur openssh-3.7.1p2.orig/buffer.c openssh-3.7.1p2/buffer.c
--- openssh-3.7.1p2.orig/buffer.c	Tue Sep 23 10:55:43 2003
+++ openssh-3.7.1p2/buffer.c	Tue Oct  7 08:22:00 2003
@@ -170,7 +170,15 @@
 buffer_dump(Buffer *buffer)
 {
 	int i;
+#ifdef CHARSET_EBCDIC
+	unsigned char *ucp;
+
+        ucp = xmalloc(buffer->alloc);
+        memcpy(ucp, buffer->buf, buffer->alloc);
+        __atoe_l(&ucp[buffer->offset], buffer->end - buffer->offset);
+#else
 	u_char *ucp = buffer->buf;
+#endif
 
 	for (i = buffer->offset; i < buffer->end; i++) {
 		fprintf(stderr, "%02x", ucp[i]);
@@ -180,4 +188,7 @@
 			fprintf(stderr, " ");
 	}
 	fprintf(stderr, "\r\n");
+#ifdef CHARSET_EBCDIC
+        xfree(ucp);
+#endif
 }
diff -bur openssh-3.7.1p2.orig/channels.c openssh-3.7.1p2/channels.c
--- openssh-3.7.1p2.orig/channels.c	Tue Sep 16 23:34:12 2003
+++ openssh-3.7.1p2/channels.c	Tue Oct  7 08:22:00 2003
@@ -1752,7 +1752,11 @@
 				packet_start(compat20 ?
 				    SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
 				packet_put_int(c->remote_id);
+				/*if (strcmp(c->ctype, "session") == 0)*/
+				if (c->ctype[0] == 's')
 				packet_put_string(buffer_ptr(&c->input), len);
+				else
+				    packet_put_binary(buffer_ptr(&c->input), len);
 				packet_send();
 				buffer_consume(&c->input, len);
 				c->remote_window -= len;
@@ -1787,7 +1791,11 @@
 			packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA);
 			packet_put_int(c->remote_id);
 			packet_put_int(SSH2_EXTENDED_DATA_STDERR);
+			/*if (strcmp(c->ctype, "session") == 0)*/
+			if (c->ctype[0] == 's')
 			packet_put_string(buffer_ptr(&c->extended), len);
+			else
+			    packet_put_binary(buffer_ptr(&c->extended), len);
 			packet_send();
 			buffer_consume(&c->extended, len);
 			c->remote_window -= len;
@@ -1823,7 +1831,11 @@
 		return;
 
 	/* Get the data. */
+	/*if (strcmp(c->ctype, "session") == 0)*/
+	if (c->ctype[0] == 's')
 	data = packet_get_string(&data_len);
+	else
+	    data = packet_get_binary(&data_len);
 
 	if (compat20) {
 		if (data_len > c->local_maxpacket) {
@@ -1875,7 +1887,11 @@
 		logit("channel %d: bad ext data", c->self);
 		return;
 	}
+	/*if (strcmp(c->ctype, "session") == 0)*/
+	if (c->ctype[0] == 's')
 	data = packet_get_string(&data_len);
+	else
+	    data = packet_get_binary(&data_len);
 	packet_check_eom();
 	if (data_len > c->local_window) {
 		logit("channel %d: rcvd too much extended_data %d, win %d",
diff -bur openssh-3.7.1p2.orig/clientloop.c openssh-3.7.1p2/clientloop.c
--- openssh-3.7.1p2.orig/clientloop.c	Thu Jul  3 05:46:56 2003
+++ openssh-3.7.1p2/clientloop.c	Tue Oct  7 08:22:00 2003
@@ -562,7 +562,11 @@
 				quit_pending = 1;
 				return -1;
 
+#ifdef CHARSET_EBCDIC
+			case '\x3F': /* os_toebcdic[^Z] */
+#else
 			case 'Z' - 64:
+#endif
 				/* Suspend the program. */
 				/* Print a message to that effect to the user. */
 				snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char);
diff -bur openssh-3.7.1p2.orig/contrib/solaris/opensshd.in openssh-3.7.1p2/contrib/solaris/opensshd.in
--- openssh-3.7.1p2.orig/contrib/solaris/opensshd.in	Thu Nov 14 00:50:07 2002
+++ openssh-3.7.1p2/contrib/solaris/opensshd.in	Tue Oct  7 08:22:00 2003
@@ -51,7 +51,23 @@
     checkkeys
 
     # Start SSHD
-    echo "starting $SSHD... \c"         ; $SSHD
+    echo "starting $SSHD... \c"         ; 
+    JOBFILE="\$SYSROOT.TMP.ENTER.OPENSSH-POSIX.$$"
+    LOGFILE="\$SYSROOT.TMP.ENTER.OPENSSH-POSIX.LOG"
+    ftyp text
+    bs2cp - bs2:${JOBFILE} <<.
+/.SSHLOGIN LOGON "SYSROOT",TIME=NTL,PRIORITY=(,EXPRESS)
+/SYSFILE SYSOUT=${LOGFILE}
+/START-POSIX-SHELL
+# Use sh (even if SYSROOT has a different shell)
+sh -c "$SSHD 2>&1 | tee /var/adm/opensshd_startup.log | cat"
+exit
+/SYSFILE SYSOUT=(PRIMARY)
+/ERASE ${LOGFILE}
+/STEP
+/LOGOFF NOSPOOL
+.
+    ${prefix}/sbin/start-sshd-as-sysroot "/ENTER-JOB FROM-FILE=${JOBFILE},DELETE=YES,USER-ID=SYSROOT,ACCOUNT=SYSACC,CPU-LIMIT=NO,START=IMMED"
 
     sshd_rc=$?
     if [ $sshd_rc -ne 0 ]; then
diff -bur openssh-3.7.1p2.orig/defines.h openssh-3.7.1p2/defines.h
--- openssh-3.7.1p2.orig/defines.h	Tue Sep 16 03:52:19 2003
+++ openssh-3.7.1p2/defines.h	Tue Oct  7 08:22:00 2003
@@ -522,7 +522,13 @@
 #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
 #  define __func__ __FUNCTION__
 #elif !defined(HAVE___func__)
-#  define __func__ ""
+# ifdef __STDC__
+#  define __stringize_internal(a)	#a
+#  define __stringize(a)		__stringize_internal(a)
+#  define __func__		__FILE__ ## ":" ## __stringize(__LINE__)
+# else
+#  define __func__ "openssh"
+# endif
 #endif
 
 #if defined(KRB5) && !defined(HEIMDAL)
diff -bur openssh-3.7.1p2.orig/dh.c openssh-3.7.1p2/dh.c
--- openssh-3.7.1p2.orig/dh.c	Wed May 14 05:40:07 2003
+++ openssh-3.7.1p2/dh.c	Tue Oct  7 08:22:00 2003
@@ -210,7 +210,7 @@
 		if (!BN_rand(dh->priv_key, 2*need, 0, 0))
 			fatal("dh_gen_key: BN_rand failed");
 		if (DH_generate_key(dh) == 0)
-			fatal("DH_generate_key");
+			fatal("dh_gen_key: DH_generate_key failed");
 		for (i = 0; i <= BN_num_bits(dh->priv_key); i++)
 			if (BN_is_bit_set(dh->priv_key, i))
 				bits_set++;
diff -bur openssh-3.7.1p2.orig/includes.h openssh-3.7.1p2/includes.h
--- openssh-3.7.1p2.orig/includes.h	Sun Jun 29 13:23:37 2003
+++ openssh-3.7.1p2/includes.h	Tue Oct  7 08:22:00 2003
@@ -110,6 +110,9 @@
 # include <sys/bsdtty.h>
 #endif
 #include <sys/param.h> /* For MAXPATHLEN and roundup() */
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN  64
+#endif 
 #ifdef HAVE_SYS_UN_H
 # include <sys/un.h> /* For sockaddr_un */
 #endif
@@ -135,10 +138,14 @@
 #include <sys/strtio.h>	/* for TIOCCBRK on HP-UX */
 #endif
 
+#if !defined(__MVS__) && !#system(bs2000)
 #include <netinet/in_systm.h> /* For typedefs */
 #include <netinet/in.h> /* For IPv6 macros */
 #include <netinet/ip.h> /* For IPTOS macros */
 #include <netinet/tcp.h>
+#else
+#include <netinet/in.h> /* For IPv6 macros */
+#endif
 #include <arpa/inet.h>
 #if defined(HAVE_NETDB_H)
 # include <netdb.h>
@@ -174,5 +181,32 @@
 #include "openbsd-compat/bsd-nextstep.h"
 
 #include "entropy.h"
+
+#if 'Z' == '\xE9' /* This test is true for all EBCDIC character dialects */
+#define CHARSET_EBCDIC
+#if #system(bs2000)
+#include <ascii_ebcdic.h>
+/* # define IPTOS_THROUGHPUT  0x08 No: setsockopt IPTOS_THROUGHPUT: Option not supported by protocol */
+/* # define IPTOS_LOWDELAY    0x10 No: setsockopt IPTOS_LOWDELAY: Option not supported by protocol */
+#ifndef MAXHOSTNAMELEN
+# ifdef NI_MAXHOST /*1025*/
+#  define MAXHOSTNAMELEN NI_MAXHOST
+#  else
+#  define MAXHOSTNAMELEN  256
+# endif
+#endif
+#define __atoe(_str) _a2e(_str)
+#define __etoa(_str) _e2a(_str)
+#define __etoa_l(_str, _len) _e2a_n(_str, _len)
+#define __atoe_l(_str, _len) _a2e_n(_str, _len)
+#define ASC(ch) _e2a_tab[(unsigned char)ch]
+#define CHR(ch) _a2e_tab[(unsigned char)ch]
+#else /* _OSD_POSIX */
+#error Please define an appropriate CHR() / ASC() macro
+#endif /* _OSD_POSIX */
+#else
+#define ASC(ch) (ch)
+#define CHR(ch) (ch)
+#endif
 
 #endif /* INCLUDES_H */
diff -bur openssh-3.7.1p2.orig/kex.c openssh-3.7.1p2/kex.c
--- openssh-3.7.1p2.orig/kex.c	Tue Apr  1 13:44:37 2003
+++ openssh-3.7.1p2/kex.c	Tue Oct  7 08:22:00 2003
@@ -456,7 +456,7 @@
 	int i, mode, ctos;
 
 	for (i = 0; i < NKEYS; i++)
-		keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret);
+		keys[i] = derive_key(kex, /*ASCII 'A'*/'\x41'+i, kex->we_need, hash, shared_secret);
 
 	debug2("kex_derive_keys");
 	for (mode = 0; mode < MODE_MAX; mode++) {
diff -bur openssh-3.7.1p2.orig/kexdh.c openssh-3.7.1p2/kexdh.c
--- openssh-3.7.1p2.orig/kexdh.c	Mon Feb 24 02:03:03 2003
+++ openssh-3.7.1p2/kexdh.c	Tue Oct  7 08:22:00 2003
@@ -60,7 +60,7 @@
 	buffer_put_char(&b, SSH2_MSG_KEXINIT);
 	buffer_append(&b, skexinit, skexinitlen);
 
-	buffer_put_string(&b, serverhostkeyblob, sbloblen);
+	buffer_put_binary(&b, serverhostkeyblob, sbloblen);
 	buffer_put_bignum2(&b, client_dh_pub);
 	buffer_put_bignum2(&b, server_dh_pub);
 	buffer_put_bignum2(&b, shared_secret);
diff -bur openssh-3.7.1p2.orig/kexdhc.c openssh-3.7.1p2/kexdhc.c
--- openssh-3.7.1p2.orig/kexdhc.c	Mon Feb 24 02:06:32 2003
+++ openssh-3.7.1p2/kexdhc.c	Tue Oct  7 08:22:00 2003
@@ -62,7 +62,7 @@
 	packet_read_expect(SSH2_MSG_KEXDH_REPLY);
 
 	/* key, cert */
-	server_host_key_blob = packet_get_string(&sbloblen);
+	server_host_key_blob = packet_get_binary(&sbloblen);
 	server_host_key = key_from_blob(server_host_key_blob, sbloblen);
 	if (server_host_key == NULL)
 		fatal("cannot decode server_host_key_blob");
@@ -86,7 +86,7 @@
 #endif
 
 	/* signed H */
-	signature = packet_get_string(&slen);
+	signature = packet_get_binary(&slen);
 	packet_check_eom();
 
 	if (!dh_pub_is_valid(dh, dh_server_pub))
diff -bur openssh-3.7.1p2.orig/kexdhs.c openssh-3.7.1p2/kexdhs.c
--- openssh-3.7.1p2.orig/kexdhs.c	Mon Feb 24 02:06:32 2003
+++ openssh-3.7.1p2/kexdhs.c	Tue Oct  7 08:22:00 2003
@@ -122,9 +122,9 @@
 
 	/* send server hostkey, DH pubkey 'f' and singed H */
 	packet_start(SSH2_MSG_KEXDH_REPLY);
-	packet_put_string(server_host_key_blob, sbloblen);
+	packet_put_binary(server_host_key_blob, sbloblen);
 	packet_put_bignum2(dh->pub_key);	/* f */
-	packet_put_string(signature, slen);
+	packet_put_binary(signature, slen);
 	packet_send();
 
 	xfree(signature);
diff -bur openssh-3.7.1p2.orig/kexgex.c openssh-3.7.1p2/kexgex.c
--- openssh-3.7.1p2.orig/kexgex.c	Mon Feb 24 02:03:03 2003
+++ openssh-3.7.1p2/kexgex.c	Tue Oct  7 08:22:01 2003
@@ -62,7 +62,7 @@
 	buffer_put_char(&b, SSH2_MSG_KEXINIT);
 	buffer_append(&b, skexinit, skexinitlen);
 
-	buffer_put_string(&b, serverhostkeyblob, sbloblen);
+	buffer_put_binary(&b, serverhostkeyblob, sbloblen);
 	if (min == -1 || max == -1)
 		buffer_put_int(&b, wantbits);
 	else {
diff -bur openssh-3.7.1p2.orig/kexgexc.c openssh-3.7.1p2/kexgexc.c
--- openssh-3.7.1p2.orig/kexgexc.c	Mon Feb 24 02:06:32 2003
+++ openssh-3.7.1p2/kexgexc.c	Tue Oct  7 08:22:01 2003
@@ -108,7 +108,7 @@
 	packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY);
 
 	/* key, cert */
-	server_host_key_blob = packet_get_string(&sbloblen);
+	server_host_key_blob = packet_get_binary(&sbloblen);
 	server_host_key = key_from_blob(server_host_key_blob, sbloblen);
 	if (server_host_key == NULL)
 		fatal("cannot decode server_host_key_blob");
@@ -132,7 +132,7 @@
 #endif
 
 	/* signed H */
-	signature = packet_get_string(&slen);
+	signature = packet_get_binary(&slen);
 	packet_check_eom();
 
 	if (!dh_pub_is_valid(dh, dh_server_pub))
diff -bur openssh-3.7.1p2.orig/kexgexs.c openssh-3.7.1p2/kexgexs.c
--- openssh-3.7.1p2.orig/kexgexs.c	Mon Feb 24 02:06:32 2003
+++ openssh-3.7.1p2/kexgexs.c	Tue Oct  7 08:22:01 2003
@@ -169,9 +169,9 @@
 	/* send server hostkey, DH pubkey 'f' and singed H */
 	debug("SSH2_MSG_KEX_DH_GEX_REPLY sent");
 	packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
-	packet_put_string(server_host_key_blob, sbloblen);
+	packet_put_binary(server_host_key_blob, sbloblen);
 	packet_put_bignum2(dh->pub_key);	/* f */
-	packet_put_string(signature, slen);
+	packet_put_binary(signature, slen);
 	packet_send();
 
 	xfree(signature);
diff -bur openssh-3.7.1p2.orig/loginrec.c openssh-3.7.1p2/loginrec.c
--- openssh-3.7.1p2.orig/loginrec.c	Sun Jul  6 07:20:46 2003
+++ openssh-3.7.1p2/loginrec.c	Tue Oct  7 08:22:01 2003
@@ -168,6 +168,16 @@
 #   include <libutil.h>
 #endif
 
+#if #system(bs2000) && !defined(_LASTLOG_H)
+/* Define the structure from the missing <lastlog.h> in OSD/POSIX */
+#define _LASTLOG_H
+struct lastlog {
+	time_t	ll_time;
+	char	ll_line[16];
+	char	ll_host[16];		/* same layout as in utmp */
+};
+#endif
+
 /**
  ** prototypes for helper functions in this file
  **/
diff -bur openssh-3.7.1p2.orig/misc.c openssh-3.7.1p2/misc.c
--- openssh-3.7.1p2.orig/misc.c	Tue Sep 23 10:59:08 2003
+++ openssh-3.7.1p2/misc.c	Tue Oct  7 08:22:01 2003
@@ -148,6 +148,11 @@
 
 	memset(copy, 0, sizeof(*copy));
 	copy->pw_name = xstrdup(pw->pw_name);
+#if #system(bs2000)
+	/* Convert the UPPERCASE USER into all lowercase to ease connectivity with unix. */
+	/* IMO that is legitimate, as BS2000's user names are case insensitive */
+        strlower(copy->pw_name, NULL);
+#endif
 	copy->pw_passwd = xstrdup(pw->pw_passwd);
 	copy->pw_gecos = xstrdup(pw->pw_gecos);
 	copy->pw_uid = pw->pw_uid;
diff -bur openssh-3.7.1p2.orig/monitor.c openssh-3.7.1p2/monitor.c
--- openssh-3.7.1p2.orig/monitor.c	Tue Sep  2 23:32:46 2003
+++ openssh-3.7.1p2/monitor.c	Tue Oct  7 08:22:01 2003
@@ -507,7 +507,7 @@
 	debug3("%s", __func__);
 
 	keyid = buffer_get_int(m);
-	p = buffer_get_string(m, &datlen);
+	p = buffer_get_binary(m, &datlen);
 
 	if (datlen != 20)
 		fatal("%s: data length incorrect: %u", __func__, datlen);
@@ -527,7 +527,7 @@
 	debug3("%s: signature %p(%u)", __func__, signature, siglen);
 
 	buffer_clear(m);
-	buffer_put_string(m, signature, siglen);
+	buffer_put_binary(m, signature, siglen);
 
 	xfree(p);
 	xfree(signature);
@@ -574,7 +574,7 @@
 	authctxt->valid = 1;
 
 	buffer_put_char(m, 1);
-	buffer_put_string(m, pwent, sizeof(struct passwd));
+	buffer_put_binary(m, pwent, sizeof(struct passwd));
 	buffer_put_cstring(m, pwent->pw_name);
 	buffer_put_cstring(m, "*");
 	buffer_put_cstring(m, pwent->pw_gecos);
@@ -937,7 +937,7 @@
 	type = buffer_get_int(m);
 	cuser = buffer_get_string(m, NULL);
 	chost = buffer_get_string(m, NULL);
-	blob = buffer_get_string(m, &bloblen);
+	blob = buffer_get_binary(m, &bloblen);
 
 	key = key_from_blob(blob, bloblen);
 
@@ -1021,7 +1021,7 @@
 			fail++;
 		buffer_consume(&b, session_id2_len);
 	} else {
-		p = buffer_get_string(&b, &len);
+		p = buffer_get_binary(&b, &len);
 		if ((session_id2 == NULL) ||
 		    (len != session_id2_len) ||
 		    (memcmp(p, session_id2, session_id2_len) != 0))
@@ -1069,7 +1069,7 @@
 	buffer_init(&b);
 	buffer_append(&b, data, datalen);
 
-	p = buffer_get_string(&b, &len);
+	p = buffer_get_binary(&b, &len);
 	if ((session_id2 == NULL) ||
 	    (len != session_id2_len) ||
 	    (memcmp(p, session_id2, session_id2_len) != 0))
@@ -1122,9 +1122,9 @@
 	int verified = 0;
 	int valid_data = 0;
 
-	blob = buffer_get_string(m, &bloblen);
-	signature = buffer_get_string(m, &signaturelen);
-	data = buffer_get_string(m, &datalen);
+	blob = buffer_get_binary(m, &bloblen);
+	signature = buffer_get_binary(m, &signaturelen);
+	data = buffer_get_binary(m, &datalen);
 
 	if (hostbased_cuser == NULL || hostbased_chost == NULL ||
 	  !monitor_allowed_key(blob, bloblen))
@@ -1361,7 +1361,7 @@
 		key->type = KEY_RSA;	/* cheat for key_to_blob */
 		if (key_to_blob(key, &blob, &blen) == 0)
 			fatal("%s: key_to_blob failed", __func__);
-		buffer_put_string(m, blob, blen);
+		buffer_put_binary(m, blob, blen);
 
 		/* Save temporarily for comparison in verify */
 		key_blob = blob;
@@ -1391,7 +1391,7 @@
 
 	if (!authctxt->valid)
 		fatal("%s: authctxt not valid", __func__);
-	blob = buffer_get_string(m, &blen);
+	blob = buffer_get_binary(m, &blen);
 	if (!monitor_allowed_key(blob, blen))
 		fatal("%s: bad key, not previously allowed", __func__);
 	if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
@@ -1431,14 +1431,14 @@
 	if (ssh1_challenge == NULL)
 		fatal("%s: no ssh1_challenge", __func__);
 
-	blob = buffer_get_string(m, &blen);
+	blob = buffer_get_binary(m, &blen);
 	if (!monitor_allowed_key(blob, blen))
 		fatal("%s: bad key, not previously allowed", __func__);
 	if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
 		fatal("%s: key type mismatch: %d", __func__, key_blobtype);
 	if ((key = key_from_blob(blob, blen)) == NULL)
 		fatal("%s: received bad key", __func__);
-	response = buffer_get_string(m, &len);
+	response = buffer_get_binary(m, &len);
 	if (len != 16)
 		fatal("%s: received bad response to challenge", __func__);
 	success = auth_rsa_verify_response(key, ssh1_challenge, response);
@@ -1550,11 +1550,11 @@
 	kex->server = 1;
 	kex->hostkey_type = buffer_get_int(m);
 	kex->kex_type = buffer_get_int(m);
-	blob = buffer_get_string(m, &bloblen);
+	blob = buffer_get_binary(m, &bloblen);
 	buffer_init(&kex->my);
 	buffer_append(&kex->my, blob, bloblen);
 	xfree(blob);
-	blob = buffer_get_string(m, &bloblen);
+	blob = buffer_get_binary(m, &bloblen);
 	buffer_init(&kex->peer);
 	buffer_append(&kex->peer, blob, bloblen);
 	xfree(blob);
@@ -1586,23 +1586,23 @@
 	if (!compat20) {
 		child_state.ssh1protoflags = buffer_get_int(&m);
 		child_state.ssh1cipher = buffer_get_int(&m);
-		child_state.ssh1key = buffer_get_string(&m,
+		child_state.ssh1key = buffer_get_binary(&m,
 		    &child_state.ssh1keylen);
-		child_state.ivout = buffer_get_string(&m,
+		child_state.ivout = buffer_get_binary(&m,
 		    &child_state.ivoutlen);
-		child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);
+		child_state.ivin = buffer_get_binary(&m, &child_state.ivinlen);
 		goto skip;
 	} else {
 		/* Get the Kex for rekeying */
 		*pmonitor->m_pkex = mm_get_kex(&m);
 	}
 
-	blob = buffer_get_string(&m, &bloblen);
+	blob = buffer_get_binary(&m, &bloblen);
 	current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
 	xfree(blob);
 
 	debug3("%s: Waiting for second key", __func__);
-	blob = buffer_get_string(&m, &bloblen);
+	blob = buffer_get_binary(&m, &bloblen);
 	current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
 	xfree(blob);
 
@@ -1618,18 +1618,18 @@
 
  skip:
 	/* Get the key context */
-	child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);
-	child_state.keyin  = buffer_get_string(&m, &child_state.keyinlen);
+	child_state.keyout = buffer_get_binary(&m, &child_state.keyoutlen);
+	child_state.keyin  = buffer_get_binary(&m, &child_state.keyinlen);
 
 	debug3("%s: Getting compression state", __func__);
 	/* Get compression state */
-	p = buffer_get_string(&m, &plen);
+	p = buffer_get_binary(&m, &plen);
 	if (plen != sizeof(child_state.outgoing))
 		fatal("%s: bad request size", __func__);
 	memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));
 	xfree(p);
 
-	p = buffer_get_string(&m, &plen);
+	p = buffer_get_binary(&m, &plen);
 	if (plen != sizeof(child_state.incoming))
 		fatal("%s: bad request size", __func__);
 	memcpy(&child_state.incoming, p, sizeof(child_state.incoming));
@@ -1637,8 +1637,8 @@
 
 	/* Network I/O buffers */
 	debug3("%s: Getting Network I/O buffers", __func__);
-	child_state.input = buffer_get_string(&m, &child_state.ilen);
-	child_state.output = buffer_get_string(&m, &child_state.olen);
+	child_state.input = buffer_get_binary(&m, &child_state.ilen);
+	child_state.output = buffer_get_binary(&m, &child_state.olen);
 
 	buffer_free(&m);
 }
@@ -1699,6 +1699,10 @@
 }
 
 #define MM_MEMSIZE	65536
+#if #system(bs2000)
+#undef MM_MEMSIZE
+#define MM_MEMSIZE      16384 /* 16 kB */
+#endif
 
 struct monitor *
 monitor_init(void)
diff -bur openssh-3.7.1p2.orig/monitor_wrap.c openssh-3.7.1p2/monitor_wrap.c
--- openssh-3.7.1p2.orig/monitor_wrap.c	Tue Sep  2 14:51:17 2003
+++ openssh-3.7.1p2/monitor_wrap.c	Tue Oct  7 08:22:01 2003
@@ -165,13 +165,13 @@
 
 	buffer_init(&m);
 	buffer_put_int(&m, kex->host_key_index(key));
-	buffer_put_string(&m, data, datalen);
+	buffer_put_binary(&m, data, datalen);
 
 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
 
 	debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
-	*sigp  = buffer_get_string(&m, lenp);
+	*sigp  = buffer_get_binary(&m, lenp);
 	buffer_free(&m);
 
 	return (0);
@@ -198,7 +198,7 @@
 		buffer_free(&m);
 		return (NULL);
 	}
-	pw = buffer_get_string(&m, &pwlen);
+	pw = buffer_get_binary(&m, &pwlen);
 	if (pwlen != sizeof(struct passwd))
 		fatal("%s: struct passwd size mismatch", __func__);
 	pw->pw_name = buffer_get_string(&m, NULL);
@@ -331,7 +331,7 @@
 	buffer_put_int(&m, type);
 	buffer_put_cstring(&m, user ? user : "");
 	buffer_put_cstring(&m, host ? host : "");
-	buffer_put_string(&m, blob, len);
+	buffer_put_binary(&m, blob, len);
 	xfree(blob);
 
 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
@@ -375,9 +375,9 @@
 		return (0);
 
 	buffer_init(&m);
-	buffer_put_string(&m, blob, len);
-	buffer_put_string(&m, sig, siglen);
-	buffer_put_string(&m, data, datalen);
+	buffer_put_binary(&m, blob, len);
+	buffer_put_binary(&m, sig, siglen);
+	buffer_put_binary(&m, data, datalen);
 	xfree(blob);
 
 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
@@ -420,8 +420,8 @@
 	buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
 	enc->enabled = buffer_get_int(&b);
 	enc->block_size = buffer_get_int(&b);
-	enc->key = buffer_get_string(&b, &enc->key_len);
-	enc->iv = buffer_get_string(&b, &len);
+	enc->key = buffer_get_binary(&b, &enc->key_len);
+	enc->iv = buffer_get_binary(&b, &len);
 	if (len != enc->block_size)
 		fatal("%s: bad ivlen: expected %u != %u", __func__,
 		    enc->block_size, len);
@@ -435,7 +435,7 @@
 	if (mac->name == NULL || mac_init(mac, mac->name) == -1)
 		fatal("%s: can not init mac %s", __func__, mac->name);
 	mac->enabled = buffer_get_int(&b);
-	mac->key = buffer_get_string(&b, &len);
+	mac->key = buffer_get_binary(&b, &len);
 	if (len > mac->key_len)
 		fatal("%s: bad mac key length: %u > %d", __func__, len,
 		    mac->key_len);
@@ -480,14 +480,14 @@
 	buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
 	buffer_put_int(&b, enc->enabled);
 	buffer_put_int(&b, enc->block_size);
-	buffer_put_string(&b, enc->key, enc->key_len);
+	buffer_put_binary(&b, enc->key, enc->key_len);
 	packet_get_keyiv(mode, enc->iv, enc->block_size);
-	buffer_put_string(&b, enc->iv, enc->block_size);
+	buffer_put_binary(&b, enc->iv, enc->block_size);
 
 	/* Mac structure */
 	buffer_put_cstring(&b, mac->name);
 	buffer_put_int(&b, mac->enabled);
-	buffer_put_string(&b, mac->key, mac->key_len);
+	buffer_put_binary(&b, mac->key, mac->key_len);
 
 	/* Comp structure */
 	buffer_put_int(&b, comp->type);
@@ -544,16 +544,16 @@
 		keylen = packet_get_encryption_key(NULL);
 		key = xmalloc(keylen+1);	/* add 1 if keylen == 0 */
 		keylen = packet_get_encryption_key(key);
-		buffer_put_string(&m, key, keylen);
+		buffer_put_binary(&m, key, keylen);
 		memset(key, 0, keylen);
 		xfree(key);
 
 		ivlen = packet_get_keyiv_len(MODE_OUT);
 		packet_get_keyiv(MODE_OUT, iv, ivlen);
-		buffer_put_string(&m, iv, ivlen);
+		buffer_put_binary(&m, iv, ivlen);
 		ivlen = packet_get_keyiv_len(MODE_OUT);
 		packet_get_keyiv(MODE_IN, iv, ivlen);
-		buffer_put_string(&m, iv, ivlen);
+		buffer_put_binary(&m, iv, ivlen);
 		goto skip;
 	} else {
 		/* Kex for rekeying */
@@ -567,13 +567,13 @@
 	if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
 		fatal("%s: conversion of newkeys failed", __func__);
 
-	buffer_put_string(&m, blob, bloblen);
+	buffer_put_binary(&m, blob, bloblen);
 	xfree(blob);
 
 	if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
 		fatal("%s: conversion of newkeys failed", __func__);
 
-	buffer_put_string(&m, blob, bloblen);
+	buffer_put_binary(&m, blob, bloblen);
 	xfree(blob);
 
 	packet_get_state(MODE_OUT, &seqnr, &blocks, &packets);
@@ -591,23 +591,23 @@
 	plen = packet_get_keycontext(MODE_OUT, NULL);
 	p = xmalloc(plen+1);
 	packet_get_keycontext(MODE_OUT, p);
-	buffer_put_string(&m, p, plen);
+	buffer_put_binary(&m, p, plen);
 	xfree(p);
 
 	plen = packet_get_keycontext(MODE_IN, NULL);
 	p = xmalloc(plen+1);
 	packet_get_keycontext(MODE_IN, p);
-	buffer_put_string(&m, p, plen);
+	buffer_put_binary(&m, p, plen);
 	xfree(p);
 
 	/* Compression state */
 	debug3("%s: Sending compression state", __func__);
-	buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
-	buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
+	buffer_put_binary(&m, &outgoing_stream, sizeof(outgoing_stream));
+	buffer_put_binary(&m, &incoming_stream, sizeof(incoming_stream));
 
 	/* Network I/O buffers */
-	buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
-	buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
+	buffer_put_binary(&m, buffer_ptr(&input), buffer_len(&input));
+	buffer_put_binary(&m, buffer_ptr(&output), buffer_len(&output));
 
 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
 	debug3("%s: Finished sending state", __func__);
@@ -999,7 +999,7 @@
 	forced_command = have_forced ? xstrdup("true") : NULL;
 
 	if (allowed && rkey != NULL) {
-		blob = buffer_get_string(&m, &blen);
+		blob = buffer_get_binary(&m, &blen);
 		if ((key = key_from_blob(blob, blen)) == NULL)
 			fatal("%s: key_from_blob failed", __func__);
 		*rkey = key;
@@ -1030,7 +1030,7 @@
 	key->type = KEY_RSA1;
 
 	buffer_init(&m);
-	buffer_put_string(&m, blob, blen);
+	buffer_put_binary(&m, blob, blen);
 	xfree(blob);
 
 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
@@ -1058,8 +1058,8 @@
 	key->type = KEY_RSA1;
 
 	buffer_init(&m);
-	buffer_put_string(&m, blob, blen);
-	buffer_put_string(&m, response, 16);
+	buffer_put_binary(&m, blob, blen);
+	buffer_put_binary(&m, response, 16);
 	xfree(blob);
 
 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
diff -bur openssh-3.7.1p2.orig/openbsd-compat/mktemp.c openssh-3.7.1p2/openbsd-compat/mktemp.c
--- openssh-3.7.1p2.orig/openbsd-compat/mktemp.c	Tue Jun  3 04:12:51 2003
+++ openssh-3.7.1p2/openbsd-compat/mktemp.c	Tue Oct  7 08:22:01 2003
@@ -106,10 +106,26 @@
 		char c;
 
 		pid = (arc4random() & 0xffff) % (26+26);
+#if 'Z' == '\xE9' /* CHARSET_EBCDIC */
+		/* EBCDIC problem: A-I J-R S-Z are contiguous, but there's a gap between the three subranges:
+00c0    c0 c1 c2 c3 c4 c5 c6 c7  c8 c9 ca cb cc cd ce cf   .ABCDEFGHI......
+00d0    d0 d1 d2 d3 d4 d5 d6 d7  d8 d9 da db dc dd de df   .JKLMNOPQR......
+00e0    e0 e1 e2 e3 e4 e5 e6 e7  e8 e9 ea eb ec ed ee ef   ..STUVWXYZ......
+*/
+		if (pid < 26)
+			c = pid + 'A'
+			    + (pid >= ('I'-'A'+1))*('J'-'I'-1) /* add 7 for >= 'J' */
+			    + (pid >= ('I'-'A'+1+'R'-'J'+1))*('S'-'R'-1); /* add another 8 for >= 'S' */
+		else
+			c = (pid - 26) + 'a'
+			    + ((pid - 26) >= ('i'-'a'+1))*('j'-'i'-1)
+			    + ((pid - 26) >= ('i'-'a'+1+'r'-'j'+1))*('s'-'r'-1);
+#else
 		if (pid < 26)
 			c = pid + 'A';
 		else
 			c = (pid - 26) + 'a';
+#endif
 		*trv-- = c;
 	}
 	start = trv + 1;
@@ -165,6 +181,16 @@
 					*trv = 'a';
 				else if (*trv == 'z')	/* inc from z to A */
 					*trv = 'A';
+#if 'Z' == '\xE9' /* CHARSET_EBCDIC */
+				/* EBCDIC problem: A-I J-R S-Z are contiguous,
+				 * but there's a gap between the three subranges.
+				 * (similar to the ASCII 'Z'..'a' gap)
+				 */
+				else if (*trv == 'I' || *trv == 'i')
+					*trv += ('J'-'I'); /* advance to 'j' (or 'J') */
+				else if (*trv == 'R' || *trv == 'r')
+					*trv += ('S'-'R'); /* advance to 's' (or 'S') */
+#endif
 				else {
 					if (trv == suffp)
 						return (0);
diff -bur openssh-3.7.1p2.orig/openbsd-compat/vis.c openssh-3.7.1p2/openbsd-compat/vis.c
--- openssh-3.7.1p2.orig/openbsd-compat/vis.c	Fri Aug 29 18:59:52 2003
+++ openssh-3.7.1p2/openbsd-compat/vis.c	Tue Oct  7 08:22:01 2003
@@ -38,6 +38,10 @@
 
 #include "vis.h"
 
+#if 'Z' == '\xE9' /* This test is true for all EBCDIC character dialects */
+#include "includes.h"
+#endif
+
 #define	isoctal(c)	(((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
 #define isvisible(c)	(((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \
 				isgraph((u_char)(c))) ||		     \
@@ -109,7 +113,7 @@
 			goto done;
 		}
 	}
-	if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {	
+	if (((ASC(c) & 0177) == ASC(' ')) || (flag & VIS_OCTAL)) {	
 		*dst++ = '\\';
 		*dst++ = ((u_char)c >> 6 & 07) + '0';
 		*dst++ = ((u_char)c >> 3 & 07) + '0';
@@ -118,16 +122,20 @@
 	}
 	if ((flag & VIS_NOSLASH) == 0)
 		*dst++ = '\\';
-	if (c & 0200) {
+	if (ASC(c) & 0200) {
+#ifdef CHARSET_EBCDIC
+		c = CHR(ASC(c) & 0177);
+#else
 		c &= 0177;
+#endif
 		*dst++ = 'M';
 	}
 	if (iscntrl(c)) {
 		*dst++ = '^';
-		if (c == 0177)
+		if (ASC(c) == 0177)
 			*dst++ = '?';
 		else
-			*dst++ = c + '@';
+			*dst++ = CHR(ASC(c) + ASC('@'));
 	} else {
 		*dst++ = '-';
 		*dst++ = c;
diff -bur openssh-3.7.1p2.orig/packet.c openssh-3.7.1p2/packet.c
--- openssh-3.7.1p2.orig/packet.c	Tue Sep 23 11:00:41 2003
+++ openssh-3.7.1p2/packet.c	Tue Oct  7 08:22:01 2003
@@ -473,6 +473,18 @@
 {
 	buffer_put_int(&outgoing_packet, value);
 }
+#ifdef CHARSET_EBCDIC
+void
+packet_put_binary(const void *buf, u_int len)
+{
+	buffer_put_binary(&outgoing_packet, buf, len);
+}
+void *
+packet_get_binary(u_int *length_ptr)
+{
+	return buffer_get_binary(&incoming_packet, length_ptr);
+}
+#endif
 void
 packet_put_string(const void *buf, u_int len)
 {
@@ -1417,8 +1429,12 @@
 		return;
 	if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &tos,
 	    sizeof(tos)) < 0)
+#if !#system(bs2000)
 		error("setsockopt IP_TOS %d: %.100s:",
 		    tos, strerror(errno));
+#else
+		; /* ignore the error -- no Type Of Service support on BS2000 yet */
+#endif
 }
 #endif
 
diff -bur openssh-3.7.1p2.orig/packet.h openssh-3.7.1p2/packet.h
--- openssh-3.7.1p2.orig/packet.h	Sat Jun 28 04:38:02 2003
+++ openssh-3.7.1p2/packet.h	Tue Oct  7 08:22:01 2003
@@ -31,6 +31,13 @@
 void     packet_set_interactive(int);
 int      packet_is_interactive(void);
 
+#ifdef CHARSET_EBCDIC
+void     packet_put_binary(const void *buf, u_int len);
+void	*packet_get_binary(u_int *length_ptr);
+#else
+#define  packet_put_binary(_buf,_len) packet_put_string(_buf,_len)
+#define	 packet_get_binary(_lenp)     packet_get_string(_lenp)
+#endif
 void     packet_start(u_char);
 void     packet_put_char(int ch);
 void     packet_put_int(u_int value);
diff -bur openssh-3.7.1p2.orig/scp.c openssh-3.7.1p2/scp.c
--- openssh-3.7.1p2.orig/scp.c	Fri Aug 22 01:34:41 2003
+++ openssh-3.7.1p2/scp.c	Tue Oct  7 08:22:02 2003
@@ -201,6 +201,9 @@
 uid_t userid;
 int errs, remin, remout;
 int pflag, iamremote, iamrecursive, targetshouldbedirectory;
+#ifdef CHARSET_EBCDIC
+int binary=0;
+#endif
 
 #define	CMDNEEDS	64
 char cmd[CMDNEEDS];		/* must hold "rcp -r -p -d\0" */
@@ -231,7 +234,11 @@
 	addargs(&args, "-oClearAllForwardings yes");
 
 	fflag = tflag = 0;
-	while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
+	while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:"
+#ifdef CHARSET_EBCDIC
+	                                                             "b" /* binary */
+#endif
+	                                                             )) != -1)
 		switch (ch) {
 		/* User-visible flags. */
 		case '1':
@@ -275,6 +282,11 @@
 		case 'q':
 			showprogress = 0;
 			break;
+#ifdef CHARSET_EBCDIC
+		case 'b':
+			binary = 1;
+			break;
+#endif
 
 		/* Server options. */
 		case 'd':
@@ -579,6 +591,13 @@
 				if (result != amt)
 					haderr = result >= 0 ? EIO : errno;
 			}
+#ifdef CHARSET_EBCDIC
+			if (binary) {
+				/* Convert to EBCDIC */
+				/* ssh will convert back to ASCII */
+				__atoe_l(bp->buf,amt);
+			}
+#endif
 			if (haderr)
 				(void) atomicio(vwrite, remout, bp->buf, amt);
 			else {
@@ -908,7 +927,13 @@
 		
 			if (limitbw)
 				bwlimit(4096);
-
+#ifdef CHARSET_EBCDIC
+			if (binary) {
+				/* Convert back to ASCII */
+				/* ssh has converted to EBCDIC */
+				__etoa_l(bp->buf,count);
+			}
+#endif
 			if (count == bp->cnt) {
 				/* Keep reading so we stay sync'd up. */
 				if (wrerr == NO) {
@@ -1072,7 +1097,7 @@
 	cp = cp0;
 	do {
 		c = (int)*cp;
-		if (c & 0200)
+		if (ASC(c) & 0200)
 			goto bad;
 		if (!isalpha(c) && !isdigit(c)) {
 			switch (c) {
diff -bur openssh-3.7.1p2.orig/serverloop.c openssh-3.7.1p2/serverloop.c
--- openssh-3.7.1p2.orig/serverloop.c	Sat Jun 28 04:38:02 2003
+++ openssh-3.7.1p2/serverloop.c	Tue Oct  7 08:22:02 2003
@@ -926,9 +926,9 @@
 	    ctype, rchan, rwindow, rmaxpack);
 
 	if (strcmp(ctype, "session") == 0) {
-		c = server_request_session(ctype);
+		c = server_request_session("session");
 	} else if (strcmp(ctype, "direct-tcpip") == 0) {
-		c = server_request_direct_tcpip(ctype);
+		c = server_request_direct_tcpip("direct-tcpip");
 	}
 	if (c != NULL) {
 		debug("server_input_channel_open: confirm %s", ctype);
diff -bur openssh-3.7.1p2.orig/session.c openssh-3.7.1p2/session.c
--- openssh-3.7.1p2.orig/session.c	Tue Sep 23 10:59:08 2003
+++ openssh-3.7.1p2/session.c	Tue Oct  7 08:22:02 2003
@@ -404,7 +404,22 @@
 #endif /* USE_PAM */
 
 	/* Fork the child. */
+#if #system(bs2000)
+	{
+	    char *upper;
+	    /* BS2000(PSD/POSIX) ufork needs the user name in UPPER case */
+	    upper = xstrdup(s->pw->pw_name);
+	    strupper(upper, NULL);
+            if ((pid = ufork(upper)) == -1 && errno == EPERM) {
+		log("Hint: Is the POSIX-RLOGIN-DEFAULT set for user %s ?",
+		       s->pw->pw_name);
+	    }
+	    free(upper);
+	}
+	if (pid == 0) {
+#else
 	if ((pid = fork()) == 0) {
+#endif
 		fatal_remove_all_cleanups();
 
 		/* Child.  Reinitialize the log since the pid has changed. */
@@ -530,7 +545,22 @@
 #endif
 
 	/* Fork the child. */
+#if #system(bs2000)
+	{
+	    char *upper;
+	    /* BS2000(PSD/POSIX) ufork needs the user name in UPPER case */
+	    upper = xstrdup(s->pw->pw_name);
+	    strupper(upper, NULL);
+            if ((pid = ufork(upper)) == -1 && errno == EPERM) {
+		log("Hint: Is the POSIX-RLOGIN-DEFAULT set for user %s ?",
+		       s->pw->pw_name);
+	    }
+	    free(upper);
+	}
+	if (pid == 0) {
+#else
 	if ((pid = fork()) == 0) {
+#endif
 		fatal_remove_all_cleanups();
 
 		/* Child.  Reinitialize the log because the pid has changed. */
diff -bur openssh-3.7.1p2.orig/ssh-agent.c openssh-3.7.1p2/ssh-agent.c
--- openssh-3.7.1p2.orig/ssh-agent.c	Tue Sep 23 10:59:08 2003
+++ openssh-3.7.1p2/ssh-agent.c	Tue Oct  7 08:22:02 2003
@@ -210,7 +210,7 @@
 			u_char *blob;
 			u_int blen;
 			key_to_blob(id->key, &blob, &blen);
-			buffer_put_string(&msg, blob, blen);
+			buffer_put_binary(&msg, blob, blen);
 			xfree(blob);
 		}
 		buffer_put_cstring(&msg, id->comment);
@@ -302,8 +302,8 @@
 
 	datafellows = 0;
 
-	blob = buffer_get_string(&e->request, &blen);
-	data = buffer_get_string(&e->request, &dlen);
+	blob = buffer_get_binary(&e->request, &blen);
+	data = buffer_get_binary(&e->request, &dlen);
 
 	flags = buffer_get_int(&e->request);
 	if (flags & SSH_AGENT_OLD_SIGNATURE)
@@ -319,7 +319,7 @@
 	buffer_init(&msg);
 	if (ok == 0) {
 		buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
-		buffer_put_string(&msg, signature, slen);
+		buffer_put_binary(&msg, signature, slen);
 	} else {
 		buffer_put_char(&msg, SSH_AGENT_FAILURE);
 	}
@@ -354,7 +354,7 @@
 			    key_size(key), bits);
 		break;
 	case 2:
-		blob = buffer_get_string(&e->request, &blen);
+		blob = buffer_get_binary(&e->request, &blen);
 		key = key_from_blob(blob, blen);
 		xfree(blob);
 		break;
diff -bur openssh-3.7.1p2.orig/ssh-dss.c openssh-3.7.1p2/ssh-dss.c
--- openssh-3.7.1p2.orig/ssh-dss.c	Mon Feb 24 02:01:41 2003
+++ openssh-3.7.1p2/ssh-dss.c	Tue Oct  7 08:22:02 2003
@@ -88,7 +88,7 @@
 		/* ietf-drafts */
 		buffer_init(&b);
 		buffer_put_cstring(&b, "ssh-dss");
-		buffer_put_string(&b, sigblob, SIGBLOB_LEN);
+		buffer_put_binary(&b, sigblob, SIGBLOB_LEN);
 		len = buffer_len(&b);
 		if (lenp != NULL)
 			*lenp = len;
@@ -134,7 +134,7 @@
 			return -1;
 		}
 		xfree(ktype);
-		sigblob = buffer_get_string(&b, &len);
+		sigblob = buffer_get_binary(&b, &len);
 		rlen = buffer_len(&b);
 		buffer_free(&b);
 		if (rlen != 0) {
diff -bur openssh-3.7.1p2.orig/ssh-keysign.c openssh-3.7.1p2/ssh-keysign.c
--- openssh-3.7.1p2.orig/ssh-keysign.c	Thu Jul  3 12:37:47 2003
+++ openssh-3.7.1p2/ssh-keysign.c	Tue Oct  7 08:22:02 2003
@@ -68,7 +68,7 @@
 	buffer_append(&b, data, datalen);
 
 	/* session id, currently limited to SHA1 (20 bytes) */
-	p = buffer_get_string(&b, &len);
+	p = buffer_get_binary(&b, &len);
 	if (len != 20)
 		fail++;
 	xfree(p);
@@ -93,7 +93,7 @@
 
 	/* pubkey */
 	pkalg = buffer_get_string(&b, NULL);
-	pkblob = buffer_get_string(&b, &blen);
+	pkblob = buffer_get_binary(&b, &blen);
 
 	pktype = key_type_from_name(pkalg);
 	if (pktype == KEY_UNSPEC)
@@ -210,7 +210,7 @@
 	if ((host = get_local_name(fd)) == NULL)
 		fatal("cannot get sockname for fd");
 
-	data = buffer_get_string(&b, &dlen);
+	data = buffer_get_binary(&b, &dlen);
 	if (valid_request(pw, host, &key, data, dlen) < 0)
 		fatal("not a valid request");
 	xfree(host);
@@ -232,7 +232,7 @@
 
 	/* send reply */
 	buffer_clear(&b);
-	buffer_put_string(&b, signature, slen);
+	buffer_put_binary(&b, signature, slen);
 	ssh_msg_send(STDOUT_FILENO, version, &b);
 
 	return (0);
diff -bur openssh-3.7.1p2.orig/ssh-rsa.c openssh-3.7.1p2/ssh-rsa.c
--- openssh-3.7.1p2.orig/ssh-rsa.c	Sun Jun 22 12:45:15 2003
+++ openssh-3.7.1p2/ssh-rsa.c	Tue Oct  7 08:22:02 2003
@@ -80,7 +80,7 @@
 	/* encode signature */
 	buffer_init(&b);
 	buffer_put_cstring(&b, "ssh-rsa");
-	buffer_put_string(&b, sig, slen);
+	buffer_put_binary(&b, sig, slen);
 	len = buffer_len(&b);
 	if (lenp != NULL)
 		*lenp = len;
@@ -126,7 +126,7 @@
 		return -1;
 	}
 	xfree(ktype);
-	sigblob = buffer_get_string(&b, &len);
+	sigblob = buffer_get_binary(&b, &len);
 	rlen = buffer_len(&b);
 	buffer_free(&b);
 	if (rlen != 0) {
diff -bur openssh-3.7.1p2.orig/sshconnect.c openssh-3.7.1p2/sshconnect.c
--- openssh-3.7.1p2.orig/sshconnect.c	Tue Sep 23 10:49:29 2003
+++ openssh-3.7.1p2/sshconnect.c	Tue Oct  7 08:22:02 2003
@@ -451,17 +451,20 @@
 				fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
 			if (len != 1)
 				fatal("ssh_exchange_identification: Connection closed by remote host");
-			if (buf[i] == '\r') {
-				buf[i] = '\n';
+			if (buf[i] == ASC('\r')) {
+				buf[i] = ASC('\n');
 				buf[i + 1] = 0;
 				continue;		/**XXX wait for \n */
 			}
-			if (buf[i] == '\n') {
+			if (buf[i] == ASC('\n')) {
 				buf[i + 1] = 0;
 				break;
 			}
 		}
 		buf[sizeof(buf) - 1] = 0;
+#ifdef CHARSET_EBCDIC
+		__atoe_l (buf, sizeof(buf));
+#endif                              
 		if (strncmp(buf, "SSH-", 4) == 0)
 			break;
 		debug("ssh_exchange_identification: %s", buf);
@@ -524,8 +527,14 @@
 	    compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
 	    compat20 ? PROTOCOL_MINOR_2 : minor1,
 	    SSH_VERSION);
+#ifdef CHARSET_EBCDIC
+	__etoa(buf);
+#endif
 	if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
 		fatal("write: %.100s", strerror(errno));
+#ifdef CHARSET_EBCDIC
+	__atoe(buf);
+#endif
 	client_version_string = xstrdup(buf);
 	chop(client_version_string);
 	chop(server_version_string);
@@ -955,6 +964,11 @@
 	char *server_user, *local_user;
 
 	local_user = xstrdup(pw->pw_name);
+#if #system(bs2000)
+	/* Convert the UPPERCASE USER into all lowercase to ease connectivity with unix. */
+	/* IMO that is legitimate, as BS2000's user names are case insensitive */
+	strlower(local_user, NULL);
+#endif
 	server_user = options.user ? options.user : local_user;
 
 	/* Convert the user-supplied hostname into all lowercase. */
diff -bur openssh-3.7.1p2.orig/sshconnect2.c openssh-3.7.1p2/sshconnect2.c
--- openssh-3.7.1p2.orig/sshconnect2.c	Tue Aug 26 04:14:05 2003
+++ openssh-3.7.1p2/sshconnect2.c	Tue Oct  7 08:22:02 2003
@@ -416,14 +416,14 @@
 	if (datafellows & SSH_BUG_PKOK) {
 		/* this is similar to SSH_BUG_PKAUTH */
 		debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
-		pkblob = packet_get_string(&blen);
+		pkblob = packet_get_binary(&blen);
 		buffer_init(&b);
 		buffer_append(&b, pkblob, blen);
 		pkalg = buffer_get_string(&b, &alen);
 		buffer_free(&b);
 	} else {
 		pkalg = packet_get_string(&alen);
-		pkblob = packet_get_string(&blen);
+		pkblob = packet_get_binary(&blen);
 	}
 	packet_check_eom();
 
@@ -847,7 +847,7 @@
 		buffer_append(&b, session_id2, session_id2_len);
 		skip = session_id2_len;
 	} else {
-		buffer_put_string(&b, session_id2, session_id2_len);
+		buffer_put_binary(&b, session_id2, session_id2_len);
 		skip = buffer_len(&b);
 	}
 	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
@@ -863,7 +863,7 @@
 		buffer_put_char(&b, have_sig);
 		buffer_put_cstring(&b, key_ssh_name(id->key));
 	}
-	buffer_put_string(&b, blob, bloblen);
+	buffer_put_binary(&b, blob, bloblen);
 
 	/* generate signature */
 	ret = identity_sign(id, &signature, &slen,
@@ -887,12 +887,12 @@
 		buffer_put_char(&b, have_sig);
 		if (!(datafellows & SSH_BUG_PKAUTH))
 			buffer_put_cstring(&b, key_ssh_name(id->key));
-		buffer_put_string(&b, blob, bloblen);
+		buffer_put_binary(&b, blob, bloblen);
 	}
 	xfree(blob);
 
 	/* append signature */
-	buffer_put_string(&b, signature, slen);
+	buffer_put_binary(&b, signature, slen);
 	xfree(signature);
 
 	/* skip session id and packet type */
@@ -932,7 +932,7 @@
 	packet_put_char(have_sig);
 	if (!(datafellows & SSH_BUG_PKAUTH))
 		packet_put_cstring(key_ssh_name(id->key));
-	packet_put_string(blob, bloblen);
+	packet_put_binary(blob, bloblen);
 	xfree(blob);
 	packet_send();
 	return 1;
@@ -1243,7 +1243,7 @@
 
 	buffer_init(&b);
 	buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
-	buffer_put_string(&b, data, datalen);
+	buffer_put_binary(&b, data, datalen);
 	ssh_msg_send(to[1], version, &b);
 
 	if (ssh_msg_recv(from[0], &b) < 0) {
@@ -1263,7 +1263,7 @@
 		buffer_clear(&b);
 		return -1;
 	}
-	*sigp = buffer_get_string(&b, lenp);
+	*sigp = buffer_get_binary(&b, lenp);
 	buffer_clear(&b);
 
 	return 0;
@@ -1318,13 +1318,13 @@
 	pkalg = xstrdup(key_ssh_name(private));
 	buffer_init(&b);
 	/* construct data */
-	buffer_put_string(&b, session_id2, session_id2_len);
+	buffer_put_binary(&b, session_id2, session_id2_len);
 	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
 	buffer_put_cstring(&b, authctxt->server_user);
 	buffer_put_cstring(&b, service);
 	buffer_put_cstring(&b, authctxt->method->name);
 	buffer_put_cstring(&b, pkalg);
-	buffer_put_string(&b, blob, blen);
+	buffer_put_binary(&b, blob, blen);
 	buffer_put_cstring(&b, chost);
 	buffer_put_cstring(&b, authctxt->local_user);
 #ifdef DEBUG_PK
@@ -1349,10 +1349,10 @@
 	packet_put_cstring(authctxt->service);
 	packet_put_cstring(authctxt->method->name);
 	packet_put_cstring(pkalg);
-	packet_put_string(blob, blen);
+	packet_put_binary(blob, blen);
 	packet_put_cstring(chost);
 	packet_put_cstring(authctxt->local_user);
-	packet_put_string(signature, slen);
+	packet_put_binary(signature, slen);
 	memset(signature, 's', slen);
 	xfree(signature);
 	xfree(chost);
diff -bur openssh-3.7.1p2.orig/sshd.c openssh-3.7.1p2/sshd.c
--- openssh-3.7.1p2.orig/sshd.c	Tue Sep  2 14:51:17 2003
+++ openssh-3.7.1p2/sshd.c	Tue Oct  7 08:22:02 2003
@@ -152,6 +152,7 @@
  */
 char *client_version_string = NULL;
 char *server_version_string = NULL;
+/* Note CHARSET_EBCDIC: these strings are kept in EBCDIC, and are converted for transmission */
 
 /* for rekeying XXX fixme */
 Kex *xxx_kex;
@@ -370,6 +371,9 @@
 	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
 	server_version_string = xstrdup(buf);
 
+#ifdef CHARSET_EBCDIC
+	__etoa(server_version_string);
+#endif
 	/* Send our protocol version identification. */
 	if (atomicio(vwrite, sock_out, server_version_string,
 	    strlen(server_version_string))
@@ -377,6 +381,9 @@
 		logit("Could not write ident string to %s", get_remote_ipaddr());
 		fatal_cleanup();
 	}
+#ifdef CHARSET_EBCDIC
+	__atoe(server_version_string); /* undo the conversion, server_version_string is used below */
+#endif
 
 	/* Read other sides version identification. */
 	memset(buf, 0, sizeof(buf));
@@ -386,21 +393,30 @@
 			    get_remote_ipaddr());
 			fatal_cleanup();
 		}
-		if (buf[i] == '\r') {
+		if (buf[i] == ASC('\r')) {
+#ifdef CHARSET_EBCDIC
+			char *FSecureMacintosh = strcpy(alloca(sizeof("SSH-1.5-W1.0")), "SSH-1.5-W1.0");
+			__etoa(FSecureMacintosh); /* need it in ASCII */
+#else
+#define                 FSecureMacintosh         "SSH-1.5-W1.0"
+#endif
 			buf[i] = 0;
 			/* Kludge for F-Secure Macintosh < 1.0.2 */
 			if (i == 12 &&
-			    strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
+			    strncmp(buf, FSecureMacintosh, 12) == 0)
 				break;
 			continue;
 		}
-		if (buf[i] == '\n') {
+		if (buf[i] == ASC('\n')) {
 			buf[i] = 0;
 			break;
 		}
 	}
 	buf[sizeof(buf) - 1] = 0;
 	client_version_string = xstrdup(buf);
+#ifdef CHARSET_EBCDIC
+	__atoe(client_version_string);
+#endif
 
 	/*
 	 * Check that the versions match.  In future this might accept
@@ -409,7 +425,14 @@
 	if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n",
 	    &remote_major, &remote_minor, remote_version) != 3) {
 		s = "Protocol mismatch.\n";
+#ifdef CHARSET_EBCDIC
+		s = xstrdup(s);
+		__etoa(s);
+		(void) atomicio(vwrite, sock_out, s, strlen(s));
+		free(s);
+#else
 		(void) atomicio(vwrite, sock_out, s, strlen(s));
+#endif
 		close(sock_in);
 		close(sock_out);
 		logit("Bad protocol version identification '%.100s' from %s",
@@ -470,7 +493,14 @@
 
 	if (mismatch) {
 		s = "Protocol major versions differ.\n";
+#ifdef CHARSET_EBCDIC
+		s = xstrdup(s);
+		__etoa(s);
+		(void) atomicio(vwrite, sock_out, s, strlen(s));
+		free(s);
+#else
 		(void) atomicio(vwrite, sock_out, s, strlen(s));
+#endif
 		close(sock_in);
 		close(sock_out);
 		logit("Protocol major versions differ for %s: %.200s vs. %.200s",
@@ -583,7 +613,25 @@
 	/* Store a pointer to the kex for later rekeying */
 	pmonitor->m_pkex = &xxx_kex;
 
+#if #system(bs2000)
+	{
+	    char *upper;
+	    /* BS2000(PSD/POSIX) ufork needs the user name in UPPER case */
+	    upper = xstrdup(SSH_PRIVSEP_USER);
+	    strupper(upper, NULL);
+            if ((pid = ufork(upper)) == -1 && errno == EPERM) {
+	        if (getpwnam(SSH_PRIVSEP_USER) == NULL)
+                    fatal("Privilege separation user %s does not exist",
+                        SSH_PRIVSEP_USER);
+                else
+	            log("Hint: Is the POSIX-RLOGIN-DEFAULT set for user %s ?",
+		         SSH_PRIVSEP_USER);
+	    }
+	    free(upper);
+	}
+#else
 	pid = fork();
+#endif
 	if (pid == -1) {
 		fatal("fork of unprivileged child failed");
 	} else if (pid != 0) {
@@ -649,7 +697,21 @@
 	/* New socket pair */
 	monitor_reinit(pmonitor);
 
+#if #system(bs2000)
+	{
+	    char *upper;
+	    /* BS2000(PSD/POSIX) ufork needs the user name in UPPER case */
+	    upper = xstrdup(authctxt->pw->pw_name);
+	    strupper(upper, NULL);
+            if ((pmonitor->m_pid = ufork(upper)) == -1 && errno == EPERM) {
+		log("Hint: Is the POSIX-RLOGIN-DEFAULT set for user %s ?",
+		       authctxt->pw->pw_name);
+	    }
+	    free(upper);
+	}
+#else
 	pmonitor->m_pid = fork();
+#endif
 	if (pmonitor->m_pid == -1)
 		fatal("fork of unprivileged child failed");
 	else if (pmonitor->m_pid != 0) {
@@ -1287,6 +1349,11 @@
 				newsock = accept(listen_socks[i], (struct sockaddr *)&from,
 				    &fromlen);
 				if (newsock < 0) {
+#if #system(bs2000)
+					/* There is not much use in looping after the network layer has been brought down... Die gracefully. */
+					if (errno == ENETDOWN)
+						fatal("accept: %.100s", strerror(errno));
+#endif
 					if (errno != EINTR && errno != EWOULDBLOCK)
 						error("accept: %.100s", strerror(errno));
 					continue;
diff -bur openssh-3.7.1p2.orig/ttymodes.c openssh-3.7.1p2/ttymodes.c
--- openssh-3.7.1p2.orig/ttymodes.c	Wed May 14 05:40:07 2003
+++ openssh-3.7.1p2/ttymodes.c	Tue Oct  7 08:22:02 2003
@@ -287,7 +287,7 @@
 #define TTYCHAR(NAME, OP) \
 	debug3("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \
 	buffer_put_char(&buf, OP); \
-	put_arg(&buf, tio.c_cc[NAME]);
+	put_arg(&buf, ASC(tio.c_cc[NAME]));
 
 #define TTYMODE(NAME, FIELD, OP) \
 	debug3("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \
@@ -303,7 +303,7 @@
 	/* Mark end of mode data. */
 	buffer_put_char(&buf, TTY_OP_END);
 	if (compat20)
-		packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
+		packet_put_binary(buffer_ptr(&buf), buffer_len(&buf));
 	else
 		packet_put_raw(buffer_ptr(&buf), buffer_len(&buf));
 	buffer_free(&buf);
@@ -375,7 +375,7 @@
 #define TTYCHAR(NAME, OP) \
 	case OP: \
 	  n_bytes += arg_size; \
-	  tio.c_cc[NAME] = get_arg(); \
+	  tio.c_cc[NAME] = CHR(get_arg()); \
 	  debug3("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \
 	  break;
 #define TTYMODE(NAME, FIELD, OP) \
diff -bur openssh-3.7.1p2.orig/uidswap.c openssh-3.7.1p2/uidswap.c
--- openssh-3.7.1p2.orig/uidswap.c	Mon Sep 22 04:55:21 2003
+++ openssh-3.7.1p2/uidswap.c	Tue Oct  7 08:22:02 2003
@@ -143,6 +143,10 @@
 void
 permanently_set_uid(struct passwd *pw)
 {
+#if #system(bs2000)
+#undef __func__
+	static const char __func__[] = { "permanently_set_uid()" };
+#endif
 	uid_t old_uid = getuid();
 	gid_t old_gid = getgid();
 


More information about the openssh-unix-dev mailing list