Compare commits

...
Sign in to create a new pull request.

7 commits

Author SHA1 Message Date
Mattias Ellert
76f997a6d6 Based on openssh-8.4p1-8.fc33 2021-10-24 06:24:47 +02:00
Mattias Ellert
42f77e22d6 Based on openssh-8.4p1-7.fc33 2021-06-21 20:09:32 +02:00
Mattias Ellert
651d6b5d57 Based on openssh-8.4p1-5.fc33 2021-05-25 09:56:34 +02:00
Mattias Ellert
6c50475edd Disable MTAES 2021-03-30 10:02:52 +02:00
Mattias Ellert
85f5ecc116 Fix issue with read-only ssh buffer during gssapi key exchange
Clean up HPN patch
2021-03-16 06:59:04 +01:00
Frank Scheiner
7b2f5e53c4 Add HPN patch 2021-03-12 13:09:16 +01:00
Mattias Ellert
2bbc3688bd Based on openssh-8.4p1-5.fc33 2021-02-05 15:12:25 +01:00
8 changed files with 2844 additions and 23 deletions

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
/*.tar.bz2
/*.tar.gz
/*.tar.gz.asc
/DJM-GPG-KEY.gpg
/*.gpg

View file

@ -28,7 +28,7 @@
%global libedit 1
%global openssh_ver 8.4p1
%global openssh_rel 3
%global openssh_rel 10
Summary: An implementation of the SSH protocol with GSI authentication
Name: gsi-openssh
@ -158,11 +158,22 @@ Patch967: openssh-8.4p1-ssh-copy-id.patch
Patch968: openssh-8.4p1-sandbox-seccomp.patch
# https://bugzilla.mindrot.org/show_bug.cgi?id=3213
Patch969: openssh-8.4p1-debian-compat.patch
# https://ftp.openbsd.org/pub/OpenBSD/patches/6.8/common/015_sshagent.patch.sig
Patch970: openssh-8.4p1-cve-2021-28041.patch
# CVE-2021-41617
Patch978: openssh-8.7p1-upstream-cve-2021-41617.patch
# Fix issue with read-only ssh buffer during gssapi key exchange (#1938224)
# https://github.com/openssh-gsskex/openssh-gsskex/pull/19
Patch97: openssh-8.0p1-sshbuf-readonly.patch
# This is the patch that adds GSI support
# Based on hpn_isshd-gsi.7.5p1b.patch from Globus upstream
Patch98: openssh-8.4p1-gsissh.patch
# This is the HPN patch
# Based on https://sourceforge.net/projects/hpnssh/files/Patches/HPN-SSH%2015v1%208.4p1/
Patch99: openssh-8.4p1-hpn-15.1-modified.patch
License: BSD
Requires: /sbin/nologin
@ -302,6 +313,8 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%patch967 -p1 -b .ssh-copy-id
%patch968 -p1 -b .seccomp
%patch969 -p0 -b .debian
%patch970 -p1 -b .cve-2021-28041
%patch978 -p1 -b .cve-2021-41617
%patch200 -p1 -b .audit
%patch201 -p1 -b .audit-race
@ -309,7 +322,9 @@ gpgv2 --quiet --keyring %{SOURCE3} %{SOURCE1} %{SOURCE0}
%patch100 -p1 -b .coverity
%patch97 -p1 -b .sshbuf-ro
%patch98 -p1 -b .gsi
%patch99 -p1 -b .hpn
sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h
sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in
@ -458,7 +473,7 @@ getent passwd sshd >/dev/null || \
%files
%license LICENCE
%doc CREDITS ChangeLog OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO
%doc CREDITS ChangeLog OVERVIEW PROTOCOL* README HPN-README README.platform README.privsep README.tun README.dns README.sshd-and-gsisshd TODO
%attr(0755,root,root) %dir %{_sysconfdir}/gsissh
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/gsissh/moduli
%attr(0755,root,root) %{_bindir}/gsissh-keygen
@ -501,7 +516,29 @@ getent passwd sshd >/dev/null || \
%attr(0644,root,root) %{_tmpfilesdir}/gsissh.conf
%changelog
* Wed Dec 9 2020 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-3
* Sat Oct 23 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-10
- Based on openssh-8.4p1-8.fc33
* Mon Jun 21 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-9
- Based on openssh-8.4p1-7.fc33
* Tue May 25 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-8
- Based on openssh-8.4p1-6.fc33
* Tue Mar 30 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-7
- Disable MTAES
* Tue Mar 16 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-6
- Fix issue with read-only ssh buffer during gssapi key exchange
- Clean up HPN patch
* Thu Mar 11 2021 Frank Scheiner <scheiner@hlrs.de> - 8.4p1-5
- Add HPN patch
* Fri Feb 05 2021 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-4
- Based on openssh-8.4p1-5.fc33
* Wed Dec 09 2020 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-3
- Based on openssh-8.4p1-4.fc33
* Mon Nov 30 2020 Mattias Ellert <mattias.ellert@physics.uu.se> - 8.4p1-2

View file

@ -179,10 +179,10 @@ diff -up openssh/misc.c.role-mls openssh/misc.c
}
return NULL;
}
diff -up openssh/monitor.c.role-mls openssh/monitor.c
--- openssh/monitor.c.role-mls 2018-08-20 07:57:29.000000000 +0200
+++ openssh/monitor.c 2018-08-22 11:19:56.006844867 +0200
@@ -115,6 +115,9 @@ int mm_answer_sign(int, struct sshbuf *)
diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c
--- openssh-8.6p1/monitor.c.role-mls 2021-04-16 05:55:25.000000000 +0200
+++ openssh-8.6p1/monitor.c 2021-05-21 14:21:56.719414087 +0200
@@ -117,6 +117,9 @@ int mm_answer_sign(struct ssh *, int, st
int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *);
int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *);
int mm_answer_authserv(struct ssh *, int, struct sshbuf *);
@ -192,7 +192,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
int mm_answer_authpassword(struct ssh *, int, struct sshbuf *);
int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *);
int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *);
@@ -189,6 +192,9 @@ struct mon_table mon_dispatch_proto20[]
@@ -195,6 +198,9 @@ struct mon_table mon_dispatch_proto20[]
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
@ -202,7 +202,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
#ifdef USE_PAM
@@ -796,6 +802,9 @@ mm_answer_pwnamallow(int sock, struct ss
@@ -803,6 +809,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in
/* Allow service/style information on the auth context */
monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
@ -212,7 +212,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
#ifdef USE_PAM
@@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb
@@ -877,6 +886,26 @@ key_base_type_match(const char *method,
return found;
}
@ -239,7 +239,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
int
mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
{
@@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i
@@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh,
{
struct sshbuf *b;
const u_char *p;
@ -248,7 +248,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
size_t len;
u_char type;
int r, fail = 0;
@@ -1251,6 +1280,8 @@ monitor_valid_userblob(u_char *data, u_i
@@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh,
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
@ -257,7 +257,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",
authctxt->style ? authctxt->style : "");
@@ -1286,7 +1317,7 @@ monitor_valid_hostbasedblob(u_char *data
@@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char
{
struct sshbuf *b;
const u_char *p;
@ -266,11 +266,11 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c
size_t len;
int r, fail = 0;
u_char type;
@@ -1308,6 +1339,8 @@ monitor_valid_hostbasedblob(u_char *data
@@ -1338,6 +1370,8 @@ monitor_valid_hostbasedblob(const u_char
fail++;
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if ((s = strchr(p, '/')) != NULL)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
+ if ((s = strchr(cp, '/')) != NULL)
+ *s = '\0';
xasprintf(&userstyle, "%s%s%s", authctxt->user,
authctxt->style ? ":" : "",

View file

@ -2159,12 +2159,13 @@ index a302c79c..879fe917 100644
if (rv != CKR_OK) {
error("C_GetAttributeValue failed: %lu", rv);
return (NULL);
@@ -717,18 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
@@ -717,19 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
* ensure that none of the others are zero length.
* XXX assumes CKA_ID is always first.
*/
if (key_attr[1].ulValueLen == 0 ||
- if (key_attr[1].ulValueLen == 0 ||
- key_attr[2].ulValueLen == 0) {
+ key_attr[2].ulValueLen == 0 ||
+ if (key_attr[2].ulValueLen == 0 ||
+ key_attr[3].ulValueLen == 0) {
error("invalid attribute length");
return (NULL);
@ -2259,12 +2260,13 @@ index a302c79c..879fe917 100644
if (rv != CKR_OK) {
error("C_GetAttributeValue failed: %lu", rv);
return (NULL);
@@ -838,18 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
@@ -838,19 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
* ensure that none of the others are zero length.
* XXX assumes CKA_ID is always first.
*/
if (key_attr[1].ulValueLen == 0 ||
- if (key_attr[1].ulValueLen == 0 ||
- key_attr[2].ulValueLen == 0) {
+ key_attr[2].ulValueLen == 0 ||
+ if (key_attr[2].ulValueLen == 0 ||
+ key_attr[3].ulValueLen == 0) {
error("invalid attribute length");
return (NULL);

View file

@ -0,0 +1,152 @@
From 063e1a255b53abde1147522f9aceccfd2a7ceb9b Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 2 Mar 2021 19:45:25 +0100
Subject: [PATCH] Unbreak gsi-openssh by not holding the sshbuf structures
originated from incoming packet buffer
Keeping buffers from sshpkt_getb_froms() for breaks further packet
processing because the "derived" buffer keeps a "link" to te parent
buffer, which is then considered readonly.
This addresses the visible issue in the kexgss_server(), which
demonstrated with GSI (requiring more round trips than GSSAPI
with kerberos).
The additional two places in the client were never hit, because the host
keys are never sent as part of the gssapi key exchange but in case we
would have different server or we would start sending hostkeys as the
code is ready for that, we would hit it anyway.
Fixes #18
---
kexgssc.c | 14 ++++++++++++--
kexgsss.c | 48 ++++++++++++++++++++++++++++--------------------
2 files changed, 40 insertions(+), 22 deletions(-)
diff --git a/kexgssc.c b/kexgssc.c
index 1c62740e..29b8b031 100644
--- a/kexgssc.c
+++ b/kexgssc.c
@@ -162,11 +162,16 @@ kexgss_client(struct ssh *ssh)
do {
type = ssh_packet_read(ssh);
if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
+ char *tmp = NULL;
+ size_t tmp_len = 0;
+
debug("Received KEXGSS_HOSTKEY");
if (server_host_key_blob)
fatal("Server host key received more than once");
- if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0)
fatal("Failed to read server host key: %s", ssh_err(r));
+ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL)
+ fatal("sshbuf_from failed");
}
} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
@@ -453,11 +458,16 @@ kexgssgex_client(struct ssh *ssh)
do {
type = ssh_packet_read(ssh);
if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
+ char *tmp = NULL;
+ size_t tmp_len = 0;
+
debug("Received KEXGSS_HOSTKEY");
if (server_host_key_blob)
fatal("Server host key received more than once");
- if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0)
fatal("sshpkt failed: %s", ssh_err(r));
+ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL)
+ fatal("sshbuf_from failed");
}
} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
diff --git a/kexgsss.c b/kexgsss.c
index a2c02148..c8b7d652 100644
--- a/kexgsss.c
+++ b/kexgsss.c
@@ -64,7 +64,7 @@ kexgss_server(struct ssh *ssh)
*/
OM_uint32 ret_flags = 0;
- gss_buffer_desc gssbuf, recv_tok, msg_tok;
+ gss_buffer_desc gssbuf = {0, NULL}, recv_tok, msg_tok;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Gssctxt *ctxt = NULL;
struct sshbuf *shared_secret = NULL;
@@ -104,7 +104,7 @@ kexgss_server(struct ssh *ssh)
type = ssh_packet_read(ssh);
switch(type) {
case SSH2_MSG_KEXGSS_INIT:
- if (client_pubkey != NULL)
+ if (gssbuf.value != NULL)
fatal("Received KEXGSS_INIT after initialising");
if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
&recv_tok)) != 0 ||
@@ -135,6 +135,31 @@ kexgss_server(struct ssh *ssh)
goto out;
/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
+
+ /* Calculate the hash early so we can free the
+ * client_pubkey, which has reference to the parent
+ * buffer state->incoming_packet
+ */
+ hashlen = sizeof(hash);
+ if ((r = kex_gen_hash(
+ kex->hash_alg,
+ kex->client_version,
+ kex->server_version,
+ kex->peer,
+ kex->my,
+ empty,
+ client_pubkey,
+ server_pubkey,
+ shared_secret,
+ hash, &hashlen)) != 0)
+ goto out;
+
+ gssbuf.value = hash;
+ gssbuf.length = hashlen;
+
+ sshbuf_free(client_pubkey);
+ client_pubkey = NULL;
+
break;
case SSH2_MSG_KEXGSS_CONTINUE:
if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
@@ -156,7 +181,7 @@ kexgss_server(struct ssh *ssh)
if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
fatal("Zero length token output when incomplete");
- if (client_pubkey == NULL)
+ if (gssbuf.value == NULL)
fatal("No client public key");
if (maj_status & GSS_S_CONTINUE_NEEDED) {
@@ -185,23 +210,6 @@ kexgss_server(struct ssh *ssh)
if (!(ret_flags & GSS_C_INTEG_FLAG))
fatal("Integrity flag wasn't set");
- hashlen = sizeof(hash);
- if ((r = kex_gen_hash(
- kex->hash_alg,
- kex->client_version,
- kex->server_version,
- kex->peer,
- kex->my,
- empty,
- client_pubkey,
- server_pubkey,
- shared_secret,
- hash, &hashlen)) != 0)
- goto out;
-
- gssbuf.value = hash;
- gssbuf.length = hashlen;
-
if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
fatal("Couldn't get MIC");

View file

@ -0,0 +1,11 @@
diff -up openssh-8.4p1/ssh-agent.c.cve-2021-28041 openssh-8.4p1/ssh-agent.c
--- openssh-8.4p1/ssh-agent.c.cve-2021-28041 2021-06-17 13:15:58.691479334 +0200
+++ openssh-8.4p1/ssh-agent.c 2021-06-17 13:17:16.573118348 +0200
@@ -581,6 +581,7 @@ process_add_identity(SocketEntry *e)
goto err;
}
free(ext_name);
+ ext_name = NULL;
break;
default:
error("%s: Unknown constraint %d", __func__, ctype);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,25 @@
diff --git a/auth.c b/auth.c
index b8d1040d..0134d694 100644
--- a/auth.c
+++ b/auth.c
@@ -56,6 +56,7 @@
# include <paths.h>
#endif
#include <pwd.h>
+#include <grp.h>
#ifdef HAVE_LOGIN_H
#include <login.h>
#endif
@@ -2695,6 +2696,12 @@ subprocess(const char *tag, const char *command,
}
closefrom(STDERR_FILENO + 1);
+ if (geteuid() == 0 &&
+ initgroups(pw->pw_name, pw->pw_gid) == -1) {
+ error("%s: initgroups(%s, %u): %s", tag,
+ pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
+ _exit(1);
+ }
/* Don't use permanently_set_uid() here to avoid fatal() */
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) {
error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,