- djm@cvs.openbsd.org 2008/06/10 22:15:23
     [PROTOCOL ssh.c serverloop.c]
     Add a no-more-sessions@openssh.com global request extension that the
     client sends when it knows that it will never request another session
     (i.e. when session multiplexing is disabled). This allows a server to
     disallow further session requests and terminate the session.
     Why would a non-multiplexing client ever issue additional session
     requests? It could have been attacked with something like SSH'jack:
     http://www.storm.net.nz/projects/7
     feedback & ok markus
diff --git a/ChangeLog b/ChangeLog
index 5239fd5..9701f25 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -41,6 +41,16 @@
    - dtucker@cvs.openbsd.org 2008/06/10 18:21:24
      [ssh_config.5]
      clarify that Host patterns are space-separated.  ok deraadt
+   - djm@cvs.openbsd.org 2008/06/10 22:15:23
+     [PROTOCOL ssh.c serverloop.c]
+     Add a no-more-sessions@openssh.com global request extension that the
+     client sends when it knows that it will never request another session
+     (i.e. when session multiplexing is disabled). This allows a server to
+     disallow further session requests and terminate the session.
+     Why would a non-multiplexing client ever issue additional session
+     requests? It could have been attacked with something like SSH'jack:
+     http://www.storm.net.nz/projects/7
+     feedback & ok markus
  - (dtucker) [openbsd-compat/fake-rfc2553.h] Add sin6_scope_id to sockaddr_in6
    since the new CIDR code in addmatch.c references it.
  - (dtucker) [Makefile.in configure.ac regress/addrmatch.sh] Skip IPv6
@@ -4133,4 +4143,4 @@
    OpenServer 6 and add osr5bigcrypt support so when someone migrates
    passwords between UnixWare and OpenServer they will still work. OK dtucker@
 
-$Id: ChangeLog,v 1.4961 2008/06/10 23:33:01 dtucker Exp $
+$Id: ChangeLog,v 1.4962 2008/06/10 23:34:01 dtucker Exp $
diff --git a/PROTOCOL b/PROTOCOL
index 4d7a447..76e6adb 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -61,7 +61,30 @@
 still be sent in the other direction. This message does not consume
 window space and may be sent even if no window space is available.
 
-4. sftp: Reversal of arguments to SSH_FXP_SYMLINK
+4. connection: disallow additional sessions extension
+   "no-more-sessions@openssh.com"
+
+Most SSH connections will only ever request a single session, but a
+attacker may abuse a running ssh client to surreptitiously open
+additional sessions under their control. OpenSSH provides a global
+request "no-more-sessions@openssh.com" to mitigate this attack.
+
+When an OpenSSH client expects that it will never open another session
+(i.e. it has been started with connection multiplexing disabled), it
+will send the following global request:
+
+	byte		SSH_MSG_GLOBAL_REQUEST
+	string		"no-more-sessions@openssh.com"
+	char		want-reply
+
+On receipt of such a message, an OpenSSH server will refuse to open
+future channels of type "session" and instead immediately abort the
+connection.
+
+Note that this is not a general defence against compromised clients
+(that is impossible), but it thwarts a simple attack.
+
+5. sftp: Reversal of arguments to SSH_FXP_SYMLINK
 
 When OpenSSH's sftp-server was implemented, the order of the arguments
 to the SSH_FXP_SYMLINK method was inadvertendly reversed. Unfortunately,
@@ -74,7 +97,7 @@
 	string		targetpath
 	string		linkpath
 
-5. sftp: Server extension announcement in SSH_FXP_VERSION
+6. sftp: Server extension announcement in SSH_FXP_VERSION
 
 OpenSSH's sftp-server lists the extensions it supports using the
 standard extension announcement mechanism in the SSH_FXP_VERSION server
@@ -95,7 +118,7 @@
 extension with multiple versions (though this is unlikely). Clients MUST
 check the version number before attemping to use the extension.
 
-6. sftp: Extension request "posix-rename@openssh.com"
+7. sftp: Extension request "posix-rename@openssh.com"
 
 This operation provides a rename operation with POSIX semantics, which
 are different to those provided by the standard SSH_FXP_RENAME in
@@ -112,7 +135,7 @@
 This extension is advertised in the SSH_FXP_VERSION hello with version
 "1".
 
-7. sftp: Extension requests "statvfs@openssh.com" and
+8. sftp: Extension requests "statvfs@openssh.com" and
          "fstatvfs@openssh.com"
 
 These requests correspond to the statvfs and fstatvfs POSIX system
@@ -153,5 +176,5 @@
 This extension is advertised in the SSH_FXP_VERSION hello with version
 "2".
 
-$OpenBSD: PROTOCOL,v 1.5 2008/06/09 13:38:46 dtucker Exp $
+$OpenBSD: PROTOCOL,v 1.6 2008/06/10 22:15:23 djm Exp $
 
diff --git a/serverloop.c b/serverloop.c
index 6bc140f..76d76ba 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.151 2008/05/09 16:21:13 markus Exp $ */
+/* $OpenBSD: serverloop.c,v 1.152 2008/06/10 22:15:23 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -105,6 +105,7 @@
 static int connection_out;	/* Connection to client (output). */
 static int connection_closed = 0;	/* Connection to client closed. */
 static u_int buffer_high;	/* "Soft" max buffer size. */
+static int no_more_sessions = 0; /* Disallow further sessions. */
 
 /*
  * This SIGCHLD kludge is used to detect when the child exits.  The server
@@ -1013,6 +1014,12 @@
 
 	debug("input_session_request");
 	packet_check_eom();
+
+	if (no_more_sessions) {
+		packet_disconnect("Possible attack: attempt to open a session "
+		    "after additional sessions disabled");
+	}
+
 	/*
 	 * A server session has no fd to read or write until a
 	 * CHANNEL_REQUEST for a shell is made, so we set the type to
@@ -1133,6 +1140,9 @@
 		success = channel_cancel_rport_listener(cancel_address,
 		    cancel_port);
 		xfree(cancel_address);
+	} else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
+		no_more_sessions = 1;
+		success = 1;
 	}
 	if (want_reply) {
 		packet_start(success ?
diff --git a/ssh.c b/ssh.c
index 3bcca53..e3737bb 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.313 2008/05/09 14:26:08 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.314 2008/06/10 22:15:23 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1151,6 +1151,15 @@
 	if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
 		id = ssh_session2_open();
 
+	/* If we don't expect to open a new session, then disallow it */
+	if (options.control_master == SSHCTL_MASTER_NO) {
+		debug("Requesting no-more-sessions@openssh.com");
+		packet_start(SSH2_MSG_GLOBAL_REQUEST);
+		packet_put_cstring("no-more-sessions@openssh.com");
+		packet_put_char(0);
+		packet_send();
+	}
+
 	/* Execute a local command */
 	if (options.local_command != NULL &&
 	    options.permit_local_command)