forked from pool/openssh
Accepting request 1034974 from home:hpjansson:openssh-tw
- Update openssh-8.1p1-audit.patch: Merge fix for race condition (bsc#1115550, bsc#1174162). - Add openssh-do-not-send-empty-message.patch, which prevents superfluous newlines with empty MOTD files (bsc#1192439). OBS-URL: https://build.opensuse.org/request/show/1034974 OBS-URL: https://build.opensuse.org/package/show/network/openssh?expand=0&rev=242
This commit is contained in:
parent
cb5c9c99b3
commit
4038ff6c0f
@ -1550,7 +1550,7 @@ Index: openssh-8.9p1/monitor_wrap.c
|
||||
sshbuf_free(m);
|
||||
}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
@@ -1074,3 +1114,83 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc
|
||||
@@ -1074,3 +1114,130 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc
|
||||
}
|
||||
|
||||
#endif /* GSSAPI */
|
||||
@ -1633,6 +1633,53 @@ Index: openssh-8.9p1/monitor_wrap.c
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m);
|
||||
+ sshbuf_free(m);
|
||||
+}
|
||||
+
|
||||
+int mm_forward_audit_messages(int fdin)
|
||||
+{
|
||||
+ u_char buf[4];
|
||||
+ u_int blen, msg_len;
|
||||
+ struct sshbuf *m;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ debug3("%s: entering", __func__);
|
||||
+ m = sshbuf_new();
|
||||
+ do {
|
||||
+ int r;
|
||||
+
|
||||
+ blen = atomicio(read, fdin, buf, sizeof(buf));
|
||||
+ if (blen == 0) /* closed pipe */
|
||||
+ break;
|
||||
+ if (blen != sizeof(buf)) {
|
||||
+ error("%s: Failed to read the buffer from child", __func__);
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ msg_len = get_u32(buf);
|
||||
+ if (msg_len > 256 * 1024)
|
||||
+ fatal("%s: read: bad msg_len %d", __func__, msg_len);
|
||||
+ sshbuf_reset(m);
|
||||
+ if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0)
|
||||
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
+ if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
|
||||
+ error("%s: Failed to read the the buffer conent from the child", __func__);
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen ||
|
||||
+ atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
|
||||
+ error("%s: Failed to write the messag to the monitor", __func__);
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ } while (1);
|
||||
+ sshbuf_free(m);
|
||||
+ return ret;
|
||||
+}
|
||||
+void mm_set_monitor_pipe(int fd)
|
||||
+{
|
||||
+ pmonitor->m_recvfd = fd;
|
||||
+}
|
||||
+#endif /* SSH_AUDIT_EVENTS */
|
||||
Index: openssh-8.9p1/monitor_wrap.h
|
||||
===================================================================
|
||||
@ -1649,7 +1696,7 @@ Index: openssh-8.9p1/monitor_wrap.h
|
||||
const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
|
||||
|
||||
#ifdef GSSAPI
|
||||
@@ -83,7 +85,12 @@ void mm_sshpam_free_ctx(void *);
|
||||
@@ -83,7 +85,14 @@ void mm_sshpam_free_ctx(void *);
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
#include "audit.h"
|
||||
void mm_audit_event(struct ssh *, ssh_audit_event_t);
|
||||
@ -1660,6 +1707,8 @@ Index: openssh-8.9p1/monitor_wrap.h
|
||||
+void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t);
|
||||
+void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t);
|
||||
+void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t);
|
||||
+int mm_forward_audit_messages(int);
|
||||
+void mm_set_monitor_pipe(int);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
@ -1689,7 +1738,12 @@ Index: openssh-8.9p1/packet.c
|
||||
/*
|
||||
* Returns the IP-address of the remote host as a string. The returned
|
||||
* string must not be freed.
|
||||
@@ -583,22 +591,19 @@ ssh_packet_close_internal(struct ssh *ss
|
||||
@@ -579,26 +587,23 @@ ssh_packet_rdomain_in(struct ssh *ssh)
|
||||
/* Closes the connection and clears and frees internal data structures. */
|
||||
|
||||
static void
|
||||
-ssh_packet_close_internal(struct ssh *ssh, int do_close)
|
||||
+ssh_packet_close_internal(struct ssh *ssh, int do_close, int do_audit)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
u_int mode;
|
||||
@ -1721,7 +1775,7 @@ Index: openssh-8.9p1/packet.c
|
||||
#endif /* WITH_ZLIB */
|
||||
cipher_free(state->send_context);
|
||||
cipher_free(state->receive_context);
|
||||
+ if (had_keys && state->server_side) {
|
||||
+ if (do_audit && had_keys && state->server_side) {
|
||||
+ /* Assuming this is called only from privsep child */
|
||||
+ audit_session_key_free(ssh, MODE_MAX);
|
||||
+ }
|
||||
@ -1736,7 +1790,29 @@ Index: openssh-8.9p1/packet.c
|
||||
free(ssh->local_ipaddr);
|
||||
ssh->local_ipaddr = NULL;
|
||||
free(ssh->remote_ipaddr);
|
||||
@@ -892,6 +907,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod
|
||||
@@ -650,13 +665,19 @@ ssh_packet_close_internal(struct ssh *ss
|
||||
void
|
||||
ssh_packet_close(struct ssh *ssh)
|
||||
{
|
||||
- ssh_packet_close_internal(ssh, 1);
|
||||
+ ssh_packet_close_internal(ssh, 1, 1);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_packet_clear_keys(struct ssh *ssh)
|
||||
{
|
||||
- ssh_packet_close_internal(ssh, 0);
|
||||
+ ssh_packet_close_internal(ssh, 0, 1);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+ssh_packet_clear_keys_noaudit(struct ssh *ssh)
|
||||
+{
|
||||
+ ssh_packet_close_internal(ssh, 0, 0);
|
||||
}
|
||||
|
||||
/* Sets remote side protocol flags. */
|
||||
@@ -892,6 +913,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod
|
||||
(unsigned long long)state->p_send.bytes,
|
||||
(unsigned long long)state->p_send.blocks);
|
||||
kex_free_newkeys(state->newkeys[mode]);
|
||||
@ -1744,7 +1820,7 @@ Index: openssh-8.9p1/packet.c
|
||||
state->newkeys[mode] = NULL;
|
||||
}
|
||||
/* note that both bytes and the seqnr are not reset */
|
||||
@@ -2183,6 +2199,73 @@ ssh_packet_get_output(struct ssh *ssh)
|
||||
@@ -2183,6 +2205,73 @@ ssh_packet_get_output(struct ssh *ssh)
|
||||
return (void *)ssh->state->output;
|
||||
}
|
||||
|
||||
@ -1822,7 +1898,15 @@ Index: openssh-8.9p1/packet.h
|
||||
===================================================================
|
||||
--- openssh-8.9p1.orig/packet.h
|
||||
+++ openssh-8.9p1/packet.h
|
||||
@@ -220,4 +220,5 @@ const u_char *sshpkt_ptr(struct ssh *, s
|
||||
@@ -102,6 +102,7 @@ int ssh_packet_get_connection_out(s
|
||||
void ssh_packet_close(struct ssh *);
|
||||
void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *);
|
||||
void ssh_packet_clear_keys(struct ssh *);
|
||||
+void ssh_packet_clear_keys_noaudit(struct ssh *);
|
||||
void ssh_clear_newkeys(struct ssh *, int);
|
||||
|
||||
int ssh_packet_is_rekeying(struct ssh *);
|
||||
@@ -220,4 +221,5 @@ const u_char *sshpkt_ptr(struct ssh *, s
|
||||
# undef EC_POINT
|
||||
#endif
|
||||
|
||||
@ -1841,7 +1925,18 @@ Index: openssh-8.9p1/session.c
|
||||
extern struct sshbuf *loginmsg;
|
||||
extern struct sshauthopt *auth_opts;
|
||||
extern char *tun_fwd_ifnames; /* serverloop.c */
|
||||
@@ -642,6 +642,14 @@ do_exec_pty(struct ssh *ssh, Session *s,
|
||||
@@ -157,6 +157,10 @@ static Session *sessions = NULL;
|
||||
login_cap_t *lc;
|
||||
#endif
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+int paudit[2];
|
||||
+#endif
|
||||
+
|
||||
static int is_child = 0;
|
||||
static int in_chroot = 0;
|
||||
|
||||
@@ -642,6 +646,14 @@ do_exec_pty(struct ssh *ssh, Session *s,
|
||||
/* Parent. Close the slave side of the pseudo tty. */
|
||||
close(ttyfd);
|
||||
|
||||
@ -1856,7 +1951,7 @@ Index: openssh-8.9p1/session.c
|
||||
/* Enter interactive session. */
|
||||
s->ptymaster = ptymaster;
|
||||
ssh_packet_set_interactive(ssh, 1,
|
||||
@@ -706,15 +714,19 @@ do_exec(struct ssh *ssh, Session *s, con
|
||||
@@ -706,15 +718,21 @@ do_exec(struct ssh *ssh, Session *s, con
|
||||
s->self);
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
@ -1875,23 +1970,66 @@ Index: openssh-8.9p1/session.c
|
||||
}
|
||||
+ if (s->command != NULL && s->ptyfd == -1)
|
||||
+ s->command_handle = PRIVSEP(audit_run_command(ssh, s->command));
|
||||
+ if (pipe(paudit) < 0)
|
||||
+ fatal("pipe: %s", strerror(errno));
|
||||
#endif
|
||||
if (s->ttyfd != -1)
|
||||
ret = do_exec_pty(ssh, s, command);
|
||||
@@ -1533,8 +1545,11 @@ do_child(struct ssh *ssh, Session *s, co
|
||||
@@ -730,6 +748,20 @@ do_exec(struct ssh *ssh, Session *s, con
|
||||
*/
|
||||
sshbuf_reset(loginmsg);
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ close(paudit[1]);
|
||||
+ if (use_privsep && ret == 0) {
|
||||
+ /*
|
||||
+ * Read the audit messages from forked child and send them
|
||||
+ * back to monitor. We don't want to communicate directly,
|
||||
+ * because the messages might get mixed up.
|
||||
+ * Continue after the pipe gets closed (all messages sent).
|
||||
+ */
|
||||
+ ret = mm_forward_audit_messages(paudit[0]);
|
||||
+ }
|
||||
+ close(paudit[0]);
|
||||
+#endif /* SSH_AUDIT_EVENTS */
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1530,11 +1562,30 @@ do_child(struct ssh *ssh, Session *s, co
|
||||
int env_size;
|
||||
int r = 0;
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ int pparent = paudit[1];
|
||||
+ close(paudit[0]);
|
||||
+ /* Hack the monitor pipe to avoid race condition with parent */
|
||||
+ if (use_privsep)
|
||||
+ mm_set_monitor_pipe(pparent);
|
||||
+#endif
|
||||
+
|
||||
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
|
||||
|
||||
/* remove hostkey from the child's memory */
|
||||
- destroy_sensitive_data();
|
||||
+ destroy_sensitive_data(ssh, 1);
|
||||
ssh_packet_clear_keys(ssh);
|
||||
+ /* Don't audit this - both us and the parent would be talking to the
|
||||
+ monitor over a single socket, with no synchronization. */
|
||||
- ssh_packet_clear_keys(ssh);
|
||||
+ destroy_sensitive_data(ssh, use_privsep);
|
||||
+ ssh_packet_clear_keys_noaudit(ssh);
|
||||
+ /*
|
||||
+ * We can audit this, because we hacked the pipe to direct the
|
||||
+ * messages over postauth child. But this message requires an answer
|
||||
+ * which we can't do using a one-way pipe.
|
||||
+ */
|
||||
+ packet_destroy_all(ssh, 0, 1);
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ /* Notify parent that we are done */
|
||||
+ close(pparent);
|
||||
+#endif
|
||||
|
||||
/* Force a password change */
|
||||
if (s->authctxt->force_pwchange) {
|
||||
@@ -1743,6 +1758,9 @@ session_unused(int id)
|
||||
@@ -1743,6 +1794,9 @@ session_unused(int id)
|
||||
sessions[id].ttyfd = -1;
|
||||
sessions[id].ptymaster = -1;
|
||||
sessions[id].x11_chanids = NULL;
|
||||
@ -1901,7 +2039,7 @@ Index: openssh-8.9p1/session.c
|
||||
sessions[id].next_unused = sessions_first_unused;
|
||||
sessions_first_unused = id;
|
||||
}
|
||||
@@ -1822,6 +1840,19 @@ session_open(Authctxt *authctxt, int cha
|
||||
@@ -1822,6 +1876,19 @@ session_open(Authctxt *authctxt, int cha
|
||||
}
|
||||
|
||||
Session *
|
||||
@ -1921,7 +2059,7 @@ Index: openssh-8.9p1/session.c
|
||||
session_by_tty(char *tty)
|
||||
{
|
||||
int i;
|
||||
@@ -2429,6 +2460,32 @@ session_exit_message(struct ssh *ssh, Se
|
||||
@@ -2429,6 +2496,32 @@ session_exit_message(struct ssh *ssh, Se
|
||||
chan_write_failed(ssh, c);
|
||||
}
|
||||
|
||||
@ -1954,7 +2092,7 @@ Index: openssh-8.9p1/session.c
|
||||
void
|
||||
session_close(struct ssh *ssh, Session *s)
|
||||
{
|
||||
@@ -2470,6 +2527,10 @@ session_close(struct ssh *ssh, Session *
|
||||
@@ -2470,6 +2563,10 @@ session_close(struct ssh *ssh, Session *
|
||||
|
||||
if (s->ttyfd != -1)
|
||||
session_pty_cleanup(s);
|
||||
@ -1965,7 +2103,7 @@ Index: openssh-8.9p1/session.c
|
||||
free(s->term);
|
||||
free(s->display);
|
||||
free(s->x11_chanids);
|
||||
@@ -2544,14 +2605,14 @@ session_close_by_channel(struct ssh *ssh
|
||||
@@ -2544,14 +2641,14 @@ session_close_by_channel(struct ssh *ssh
|
||||
}
|
||||
|
||||
void
|
||||
@ -1982,7 +2120,7 @@ Index: openssh-8.9p1/session.c
|
||||
else
|
||||
session_close(ssh, s);
|
||||
}
|
||||
@@ -2677,6 +2738,15 @@ do_authenticated2(struct ssh *ssh, Authc
|
||||
@@ -2677,6 +2774,15 @@ do_authenticated2(struct ssh *ssh, Authc
|
||||
server_loop2(ssh, authctxt);
|
||||
}
|
||||
|
||||
@ -1998,7 +2136,7 @@ Index: openssh-8.9p1/session.c
|
||||
void
|
||||
do_cleanup(struct ssh *ssh, Authctxt *authctxt)
|
||||
{
|
||||
@@ -2740,7 +2810,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au
|
||||
@@ -2740,7 +2846,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au
|
||||
* or if running in monitor.
|
||||
*/
|
||||
if (!use_privsep || mm_is_monitor())
|
||||
|
19
openssh-do-not-send-empty-message.patch
Normal file
19
openssh-do-not-send-empty-message.patch
Normal file
@ -0,0 +1,19 @@
|
||||
--- openssh-8.4p1.orig/auth-pam.c 2020-09-27 09:25:01.000000000 +0200
|
||||
+++ openssh-8.4p1/auth-pam.c 2022-03-04 13:02:23.447712697 +0100
|
||||
@@ -638,10 +638,12 @@
|
||||
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
|
||||
case PAM_ERROR_MSG:
|
||||
case PAM_TEXT_INFO:
|
||||
- if ((r = sshbuf_putf(loginmsg, "%s\n",
|
||||
- PAM_MSG_MEMBER(msg, i, msg))) != 0)
|
||||
- fatal("%s: buffer error: %s",
|
||||
- __func__, ssh_err(r));
|
||||
+ if (strlen(PAM_MSG_MEMBER(msg, i, msg)) != 0) {
|
||||
+ if ((r = sshbuf_putf(loginmsg, "%s\n",
|
||||
+ PAM_MSG_MEMBER(msg, i, msg))) != 0)
|
||||
+ fatal("%s: buffer error: %s",
|
||||
+ __func__, ssh_err(r));
|
||||
+ }
|
||||
reply[i].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
default:
|
@ -1,3 +1,11 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 10 02:18:08 UTC 2022 - Hans Petter Jansson <hpj@suse.com>
|
||||
|
||||
- Update openssh-8.1p1-audit.patch: Merge fix for race condition
|
||||
(bsc#1115550, bsc#1174162).
|
||||
- Add openssh-do-not-send-empty-message.patch, which prevents
|
||||
superfluous newlines with empty MOTD files (bsc#1192439).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Aug 8 07:36:55 UTC 2022 - Thorsten Kukuk <kukuk@suse.com>
|
||||
|
||||
|
@ -109,6 +109,7 @@ Patch45: openssh-8.4p1-ssh_config_d.patch
|
||||
Patch46: openssh-whitelist-syscalls.patch
|
||||
Patch47: openssh-8.4p1-vendordir.patch
|
||||
Patch48: openssh-8.4p1-pam_motd.patch
|
||||
Patch49: openssh-do-not-send-empty-message.patch
|
||||
BuildRequires: audit-devel
|
||||
BuildRequires: automake
|
||||
BuildRequires: groff
|
||||
|
Loading…
Reference in New Issue
Block a user