25809379 Openssh 7.4p1 has 3 regressions, fixed in 7.5
authorTomas Kuthan <tomas.kuthan@oracle.com>
Mon, 03 Apr 2017 01:42:38 -0700
changeset 7839 d2c617295be6
parent 7838 b841215bb9aa
child 7840 6eb80902a873
25809379 Openssh 7.4p1 has 3 regressions, fixed in 7.5
components/openssh/patches/99-sha2-regression.patch
components/openssh/patches/99-smartcard-key-regression.patch
components/openssh/patches/99-unbreak-root-regression.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssh/patches/99-sha2-regression.patch	Mon Apr 03 01:42:38 2017 -0700
@@ -0,0 +1,74 @@
+#
+# Temporary patch for 7.4p1 regression fixed in 7.5
+# From upstream
+# Remove when upgrading 
+#
+# https://bugzilla.mindrot.org/show_bug.cgi?id=2680
+# fix regression in 7.4 server-sig-algs,
+# accidentally excluding SHA2 RSA signature methods.
+#
+
+diff -rupN old/kex.c new/kex.c
+--- old/kex.c	2017-03-28 19:08:53.584501767 -0700
++++ new/kex.c	2017-03-28 19:22:26.034204047 -0700
[email protected]@ -388,7 +388,7 @@ kex_send_ext_info(struct ssh *ssh)
+ 	int r;
+ 	char *algs;
+ 
+-	if ((algs = sshkey_alg_list(0, 1, ',')) == NULL)
++	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
+ 		return SSH_ERR_ALLOC_FAIL;
+ 	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
+ 	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
+diff -rupN old/ssh.c new/ssh.c
+--- old/ssh.c	2017-03-28 19:08:53.587726975 -0700
++++ new/ssh.c	2017-03-28 19:25:10.561309338 -0700
[email protected]@ -697,11 +697,11 @@ main(int ac, char **av)
+ 			else if (strcmp(optarg, "kex") == 0)
+ 				cp = kex_alg_list('\n');
+ 			else if (strcmp(optarg, "key") == 0)
+-				cp = sshkey_alg_list(0, 0, '\n');
++				cp = sshkey_alg_list(0, 0, 0, '\n');
+ 			else if (strcmp(optarg, "key-cert") == 0)
+-				cp = sshkey_alg_list(1, 0, '\n');
++				cp = sshkey_alg_list(1, 0, 0, '\n');
+ 			else if (strcmp(optarg, "key-plain") == 0)
+-				cp = sshkey_alg_list(0, 1, '\n');
++				cp = sshkey_alg_list(0, 1, 0, '\n');
+ 			else if (strcmp(optarg, "protocol-version") == 0) {
+ #ifdef WITH_SSH1
+ 				cp = xstrdup("1\n2");
+diff -rupN old/sshkey.c new/sshkey.c
+--- old/sshkey.c	2017-03-28 19:08:53.590992687 -0700
++++ new/sshkey.c	2017-03-28 19:32:28.309848396 -0700
[email protected]@ -235,14 +235,16 @@ sshkey_ecdsa_nid_from_name(const char *n
+ }
+ 
+ char *
+-sshkey_alg_list(int certs_only, int plain_only, char sep)
++sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
+ {
+ 	char *tmp, *ret = NULL;
+ 	size_t nlen, rlen = 0;
+ 	const struct keytype *kt;
+ 
+ 	for (kt = keytypes; kt->type != -1; kt++) {
+-		if (kt->name == NULL || kt->sigonly)
++		if (kt->name == NULL)
++			continue;
++		if (!include_sigonly && kt->sigonly)
+ 			continue;
+ 		if ((certs_only && !kt->cert) || (plain_only && kt->cert))
+ 			continue;
+diff -rupN old/sshkey.h new/sshkey.h
+--- old/sshkey.h	2017-03-28 19:08:53.594083865 -0700
++++ new/sshkey.h	2017-03-28 19:33:39.322046181 -0700
[email protected]@ -157,7 +157,7 @@ int		 sshkey_ec_validate_private(const E
+ const char	*sshkey_ssh_name(const struct sshkey *);
+ const char	*sshkey_ssh_name_plain(const struct sshkey *);
+ int		 sshkey_names_valid2(const char *, int);
+-char		*sshkey_alg_list(int, int, char);
++char		*sshkey_alg_list(int, int, int, char);
+ 
+ int	 sshkey_from_blob(const u_char *, size_t, struct sshkey **);
+ int	 sshkey_fromb(struct sshbuf *, struct sshkey **);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssh/patches/99-smartcard-key-regression.patch	Mon Apr 03 01:42:38 2017 -0700
@@ -0,0 +1,58 @@
+#
+# Temporary patch for 7.4p1 regression, fixed in 7.5
+# Fix from upstream
+# Remove when upgrading
+#
+# https://bugzilla.mindrot.org/show_bug.cgi?id=2682
+# fix regression in 7.4: deletion of PKCS#11-hosted keys
+# would fail unless they were specified by full physical pathname. 
+#
+diff -rupN old/ssh-agent.c new/ssh-agent.c
+--- old/ssh-agent.c	2017-03-30 14:48:53.785202740 -0700
++++ new/ssh-agent.c	2017-03-30 16:19:56.238660913 -0700
[email protected]@ -821,7 +821,7 @@ send:
+ static void
+ process_remove_smartcard_key(SocketEntry *e)
+ {
+-	char *provider = NULL, *pin = NULL;
++	char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
+ 	int r, version, success = 0;
+ 	Identity *id, *nxt;
+ 	Idtab *tab;
[email protected]@ -831,6 +831,14 @@ process_remove_smartcard_key(SocketEntry
+ 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ 	free(pin);
+ 
++	if (realpath(provider, canonical_provider) == NULL) {
++		verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
++		    provider, strerror(errno));
++		goto send;
++	}
++
++	debug("%s: remove %.100s", __func__, canonical_provider);
++
+ 	for (version = 1; version < 3; version++) {
+ 		tab = idtab_lookup(version);
+ 		for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
[email protected]@ -838,18 +846,19 @@ process_remove_smartcard_key(SocketEntry
+ 			/* Skip file--based keys */
+ 			if (id->provider == NULL)
+ 				continue;
+-			if (!strcmp(provider, id->provider)) {
++			if (!strcmp(canonical_provider, id->provider)) {
+ 				TAILQ_REMOVE(&tab->idlist, id, next);
+ 				free_identity(id);
+ 				tab->nentries--;
+ 			}
+ 		}
+ 	}
+-	if (pkcs11_del_provider(provider) == 0)
++	if (pkcs11_del_provider(canonical_provider) == 0)
+ 		success = 1;
+ 	else
+ 		error("process_remove_smartcard_key:"
+ 		    " pkcs11_del_provider failed");
++send:
+ 	free(provider);
+ 	send_status(e, success);
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssh/patches/99-unbreak-root-regression.patch	Mon Apr 03 01:42:38 2017 -0700
@@ -0,0 +1,69 @@
+#
+# Temporary patch for 7.4p1 regression, fixed in 7.5
+# Fix from upstream
+# Remove when upgrading 
+#
+# https://github.com/openssh/openssh-portable/commit/51045869fa084cdd016fdd721ea760417c0a3bf3
+# unbreak Unix domain socket forwarding for root
+#
+diff -rupN old/serverloop.c new/serverloop.c
+--- old/serverloop.c	2017-03-30 14:34:07.762152901 -0700
++++ new/serverloop.c	2017-03-30 14:43:20.195633292 -0700
[email protected]@ -469,6 +469,11 @@ server_request_direct_streamlocal(void)
+ 	char *target, *originator;
+ 	u_short originator_port;
+ 
++	struct passwd *pw = the_authctxt->pw;
++
++	if (pw == NULL || !the_authctxt->valid)
++		fatal("server_input_global_request: no/invalid user");
++
+ 	target = packet_get_string(NULL);
+ 	originator = packet_get_string(NULL);
+ 	originator_port = packet_get_int();
[email protected]@ -480,7 +485,7 @@ server_request_direct_streamlocal(void)
+ 	/* XXX fine grained permissions */
+ 	if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
+ 	    !no_port_forwarding_flag && !options.disable_forwarding &&
+-	    use_privsep) {
++	    (pw->pw_uid == 0 || use_privsep)) {
+ 		c = channel_connect_to_path(target,
+ 		    "[email protected]", "direct-streamlocal");
+ 	} else {
[email protected]@ -702,6 +707,10 @@ server_input_global_request(int type, u_
+ 	int want_reply;
+ 	int r, success = 0, allocated_listen_port = 0;
+ 	struct sshbuf *resp = NULL;
++	struct passwd *pw = the_authctxt->pw;
++
++	if (pw == NULL || !the_authctxt->valid)
++		fatal("server_input_global_request: no/invalid user");
+ 
+ 	rtype = packet_get_string(NULL);
+ 	want_reply = packet_get_char();
[email protected]@ -709,12 +718,8 @@ server_input_global_request(int type, u_
+ 
+ 	/* -R style forwarding */
+ 	if (strcmp(rtype, "tcpip-forward") == 0) {
+-		struct passwd *pw;
+ 		struct Forward fwd;
+ 
+-		pw = the_authctxt->pw;
+-		if (pw == NULL || !the_authctxt->valid)
+-			fatal("server_input_global_request: no/invalid user");
+ 		memset(&fwd, 0, sizeof(fwd));
+ 		fwd.listen_host = packet_get_string(NULL);
+ 		fwd.listen_port = (u_short)packet_get_int();
[email protected]@ -762,9 +767,10 @@ server_input_global_request(int type, u_
+ 		/* check permissions */
+ 		if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0
+ 		    || no_port_forwarding_flag || options.disable_forwarding ||
+-		    !use_privsep) {
++		    (pw->pw_uid != 0 && !use_privsep)) {
+ 			success = 0;
+-			packet_send_debug("Server has disabled port forwarding.");
++			packet_send_debug("Server has disabled "
++			    "streamlocal forwarding.");
+ 		} else {
+ 			/* Start listening on the socket */
+ 			success = channel_setup_remote_fwd_listener(