diff -wpruN --no-dereference '--exclude=*.orig' a~/readconf.c a/readconf.c
--- a~/readconf.c	1970-01-01 00:00:00
+++ a/readconf.c	1970-01-01 00:00:00
@@ -167,6 +167,9 @@ typedef enum {
 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
 	oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
 	oHashKnownHosts,
+#ifdef DISABLE_BANNER
+	oDisableBanner,
+#endif
 	oTunnel, oTunnelDevice,
 	oLocalCommand, oPermitLocalCommand, oRemoteCommand,
 	oVisualHostKey,
@@ -294,6 +297,9 @@ static struct {
 	{ "controlpersist", oControlPersist },
 	{ "hashknownhosts", oHashKnownHosts },
 	{ "include", oInclude },
+#ifdef DISABLE_BANNER
+	{ "disablebanner", oDisableBanner },
+#endif
 	{ "tunnel", oTunnel },
 	{ "tunneldevice", oTunnelDevice },
 	{ "localcommand", oLocalCommand },
@@ -1054,6 +1060,17 @@ parse_multistate_value(const char *arg,
 	return -1;
 }
 
+#ifdef DISABLE_BANNER
+static const struct multistate multistate_disablebanner[] = {
+	{ "true",			SSH_DISABLEBANNER_YES },
+	{ "false",			SSH_DISABLEBANNER_NO },
+	{ "yes",			SSH_DISABLEBANNER_YES },
+	{ "no",				SSH_DISABLEBANNER_NO },
+	{ "in-exec-mode",		SSH_DISABLEBANNER_INEXECMODE },
+	{ NULL, -1 }
+};
+#endif
+
 /*
  * Processes a single option line as used in the configuration files. This
  * only sets those values that have not already been set.
@@ -2422,6 +2439,13 @@ parse_pubkey_algos:
 		}
 		break;
 
+#ifdef DISABLE_BANNER
+	case oDisableBanner:
+	        intptr = &options->disable_banner;
+                multistate_ptr = multistate_disablebanner;
+                goto parse_multistate;
+#endif
+
 	case oDeprecated:
 		debug("%s line %d: Deprecated option \"%s\"",
 		    filename, linenum, keyword);
@@ -2660,6 +2684,9 @@ initialize_options(Options * options)
 	options->stdin_null = -1;
 	options->fork_after_authentication = -1;
 	options->proxy_use_fdpass = -1;
+#ifdef DISABLE_BANNER
+	options->disable_banner = -1;
+#endif
 	options->ignored_unknown = NULL;
 	options->num_canonical_domains = 0;
 	options->num_permitted_cnames = 0;
@@ -2867,6 +2894,10 @@ fill_default_options(Options * options)
 		options->canonicalize_fallback_local = 1;
 	if (options->canonicalize_hostname == -1)
 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
+#ifdef DISABLE_BANNER
+	if (options->disable_banner == -1)
+		options->disable_banner = 0;
+#endif
 	if (options->fingerprint_hash == -1)
 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
 #ifdef ENABLE_SK_INTERNAL
diff -wpruN --no-dereference '--exclude=*.orig' a~/readconf.h a/readconf.h
--- a~/readconf.h	1970-01-01 00:00:00
+++ a/readconf.h	1970-01-01 00:00:00
@@ -186,6 +186,9 @@ typedef struct {
 	u_int	num_channel_timeouts;
 
 	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */
+#ifdef DISABLE_BANNER
+        int     disable_banner; /* Disable display of banner */
+#endif
 }       Options;
 
 #define SSH_PUBKEY_AUTH_NO	0x00
@@ -231,6 +234,12 @@ typedef struct {
 #define SSH_KEYSTROKE_CHAFF_MIN_MS		1024
 #define SSH_KEYSTROKE_CHAFF_RNG_MS		2048
 
+#ifdef DISABLE_BANNER
+#define SSH_DISABLEBANNER_NO		0
+#define SSH_DISABLEBANNER_YES		1
+#define SSH_DISABLEBANNER_INEXECMODE	2
+#endif
+
 const char *kex_default_pk_alg(void);
 char	*ssh_connection_hash(const char *thishost, const char *host,
     const char *portstr, const char *user, const char *jump_host);
diff -wpruN --no-dereference '--exclude=*.orig' a~/ssh_config.5 a/ssh_config.5
--- a~/ssh_config.5	1970-01-01 00:00:00
+++ a/ssh_config.5	1970-01-01 00:00:00
@@ -710,6 +710,14 @@ If set to a time in seconds, or a time i
 then the backgrounded master connection will automatically terminate
 after it has remained idle (with no client connections) for the
 specified time.
+.It Cm DisableBanner
+If set to yes, disables the display of the  banner  message.
+If set to in-exec-mode, disables the display of banner message when in remote
+command mode only.
+.Pp
+The default value is no, which means that the banner is displayed unless the
+log level  is  QUIET, FATAL, or ERROR. See also the Banner option in
+.Xr sshd_config 4 . This option applies to protocol version 2 only.
 .It Cm DynamicForward
 Specifies that a TCP port on the local machine be forwarded
 over the secure channel, and the application
diff -wpruN --no-dereference '--exclude=*.orig' a~/sshconnect2.c a/sshconnect2.c
--- a~/sshconnect2.c	1970-01-01 00:00:00
+++ a/sshconnect2.c	1970-01-01 00:00:00
@@ -82,6 +82,10 @@
 /* import */
 extern Options options;
 
+#ifdef DISABLE_BANNER
+extern struct sshbuf *command;
+#endif
+
 /*
  * SSH2 key exchange
  */
@@ -576,8 +580,28 @@ input_userauth_banner(int type, u_int32_
 	if ((r = sshpkt_get_cstring(ssh, &msg, &len)) != 0 ||
 	    (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0)
 		goto out;
-	if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO)
-		fmprintf(stderr, "%s", msg);
+#ifdef DISABLE_BANNER
+	/*
+	 * Banner is a warning message according to RFC 4252. So, never print
+	 * a banner in error log level or lower. If the log level is higher,
+	 * use DisableBanner option to decide whether to display it or not.
+	 */
+	if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO &&
+            (options.disable_banner == SSH_DISABLEBANNER_NO ||
+            (options.disable_banner == SSH_DISABLEBANNER_INEXECMODE &&
+            sshbuf_len(command) == 0))) {
+#else
+	if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) {
+#endif
+		char *safe;
+
+		if (len > 65536)
+			len = 65536;
+		safe = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
+		strnvis(safe, msg, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
+		fmprintf(stderr, "%s", safe);
+		free(safe);
+	}
 	r = 0;
  out:
 	free(msg);
