Have sftp print a warning about shell cleanliness when decoding the first
authordtucker <dtucker@openbsd.org>
Tue, 28 Nov 2017 21:10:22 +0000 (21:10 +0000)
committerdtucker <dtucker@openbsd.org>
Tue, 28 Nov 2017 21:10:22 +0000 (21:10 +0000)
packet fails, which is usually caused by shells polluting stdout of
non-interactive starups.  bz#2800, ok markus@ deraadt@.

usr.bin/ssh/sftp-client.c

index 5db6b5d..2f3e68e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.127 2017/08/11 04:41:08 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.128 2017/11/28 21:10:22 dtucker Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
  *
@@ -116,7 +116,7 @@ send_msg(struct sftp_conn *conn, struct sshbuf *m)
 }
 
 static void
-get_msg(struct sftp_conn *conn, struct sshbuf *m)
+get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial)
 {
        u_int msg_len;
        u_char *p;
@@ -134,8 +134,12 @@ get_msg(struct sftp_conn *conn, struct sshbuf *m)
 
        if ((r = sshbuf_get_u32(m, &msg_len)) != 0)
                fatal("%s: buffer error: %s", __func__, ssh_err(r));
-       if (msg_len > SFTP_MAX_MSG_LENGTH)
-               fatal("Received message too long %u", msg_len);
+       if (msg_len > SFTP_MAX_MSG_LENGTH) {
+               do_log2(initial ? SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_FATAL,
+                   "Received message too long %u", msg_len);
+               fatal("Ensure the remote shell produces no output "
+                   "for non-interactive sessions.");
+       }
 
        if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
                fatal("%s: buffer error: %s", __func__, ssh_err(r));
@@ -149,6 +153,12 @@ get_msg(struct sftp_conn *conn, struct sshbuf *m)
        }
 }
 
+static void
+get_msg(struct sftp_conn *conn, struct sshbuf *m)
+{
+       get_msg_extended(conn, m, 0);
+}
+
 static void
 send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s,
     u_int len)
@@ -392,7 +402,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
 
        sshbuf_reset(msg);
 
-       get_msg(ret, msg);
+       get_msg_extended(ret, msg, 1);
 
        /* Expecting a VERSION reply */
        if ((r = sshbuf_get_u8(msg, &type)) != 0)