openssh: Update to 7.3p1.
Message ID | H000006e002c03f0.1487705969.mail.at4b.net@MHS |
---|---|
State | Dropped |
Headers |
Return-Path: <development-bounces@lists.ipfire.org> Received: from mail01.ipfire.org (unknown [172.28.1.200]) by web02.ipfire.org (Postfix) with ESMTP id 5F53162095 for <patchwork@ipfire.org>; Tue, 21 Feb 2017 20:39:40 +0100 (CET) Received: from mail01.ipfire.org (localhost [IPv6:::1]) by mail01.ipfire.org (Postfix) with ESMTP id D1653CCD; Tue, 21 Feb 2017 20:39:37 +0100 (CET) Received: from mail.at4b.net (99-111-67-20.uvs.tukrga.sbcglobal.net [99.111.67.20]) by mail01.ipfire.org (Postfix) with ESMTP id 8D43892D for <development@lists.ipfire.org>; Tue, 21 Feb 2017 20:39:31 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by mail.at4b.net (Postfix) with ESMTP id 253F7E3AC4 for <development@lists.ipfire.org>; Tue, 21 Feb 2017 14:39:30 -0500 (EST) X-Virus-Scanned: amavisd-new at at4b.com Received: from mail.at4b.net ([127.0.0.1]) by localhost (mail.at4b.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id psSYGSgH0vEy for <development@lists.ipfire.org>; Tue, 21 Feb 2017 14:39:29 -0500 (EST) Received: from mail.at4b.net (localhost [127.0.0.1]) by mail.at4b.net (Postfix) with ESMTP id AFC1FE3852 for <development@lists.ipfire.org>; Tue, 21 Feb 2017 14:39:29 -0500 (EST) Date: Tue, 21 Feb 2017 14:39:29 -0500 From: "Kienker, Fred" <fkienker@at4b.com> To: development <development@lists.ipfire.org> Message-ID: <H000006e002c03f0.1487705969.mail.at4b.net@MHS> In-Reply-To: <1480507323-2470-1-git-send-email-stefan.schantl@ipfire.org> Subject: RE: [PATCH] openssh: Update to 7.3p1. x-scalix-Hops: 1 MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: IPFire development talk <development.lists.ipfire.org> List-Unsubscribe: <http://lists.ipfire.org/mailman/options/development>, <mailto:development-request@lists.ipfire.org?subject=unsubscribe> List-Archive: <http://lists.ipfire.org/pipermail/development/> List-Post: <mailto:development@lists.ipfire.org> List-Help: <mailto:development-request@lists.ipfire.org?subject=help> List-Subscribe: <http://lists.ipfire.org/mailman/listinfo/development>, <mailto:development-request@lists.ipfire.org?subject=subscribe> Errors-To: development-bounces@lists.ipfire.org Sender: "Development" <development-bounces@lists.ipfire.org> |
Message
Kienker, Fred
Feb. 22, 2017, 6:39 a.m. UTC
FYI: This is no longer considered "current" enough to pass a PCI Compliance audit. Only a version > 7.4 will now pass due to CVE-2016-10009. Anyone using an IPFire firewall system who has to pass a PCI Compliance audit will have to disable ssh access until this is updated to at least 7.4. Fred Kienker -----Original Message----- From: Stefan Schantl [mailto:stefan.schantl@ipfire.org] Sent: Wednesday, November 30, 2016 7:02 AM To: development@lists.ipfire.org Subject: [PATCH] openssh: Update to 7.3p1. This is a major update to the latest stable version of OpenSSH. * Drop not longer required patches. * Drop SElinux support. Fixes #11218. Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org> --- openssh/openssh.nm | 8 +- openssh/patches/openssh-6.7p1-audit.patch | 2332 -------------------- .../patches/openssh-6.7p1-seccomp-aarch64.patch | 66 - 3 files changed, 3 insertions(+), 2403 deletions(-) delete mode 100644 openssh/patches/openssh-6.7p1-audit.patch delete mode 100644 openssh/patches/openssh-6.7p1-seccomp-aarch64.patch - #ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ - SC_ALLOW(mmap2),
Comments
Hi Fred, you are referring to IPFire 3 here, but I suppose that you are rather using IPFire 2 in production. This version of IPFire comes with OpenSSH 7.3p1: http://git.ipfire.org/?p=ipfire-2.x.git;a=blob;f=lfs/openssh;h=371d0df4ac09c4106f761886fa4e3f6107bd2265;hb=HEAD It would be helpful if you could give us some more context about your environment, why PCI compliance is required and what other things probably need to be mended to comply or even comply better. Best, -Michael On Tue, 2017-02-21 at 14:39 -0500, Kienker, Fred wrote: > FYI: > > This is no longer considered "current" enough to pass a PCI Compliance > audit. Only a version > 7.4 will now pass due to CVE-2016-10009. > Anyone using an IPFire firewall system who has to pass a PCI Compliance > audit will have to disable ssh access until this is updated to at least > 7.4. > > Fred Kienker > > -----Original Message----- > From: Stefan Schantl [mailto:stefan.schantl@ipfire.org] > Sent: Wednesday, November 30, 2016 7:02 AM > To: development@lists.ipfire.org > Subject: [PATCH] openssh: Update to 7.3p1. > > This is a major update to the latest stable version of OpenSSH. > > * Drop not longer required patches. > * Drop SElinux support. > > Fixes #11218. > > Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org> > --- > openssh/openssh.nm | 8 +- > openssh/patches/openssh-6.7p1-audit.patch | 2332 > -------------------- > .../patches/openssh-6.7p1-seccomp-aarch64.patch | 66 - > 3 files changed, 3 insertions(+), 2403 deletions(-) > delete mode 100644 openssh/patches/openssh-6.7p1-audit.patch > delete mode 100644 openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > > diff --git a/openssh/openssh.nm b/openssh/openssh.nm > index 8489438..2e8de76 100644 > --- a/openssh/openssh.nm > +++ b/openssh/openssh.nm > @@ -4,8 +4,8 @@ > ####################################################################### > ######## > > name = openssh > -version = 6.8p1 > -release = 2 > +version = 7.3p1 > +release = 1 > > groups = Application/Internet > url = http://www.openssh.com/portable.html > @@ -28,10 +28,9 @@ build > automake > groff > libedit-devel > - libselinux-devel > ncurses-devel > openldap-devel > - openssl-devel >= 1.0.0d-2 > + openssl-devel >= 1.0.2 > pam-devel > util-linux > zlib-devel > @@ -51,7 +50,6 @@ build > --with-ipaddr-display \ > --with-pam \ > --with-libedit \ > - --with-selinux \ > --with-audit=linux > > prepare_cmds > diff --git a/openssh/patches/openssh-6.7p1-audit.patch > b/openssh/patches/openssh-6.7p1-audit.patch > deleted file mode 100644 > index 213ca67..0000000 > --- a/openssh/patches/openssh-6.7p1-audit.patch > +++ /dev/null > @@ -1,2332 +0,0 @@ > -diff -up openssh-6.8p1/Makefile.in.audit openssh-6.8p1/Makefile.in > ---- openssh-6.8p1/Makefile.in.audit 2015-03-20 13:41:15.065883826 > +0100 > -+++ openssh-6.8p1/Makefile.in 2015-03-20 13:41:15.100883769 +0100 > -@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ > - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o > \ > - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ > - kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ > -- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o > -+ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o > - > - SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ > - sshconnect.o sshconnect1.o sshconnect2.o mux.o \ > -diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c > ---- openssh-6.8p1/audit-bsm.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/audit-bsm.c 2015-03-20 13:41:15.092883782 +0100 > -@@ -375,10 +375,23 @@ audit_connection_from(const char *host, > - #endif > - } > - > --void > -+int > - audit_run_command(const char *command) > - { > - /* not implemented */ > -+ return 0; > -+} > -+ > -+void > -+audit_end_command(int handle, const char *command) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_count_session_open(void) > -+{ > -+ /* not necessary */ > - } > - > - void > -@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li) > - /* not implemented */ > - } > - > -+int > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > *fp, int rv) > -+{ > -+ /* not implemented */ > -+} > -+ > - void > - audit_event(ssh_audit_event_t event) > - { > -@@ -454,4 +473,40 @@ audit_event(ssh_audit_event_t event) > - debug("%s: unhandled event %d", __func__, event); > - } > - } > -+ > -+void > -+audit_unsupported_body(int what) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > *pfs, pid_t pid, uid_t uid) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_destroy_sensitive_data(const char *fp) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_generate_ephemeral_server_key(const char *fp) > -+{ > -+ /* not implemented */ > -+} > - #endif /* BSM */ > -diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c > ---- openssh-6.8p1/audit-linux.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/audit-linux.c 2015-03-20 13:41:15.093883780 +0100 > -@@ -35,13 +35,25 @@ > - > - #include "log.h" > - #include "audit.h" > -+#include "key.h" > -+#include "hostfile.h" > -+#include "auth.h" > -+#include "misc.h" /* servconf.h needs misc.h for struct > ForwardOptions */ > -+#include "servconf.h" > - #include "canohost.h" > -+#include "packet.h" > -+#include "cipher.h" > - > -+#define AUDIT_LOG_SIZE 256 > -+ > -+extern ServerOptions options; > -+extern Authctxt *the_authctxt; > -+extern u_int utmp_len; > - const char* audit_username(void); > - > --int > --linux_audit_record_event(int uid, const char *username, > -- const char *hostname, const char *ip, const char *ttyn, int > success) > -+static void > -+linux_audit_user_logxxx(int uid, const char *username, > -+ const char *hostname, const char *ip, const char *ttyn, int > success, int event) > - { > - int audit_fd, rc, saved_errno; > - > -@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const char > *username, > - if (audit_fd < 0) { > - if (errno == EINVAL || errno == EPROTONOSUPPORT || > - errno == EAFNOSUPPORT) > -- return 1; /* No audit support in kernel */ > -+ return; /* No audit support in kernel */ > - else > -- return 0; /* Must prevent login */ > -+ goto fatal_report; /* Must prevent login */ > - } > -- rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, > -+ rc = audit_log_acct_message(audit_fd, event, > - NULL, "login", username ? username : "(unknown)", > - username == NULL ? uid : -1, hostname, ip, ttyn, success); > - saved_errno = errno; > -@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const char > *username, > - if ((rc == -EPERM) && (geteuid() != 0)) > - rc = 0; > - errno = saved_errno; > -- return (rc >= 0); > -+ if (rc < 0) { > -+fatal_report: > -+ fatal("linux_audit_write_entry failed: %s", > strerror(errno)); > -+ } > - } > - > -+static void > -+linux_audit_user_auth(int uid, const char *username, > -+ const char *hostname, const char *ip, const char *ttyn, int > success, int event) > -+{ > -+ int audit_fd, rc, saved_errno; > -+ static const char *event_name[] = { > -+ "maxtries exceeded", > -+ "root denied", > -+ "success", > -+ "none", > -+ "password", > -+ "challenge-response", > -+ "pubkey", > -+ "hostbased", > -+ "gssapi", > -+ "invalid user", > -+ "nologin", > -+ "connection closed", > -+ "connection abandoned", > -+ "unknown" > -+ }; > -+ > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > -+ errno == EAFNOSUPPORT) > -+ return; /* No audit support in kernel */ > -+ else > -+ goto fatal_report; /* Must prevent login */ > -+ } > -+ > -+ if ((event < 0) || (event > SSH_AUDIT_UNKNOWN)) > -+ event = SSH_AUDIT_UNKNOWN; > -+ > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, > -+ NULL, event_name[event], username ? username : "(unknown)", > -+ username == NULL ? uid : -1, hostname, ip, ttyn, success); > -+ saved_errno = errno; > -+ close(audit_fd); > -+ /* > -+ * Do not report error if the error is EPERM and sshd is run as > non > -+ * root user. > -+ */ > -+ if ((rc == -EPERM) && (geteuid() != 0)) > -+ rc = 0; > -+ errno = saved_errno; > -+ if (rc < 0) { > -+fatal_report: > -+ fatal("linux_audit_write_entry failed: %s", > strerror(errno)); > -+ } > -+} > -+ > -+int > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > *fp, int rv) > -+{ > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, rc, saved_errno; > -+ > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > -+ errno == EAFNOSUPPORT) > -+ return 1; /* No audit support in kernel */ > -+ else > > > > -+ return 0; /* Must prevent login */ > -+ } > -+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? > "pubkey" : "hostbased", get_remote_port()); > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, > -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, > rv); > -+ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) > -+ goto out; > -+ /* is the fingerprint_prefix() still needed? > -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s > rport=%d", > -+ type, bits, sshkey_fingerprint_prefix(), fp, > get_remote_port()); > -+ */ > -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", > -+ type, bits, fp, get_remote_port()); > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, > -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, > rv); > -+out: > -+ saved_errno = errno; > -+ audit_close(audit_fd); > -+ errno = saved_errno; > -+ /* do not report error if the error is EPERM and sshd is run as > non root user */ > -+ return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0)); > -+} > -+ > -+static int user_login_count = 0; > -+ > - /* Below is the sshd audit API code */ > - > - void > - audit_connection_from(const char *host, int port) > - { > --} > - /* not implemented */ > -+} > - > --void > -+int > - audit_run_command(const char *command) > - { > -- /* not implemented */ > -+ if (!user_login_count++) > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_LOGIN); > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_START); > -+ return 0; > -+} > -+ > -+void > -+audit_end_command(int handle, const char *command) > -+{ > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_END); > -+ if (user_login_count && !--user_login_count) > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); > -+} > -+ > -+void > -+audit_count_session_open(void) > -+{ > -+ user_login_count++; > - } > - > - void > - audit_session_open(struct logininfo *li) > - { > -- if (linux_audit_record_event(li->uid, NULL, li->hostname, > -- NULL, li->line, 1) == 0) > -- fatal("linux_audit_write_entry failed: %s", > strerror(errno)); > -+ if (!user_login_count++) > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > -+ NULL, li->line, 1, AUDIT_USER_LOGIN); > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > -+ NULL, li->line, 1, AUDIT_USER_START); > - } > - > - void > - audit_session_close(struct logininfo *li) > - { > -- /* not implemented */ > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > -+ NULL, li->line, 1, AUDIT_USER_END); > -+ if (user_login_count && !--user_login_count) > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > -+ NULL, li->line, 1, AUDIT_USER_LOGOUT); > - } > - > - void > -@@ -101,21 +232,43 @@ audit_event(ssh_audit_event_t event) > - { > - switch(event) { > - case SSH_AUTH_SUCCESS: > -- case SSH_CONNECTION_CLOSE: > -+ linux_audit_user_auth(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 1, event); > -+ break; > -+ > - case SSH_NOLOGIN: > -- case SSH_LOGIN_EXCEED_MAXTRIES: > - case SSH_LOGIN_ROOT_DENIED: > -+ linux_audit_user_auth(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 0, event); > -+ linux_audit_user_logxxx(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); > - break; > - > -+ case SSH_LOGIN_EXCEED_MAXTRIES: > - case SSH_AUTH_FAIL_NONE: > - case SSH_AUTH_FAIL_PASSWD: > - case SSH_AUTH_FAIL_KBDINT: > - case SSH_AUTH_FAIL_PUBKEY: > - case SSH_AUTH_FAIL_HOSTBASED: > - case SSH_AUTH_FAIL_GSSAPI: > -+ linux_audit_user_auth(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 0, event); > -+ break; > -+ > -+ case SSH_CONNECTION_CLOSE: > -+ if (user_login_count) { > -+ while (user_login_count--) > -+ linux_audit_user_logxxx(the_authctxt->pw- > >pw_uid, > NULL, get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_END); > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, > NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); > -+ } > -+ break; > -+ > -+ case SSH_CONNECTION_ABANDON: > - case SSH_INVALID_USER: > -- linux_audit_record_event(-1, audit_username(), NULL, > -- get_remote_ipaddr(), "sshd", 0); > -+ linux_audit_user_logxxx(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); > - break; > - > - default: > -@@ -123,4 +276,135 @@ audit_event(ssh_audit_event_t event) > - } > - } > - > -+void > -+audit_unsupported_body(int what) > -+{ > -+#ifdef AUDIT_CRYPTO_SESSION > -+ char buf[AUDIT_LOG_SIZE]; > -+ const static char *name[] = { "cipher", "mac", "comp" }; > -+ char *s; > -+ int audit_fd; > -+ > -+ snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? > cipher=? ksize=? rport=%d laddr=%s lport=%d ", > -+ name[what], get_remote_port(), (s = > get_local_ipaddr(packet_get_connection_in())), > -+ get_local_port()); > -+ free(s); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) > -+ /* no problem, the next instruction will be fatal() */ > -+ return; > -+ audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, > -+ buf, NULL, get_remote_ipaddr(), NULL, 0); > -+ audit_close(audit_fd); > -+#endif > -+} > -+ > -+const static char *direction[] = { "from-server", "from-client", > "both" }; > -+ > -+void > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > *pfs, pid_t pid, > -+ uid_t uid) > -+{ > -+#ifdef AUDIT_CRYPTO_SESSION > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, audit_ok; > -+ const Cipher *cipher = cipher_by_name(enc); > -+ char *s; > -+ > -+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s > ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", > -+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, > mac, > pfs, > -+ (intmax_t)pid, (intmax_t)uid, > -+ get_remote_port(), (s = > get_local_ipaddr(packet_get_connection_in())), get_local_port()); > -+ free(s); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > -+ errno == EAFNOSUPPORT) > -+ return; /* No audit support in kernel */ > -+ else > > > > -+ fatal("cannot open audit"); /* Must prevent login */ > -+ } > -+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, > -+ buf, NULL, get_remote_ipaddr(), NULL, 1); > -+ audit_close(audit_fd); > -+ /* do not abort if the error is EPERM and sshd is run as non root > user */ > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > -+ fatal("cannot write into audit"); /* Must prevent login */ > -+#endif > -+} > -+ > -+void > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, audit_ok; > -+ char *s; > -+ > -+ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? > direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", > -+ direction[ctos], (intmax_t)pid, (intmax_t)uid, > -+ get_remote_port(), > -+ (s = get_local_ipaddr(packet_get_connection_in())), > -+ get_local_port()); > -+ free(s); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > -+ errno != EAFNOSUPPORT) > -+ error("cannot open audit"); > -+ return; > -+ } > -+ audit_ok = audit_log_user_message(audit_fd, > AUDIT_CRYPTO_KEY_USER, > -+ buf, NULL, get_remote_ipaddr(), NULL, 1); > -+ audit_close(audit_fd); > -+ /* do not abort if the error is EPERM and sshd is run as non root > user */ > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > -+ error("cannot write into audit"); > -+} > -+ > -+void > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > -+{ > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, audit_ok; > -+ > -+ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s > direction=? spid=%jd suid=%jd ", > -+ fp, (intmax_t)pid, (intmax_t)uid); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > -+ errno != EAFNOSUPPORT) > -+ error("cannot open audit"); > -+ return; > -+ } > -+ audit_ok = audit_log_user_message(audit_fd, > AUDIT_CRYPTO_KEY_USER, > -+ buf, NULL, > -+ listening_for_clients() ? get_remote_ipaddr() : > NULL, > -+ NULL, 1); > -+ audit_close(audit_fd); > -+ /* do not abort if the error is EPERM and sshd is run as non root > user */ > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > -+ error("cannot write into audit"); > -+} > -+ > -+void > -+audit_generate_ephemeral_server_key(const char *fp) > -+{ > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, audit_ok; > -+ > -+ snprintf(buf, sizeof(buf), "op=create kind=server fp=%s > direction=? ", fp); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > -+ errno != EAFNOSUPPORT) > -+ error("cannot open audit"); > -+ return; > -+ } > -+ audit_ok = audit_log_user_message(audit_fd, > AUDIT_CRYPTO_KEY_USER, > -+ buf, NULL, 0, NULL, 1); > -+ audit_close(audit_fd); > -+ /* do not abort if the error is EPERM and sshd is run as non root > user */ > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > -+ error("cannot write into audit"); > -+} > - #endif /* USE_LINUX_AUDIT */ > -diff -up openssh-6.8p1/audit.c.audit openssh-6.8p1/audit.c > ---- openssh-6.8p1/audit.c.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/audit.c 2015-03-20 13:41:15.093883780 +0100 > -@@ -28,6 +28,7 @@ > - > - #include <stdarg.h> > - #include <string.h> > -+#include <unistd.h> > - > - #ifdef SSH_AUDIT_EVENTS > - > -@@ -36,6 +37,11 @@ > - #include "key.h" > - #include "hostfile.h" > - #include "auth.h" > -+#include "ssh-gss.h" > -+#include "monitor_wrap.h" > -+#include "xmalloc.h" > -+#include "misc.h" > -+#include "servconf.h" > - > - /* > - * Care must be taken when using this since it WILL NOT be initialized > when > -@@ -43,6 +49,7 @@ > - * audit_event(CONNECTION_ABANDON) is called. Test for NULL before > using. > - */ > - extern Authctxt *the_authctxt; > -+extern ServerOptions options; > - > - /* Maybe add the audit class to struct Authmethod? */ > - ssh_audit_event_t > -@@ -71,13 +78,10 @@ audit_classify_auth(const char *method) > - const char * > - audit_username(void) > - { > -- static const char unknownuser[] = "(unknown user)"; > -- static const char invaliduser[] = "(invalid user)"; > -+ static const char unknownuser[] = "(unknown)"; > - > -- if (the_authctxt == NULL || the_authctxt->user == NULL) > -+ if (the_authctxt == NULL || the_authctxt->user == NULL || > !the_authctxt->valid) > - return (unknownuser); > -- if (!the_authctxt->valid) > -- return (invaliduser); > - return (the_authctxt->user); > - } > - > -@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) > - return(event_lookup[i].name); > - } > - > -+void > -+audit_key(int host_user, int *rv, const Key *key) > -+{ > -+ char *fp; > -+ const char *crypto_name; > -+ > -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, > SSH_FP_HEX); > -+ if (key->type == KEY_RSA1) > -+ crypto_name = "ssh-rsa1"; > -+ else > -+ crypto_name = key_ssh_name(key); > -+ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, > *rv) == 0) > -+ *rv = 0; > -+ free(fp); > -+} > -+ > -+void > -+audit_unsupported(int what) > -+{ > -+ PRIVSEP(audit_unsupported_body(what)); > -+} > -+ > -+void > -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) > -+{ > -+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), > getuid())); > -+} > -+ > -+void > -+audit_session_key_free(int ctos) > -+{ > -+ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); > -+} > -+ > - # ifndef CUSTOM_SSH_AUDIT_EVENTS > - /* > - * Null implementations of audit functions. > -@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) > - } > - > - /* > -+ * Called when a child process has called, or will soon call, > -+ * audit_session_open. > -+ */ > -+void > -+audit_count_session_open(void) > -+{ > -+ debug("audit count session open euid %d user %s", geteuid(), > -+ audit_username()); > -+} > -+ > -+/* > - * Called when a user session is started. Argument is the tty > allocated to > - * the session, or NULL if no tty was allocated. > - * > -@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li) > - /* > - * This will be called when a user runs a non-interactive command. > Note that > - * it may be called multiple times for a single connection since SSH2 > allows > -- * multiple sessions within a single connection. > -+ * multiple sessions within a single connection. Returns a "handle" > for > -+ * audit_end_command. > - */ > --void > -+int > - audit_run_command(const char *command) > - { > - debug("audit run command euid %d user %s command '%.200s'", > geteuid(), > - audit_username(), command); > -+ return 0; > -+} > -+ > -+/* > -+ * This will be called when the non-interactive command finishes. > Note that > -+ * it may be called multiple times for a single connection since SSH2 > allows > -+ * multiple sessions within a single connection. "handle" should come > from > -+ * the corresponding audit_run_command. > -+ */ > -+void > -+audit_end_command(int handle, const char *command) > -+{ > -+ debug("audit end nopty exec euid %d user %s command '%.200s'", > geteuid(), > -+ audit_username(), command); > -+} > -+ > -+/* > -+ * This will be called when user is successfully autherized by the > RSA1/RSA/DSA key. > -+ * > -+ * Type is the key type, len is the key length(byte) and fp is the > fingerprint of the key. > -+ */ > -+int > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > *fp, int rv) > -+{ > -+ debug("audit %s key usage euid %d user %s key type %s key length > %d fingerprint %s%s, result %d", > -+ host_user ? "pubkey" : "hostbased", geteuid(), > audit_username(), type, bits, > -+ sshkey_fingerprint_prefix(), fp, rv); > -+} > -+ > -+/* > -+ * This will be called when the protocol negotiation fails. > -+ */ > -+void > -+audit_unsupported_body(int what) > -+{ > -+ debug("audit unsupported protocol euid %d type %d", geteuid(), > what); > -+} > -+ > -+/* > -+ * This will be called on succesfull protocol negotiation. > -+ */ > -+void > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > *pfs, pid_t pid, > -+ uid_t uid) > -+{ > -+ debug("audit protocol negotiation euid %d direction %d cipher %s > mac %s compresion %s pfs %s from pid %ld uid %u", > -+ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, > (long)pid, > -+ (unsigned)uid); > -+} > -+ > -+/* > -+ * This will be called on succesfull session key discard > -+ */ > -+void > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+ debug("audit session key discard euid %u direction %d from pid > %ld uid %u", > -+ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); > -+} > -+ > -+/* > -+ * This will be called on destroy private part of the server key > -+ */ > -+void > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > -+{ > -+ debug("audit destroy sensitive data euid %d fingerprint %s from > pid %ld uid %u", > -+ geteuid(), fp, (long)pid, (unsigned)uid); > -+} > -+ > -+/* > -+ * This will be called on generation of the ephemeral server key > -+ */ > -+void > -+audit_generate_ephemeral_server_key(const char *) > -+{ > -+ debug("audit create ephemeral server key euid %d fingerprint %s", > geteuid(), fp); > - } > - # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ > - #endif /* SSH_AUDIT_EVENTS */ > -diff -up openssh-6.8p1/audit.h.audit openssh-6.8p1/audit.h > ---- openssh-6.8p1/audit.h.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/audit.h 2015-03-20 13:41:15.093883780 +0100 > -@@ -28,6 +28,7 @@ > - # define _SSH_AUDIT_H > - > - #include "loginrec.h" > -+#include "key.h" > - > - enum ssh_audit_event_type { > - SSH_LOGIN_EXCEED_MAXTRIES, > -@@ -47,11 +48,25 @@ enum ssh_audit_event_type { > - }; > - typedef enum ssh_audit_event_type ssh_audit_event_t; > - > -+int listening_for_clients(void); > -+ > - void audit_connection_from(const char *, int); > - void audit_event(ssh_audit_event_t); > -+void audit_count_session_open(void); > - void audit_session_open(struct logininfo *); > - void audit_session_close(struct logininfo *); > --void audit_run_command(const char *); > -+int audit_run_command(const char *); > -+void audit_end_command(int, const char *); > - ssh_audit_event_t audit_classify_auth(const char *); > -+int audit_keyusage(int, const char *, unsigned, char *, int); > -+void audit_key(int, int *, const Key *); > -+void audit_unsupported(int); > -+void audit_kex(int, char *, char *, char *, char *); > -+void audit_unsupported_body(int); > -+void audit_kex_body(int, char *, char *, char *, char *, pid_t, > uid_t); > -+void audit_session_key_free(int ctos); > -+void audit_session_key_free_body(int ctos, pid_t, uid_t); > -+void audit_destroy_sensitive_data(const char *, pid_t, uid_t); > -+void audit_generate_ephemeral_server_key(const char *); > - > - #endif /* _SSH_AUDIT_H */ > -diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c > ---- openssh-6.8p1/auditstub.c.audit 2015-03-20 13:41:15.093883780 > +0100 > -+++ openssh-6.8p1/auditstub.c 2015-03-20 13:41:15.093883780 +0100 > -@@ -0,0 +1,50 @@ > -+/* $Id: auditstub.c,v 1.1 jfch Exp $ */ > -+ > -+/* > -+ * Copyright 2010 Red Hat, Inc. All rights reserved. > -+ * Use is subject to license terms. > -+ * > -+ * Redistribution and use in source and binary forms, with or without > -+ * modification, are permitted provided that the following conditions > -+ * are met: > -+ * 1. Redistributions of source code must retain the above copyright > -+ * notice, this list of conditions and the following disclaimer. > -+ * 2. Redistributions in binary form must reproduce the above > copyright > -+ * notice, this list of conditions and the following disclaimer in > the > -+ * documentation and/or other materials provided with the > distribution. > -+ * > -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS > OR > -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > WARRANTIES > -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > DISCLAIMED. > -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES > (INCLUDING, BUT > -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS > OF USE, > -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON > ANY > -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE > USE OF > -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > -+ * > -+ * Red Hat author: Jan F. Chadima <jchadima@redhat.com> > -+ */ > -+ > -+#include <sys/types.h> > -+ > -+void > -+audit_unsupported(int n) > -+{ > -+} > -+ > -+void > -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) > -+{ > -+} > -+ > -+void > -+audit_session_key_free(int ctos) > -+{ > -+} > -+ > -+void > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+} > -diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c > ---- openssh-6.8p1/auth-rsa.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/auth-rsa.c 2015-03-20 13:41:15.094883779 +0100 > -@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNUM > *challenge, u_char response[16]) > - { > - u_char buf[32], mdbuf[16]; > - struct ssh_digest_ctx *md; > -- int len; > -+ int len, rv; > -+#ifdef SSH_AUDIT_EVENTS > -+ char *fp; > -+#endif > - > - /* don't allow short keys */ > - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { > -@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNUM > *challenge, u_char response[16]) > - ssh_digest_free(md); > - > - /* Verify that the response is the original challenge. */ > -- if (timingsafe_bcmp(response, mdbuf, 16) != 0) { > -- /* Wrong answer. */ > -- return (0); > -+ rv = timingsafe_bcmp(response, mdbuf, 16) == 0; > -+ > -+#ifdef SSH_AUDIT_EVENTS > -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, > SSH_FP_HEX); > -+ if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) > == 0) { > -+ debug("unsuccessful audit"); > -+ rv = 0; > - } > -- /* Correct answer. */ > -- return (1); > -+ free(fp); > -+#endif > -+ > -+ return rv; > - } > - > - /* > -diff -up openssh-6.8p1/auth.c.audit openssh-6.8p1/auth.c > ---- openssh-6.8p1/auth.c.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/auth.c 2015-03-20 13:41:15.094883779 +0100 > -@@ -644,9 +644,6 @@ getpwnamallow(const char *user) > - record_failed_login(user, > - get_canonical_hostname(options.use_dns), "ssh"); > - #endif > --#ifdef SSH_AUDIT_EVENTS > -- audit_event(SSH_INVALID_USER); > --#endif /* SSH_AUDIT_EVENTS */ > - return (NULL); > - } > - if (!allowed_user(pw)) > -diff -up openssh-6.8p1/auth.h.audit openssh-6.8p1/auth.h > ---- openssh-6.8p1/auth.h.audit 2015-03-20 13:41:15.002883927 +0100 > -+++ openssh-6.8p1/auth.h 2015-03-20 13:41:15.094883779 +0100 > -@@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt > - > - char *expand_authorized_keys(const char *, struct passwd *pw); > - char *authorized_principals_file(struct passwd *); > -+int user_key_verify(const Key *, const u_char *, u_int, const > u_char *, u_int); > - > - FILE *auth_openkeyfile(const char *, struct passwd *, int); > - FILE *auth_openprincipals(const char *, struct passwd *, int); > -@@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc > - int ssh1_session_key(BIGNUM *); > - int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, > - const u_char *, size_t, u_int); > -+int hostbased_key_verify(const Key *, const u_char *, u_int, > const u_char *, u_int); > - > - /* debug messages during authentication */ > - void auth_debug_add(const char *fmt,...) > __attribute__((format(printf, 1, 2))); > -diff -up openssh-6.8p1/auth2-hostbased.c.audit > openssh-6.8p1/auth2-hostbased.c > ---- openssh-6.8p1/auth2-hostbased.c.audit 2015-03-20 > 13:41:15.002883927 +0100 > -+++ openssh-6.8p1/auth2-hostbased.c 2015-03-20 13:41:15.093883780 > +0100 > -@@ -147,7 +147,7 @@ userauth_hostbased(Authctxt *authctxt) > - /* test for allowed key and correct signature */ > - authenticated = 0; > - if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, > key)) && > -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), > -+ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b), > - buffer_len(&b))) == 1) > - authenticated = 1; > - > -@@ -164,6 +164,18 @@ done: > - return authenticated; > - } > - > -+int > -+hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, > const u_char *data, u_int datalen) > -+{ > -+ int rv; > -+ > -+ rv = key_verify(key, sig, slen, data, datalen); > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_key(0, &rv, key); > -+#endif > -+ return rv; > -+} > -+ > - /* return 1 if given hostkey is allowed */ > - int > - hostbased_key_allowed(struct passwd *pw, const char *cuser, char > *chost, > -diff -up openssh-6.8p1/auth2-pubkey.c.audit > openssh-6.8p1/auth2-pubkey.c > ---- openssh-6.8p1/auth2-pubkey.c.audit 2015-03-20 > 13:41:15.013883910 +0100 > -+++ openssh-6.8p1/auth2-pubkey.c 2015-03-20 13:41:15.094883779 > +0100 > -@@ -172,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt) > - /* test for correct signature */ > - authenticated = 0; > - if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && > -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), > -+ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), > - buffer_len(&b))) == 1) { > - authenticated = 1; > - /* Record the successful key to prevent reuse */ > -@@ -250,6 +250,18 @@ pubkey_auth_info(Authctxt *authctxt, con > - free(extra); > - } > - > -+int > -+user_key_verify(const Key *key, const u_char *sig, u_int slen, const > u_char *data, u_int datalen) > -+{ > -+ int rv; > -+ > -+ rv = key_verify(key, sig, slen, data, datalen); > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_key(1, &rv, key); > -+#endif > -+ return rv; > -+} > -+ > - static int > - match_principals_option(const char *principal_list, struct sshkey_cert > *cert) > - { > -diff -up openssh-6.8p1/auth2.c.audit openssh-6.8p1/auth2.c > ---- openssh-6.8p1/auth2.c.audit 2015-03-20 13:41:15.044883860 +0100 > -+++ openssh-6.8p1/auth2.c 2015-03-20 13:41:15.093883780 +0100 > -@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 > - } else { > - logit("input_userauth_request: invalid user %s", > user); > - authctxt->pw = fakepw(); > --#ifdef SSH_AUDIT_EVENTS > -- PRIVSEP(audit_event(SSH_INVALID_USER)); > --#endif > - } > - #ifdef USE_PAM > - if (options.use_pam) > -diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c > ---- openssh-6.8p1/cipher.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/cipher.c 2015-03-20 13:41:15.101883767 +0100 > -@@ -57,26 +59,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v > - extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); > - #endif > - > --struct sshcipher { > -- char *name; > -- int number; /* for ssh1 only */ > -- u_int block_size; > -- u_int key_len; > -- u_int iv_len; /* defaults to block_size */ > -- u_int auth_len; > -- u_int discard_len; > -- u_int flags; > --#define CFLAG_CBC (1<<0) > --#define CFLAG_CHACHAPOLY (1<<1) > --#define CFLAG_AESCTR (1<<2) > --#define CFLAG_NONE (1<<3) > --#ifdef WITH_OPENSSL > -- const EVP_CIPHER *(*evptype)(void); > --#else > -- void *ignored; > --#endif > --}; > -- > - static const struct sshcipher ciphers[] = { > - #ifdef WITH_SSH1 > - { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, > -diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h > ---- openssh-6.8p1/cipher.h.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/cipher.h 2015-03-20 13:41:15.094883779 +0100 > -@@ -62,7 +62,26 @@ > - #define CIPHER_ENCRYPT 1 > - #define CIPHER_DECRYPT 0 > - > --struct sshcipher; > -+struct sshcipher { > -+ char *name; > -+ int number; /* for ssh1 only */ > -+ u_int block_size; > -+ u_int key_len; > -+ u_int iv_len; /* defaults to block_size */ > -+ u_int auth_len; > -+ u_int discard_len; > -+ u_int flags; > -+#define CFLAG_CBC (1<<0) > -+#define CFLAG_CHACHAPOLY (1<<1) > -+#define CFLAG_AESCTR (1<<2) > -+#define CFLAG_NONE (1<<3) > -+#ifdef WITH_OPENSSL > -+ const EVP_CIPHER *(*evptype)(void); > -+#else > -+ void *ignored; > -+#endif > -+}; > -+ > - struct sshcipher_ctx { > - int plaintext; > - int encrypt; > -diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c > ---- openssh-6.8p1/kex.c.audit 2015-03-20 13:41:15.046883856 +0100 > -+++ openssh-6.8p1/kex.c 2015-03-20 13:41:15.101883767 +0100 > -@@ -54,6 +55,7 @@ > - #include "ssherr.h" > - #include "sshbuf.h" > - #include "digest.h" > -+#include "audit.h" > - > - #ifdef GSSAPI > - #include "ssh-gss.h" > -@@ -484,8 +508,12 @@ choose_enc(struct sshenc *enc, char *cli > - { > - char *name = match_list(client, server, NULL); > - > -- if (name == NULL) > -+ if (name == NULL) { > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_unsupported(0); > -+#endif > - return SSH_ERR_NO_CIPHER_ALG_MATCH; > -+ } > - if ((enc->cipher = cipher_by_name(name)) == NULL) > - return SSH_ERR_INTERNAL_ERROR; > - enc->name = name; > -@@ -503,8 +531,12 @@ choose_mac(struct ssh *ssh, struct sshma > - { > - char *name = match_list(client, server, NULL); > - > -- if (name == NULL) > -+ if (name == NULL) { > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_unsupported(1); > -+#endif > - return SSH_ERR_NO_MAC_ALG_MATCH; > -+ } > - if (mac_setup(mac, name) < 0) > - return SSH_ERR_INTERNAL_ERROR; > - /* truncate the key */ > -@@ -521,8 +553,12 @@ choose_comp(struct sshcomp *comp, char * > - { > - char *name = match_list(client, server, NULL); > - > -- if (name == NULL) > -+ if (name == NULL) { > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_unsupported(2); > -+#endif > - return SSH_ERR_NO_COMPRESS_ALG_MATCH; > -+ } > - if (strcmp(name, "zlib@openssh.com") == 0) { > - comp->type = COMP_DELAYED; > - } else if (strcmp(name, "zlib") == 0) { > -@@ -672,6 +708,10 @@ kex_choose_conf(struct ssh *ssh) > - dh_need = MAX(dh_need, newkeys->enc.block_size); > - dh_need = MAX(dh_need, newkeys->enc.iv_len); > - dh_need = MAX(dh_need, newkeys->mac.key_len); > -+ debug("kex: %s need=%d dh_need=%d", kex->name, need, > dh_need); > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_kex(mode, newkeys->enc.name, newkeys->mac.name, > newkeys->comp.name, kex->name); > -+#endif > - } > - /* XXX need runden? */ > - kex->we_need = need; > -@@ -847,3 +887,34 @@ dump_digest(char *msg, u_char *digest, i > - sshbuf_dump_data(digest, len, stderr); > - } > - #endif > -+ > -+static void > -+enc_destroy(struct sshenc *enc) > -+{ > -+ if (enc == NULL) > -+ return; > -+ > -+ if (enc->key) { > -+ memset(enc->key, 0, enc->key_len); > -+ free(enc->key); > -+ } > -+ > -+ if (enc->iv) { > -+ memset(enc->iv, 0, enc->block_size); > -+ free(enc->iv); > -+ } > -+ > -+ memset(enc, 0, sizeof(*enc)); > -+} > -+ > -+void > -+newkeys_destroy(struct newkeys *newkeys) > -+{ > -+ if (newkeys == NULL) > -+ return; > -+ > -+ enc_destroy(&newkeys->enc); > -+ mac_destroy(&newkeys->mac); > -+ memset(&newkeys->comp, 0, sizeof(newkeys->comp)); > -+} > -+ > -diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h > ---- openssh-6.8p1/kex.h.audit 2015-03-20 13:41:15.046883856 +0100 > -+++ openssh-6.8p1/kex.h 2015-03-20 13:41:15.095883777 +0100 > -@@ -199,6 +199,8 @@ int kexgss_client(struct ssh *); > - int kexgss_server(struct ssh *); > - #endif > - > -+void newkeys_destroy(struct newkeys *newkeys); > -+ > - int kex_dh_hash(const char *, const char *, > - const u_char *, size_t, const u_char *, size_t, const u_char *, > size_t, > - const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t > *); > -diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h > ---- openssh-6.8p1/key.h.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/key.h 2015-03-20 13:41:15.095883777 +0100 > -@@ -50,6 +50,7 @@ typedef struct sshkey Key; > - #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid > - #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid > - #define key_is_cert sshkey_is_cert > -+#define key_is_private sshkey_is_private > - #define key_type_plain sshkey_type_plain > - #define key_cert_is_legacy sshkey_cert_is_legacy > - #define key_curve_name_to_nid sshkey_curve_name_to_nid > -diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c > ---- openssh-6.8p1/mac.c.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/mac.c 2015-03-20 13:41:15.102883766 +0100 > -@@ -226,6 +246,20 @@ mac_clear(struct sshmac *mac) > - mac->umac_ctx = NULL; > - } > - > -+void > -+mac_destroy(struct sshmac *mac) > -+{ > -+ if (mac == NULL) > -+ return; > -+ > -+ if (mac->key) { > -+ memset(mac->key, 0, mac->key_len); > -+ free(mac->key); > -+ } > -+ > -+ memset(mac, 0, sizeof(*mac)); > -+} > -+ > - /* XXX copied from ciphers_valid */ > - #define MAC_SEP "," > - int > -diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h > ---- openssh-6.8p1/mac.h.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/mac.h 2015-03-20 13:41:15.095883777 +0100 > -@@ -47,5 +47,6 @@ int mac_init(struct sshmac *); > - int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, > - u_char *, size_t); > - void mac_clear(struct sshmac *); > -+void mac_destroy(struct sshmac *); > - > - #endif /* SSHMAC_H */ > -diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c > ---- openssh-6.8p1/monitor.c.audit 2015-03-20 13:41:15.072883814 > +0100 > -+++ openssh-6.8p1/monitor.c 2015-03-20 13:41:15.107883758 +0100 > -@@ -102,6 +102,7 @@ > - #include "ssh2.h" > - #include "roaming.h" > - #include "authfd.h" > -+#include "audit.h" > - #include "match.h" > - #include "ssherr.h" > - > -@@ -117,6 +118,8 @@ extern Buffer auth_debug; > - extern int auth_debug_init; > - extern Buffer loginmsg; > - > -+extern void destroy_sensitive_data(int); > -+ > - /* State exported from the child */ > - static struct sshbuf *child_state; > - > -@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe > - #ifdef SSH_AUDIT_EVENTS > - int mm_answer_audit_event(int, Buffer *); > - int mm_answer_audit_command(int, Buffer *); > -+int mm_answer_audit_end_command(int, Buffer *); > -+int mm_answer_audit_unsupported_body(int, Buffer *); > -+int mm_answer_audit_kex_body(int, Buffer *); > -+int mm_answer_audit_session_key_free_body(int, Buffer *); > -+int mm_answer_audit_server_key_free(int, Buffer *); > - #endif > - > - static int monitor_read_log(struct monitor *); > -@@ -226,6 +234,10 @@ struct mon_table mon_dispatch_proto20[] > - #endif > - #ifdef SSH_AUDIT_EVENTS > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > mm_answer_audit_unsupported_body}, > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > mm_answer_audit_session_key_free_body}, > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > mm_answer_audit_server_key_free}, > - #endif > - #ifdef BSD_AUTH > - {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, > -@@ -264,6 +276,11 @@ struct mon_table mon_dispatch_postauth20 > - #ifdef SSH_AUDIT_EVENTS > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > - {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, > -+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, > mm_answer_audit_end_command}, > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > mm_answer_audit_unsupported_body}, > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > mm_answer_audit_session_key_free_body}, > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > mm_answer_audit_server_key_free}, > - #endif > - {0, 0, NULL} > - }; > -@@ -296,6 +313,10 @@ struct mon_table mon_dispatch_proto15[] > - #endif > - #ifdef SSH_AUDIT_EVENTS > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > mm_answer_audit_unsupported_body}, > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > mm_answer_audit_session_key_free_body}, > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > mm_answer_audit_server_key_free}, > - #endif > - #endif /* WITH_SSH1 */ > - {0, 0, NULL} > -@@ -309,6 +330,11 @@ struct mon_table mon_dispatch_postauth15 > - #ifdef SSH_AUDIT_EVENTS > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > - {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, > mm_answer_audit_command}, > -+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, > mm_answer_audit_end_command}, > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > mm_answer_audit_unsupported_body}, > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > mm_answer_audit_session_key_free_body}, > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > mm_answer_audit_server_key_free}, > - #endif > - #endif /* WITH_SSH1 */ > - {0, 0, NULL} > -@@ -1466,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m) > - Key *key; > - u_char *signature, *data, *blob; > - u_int signaturelen, datalen, bloblen; > -+ int type = 0; > - int verified = 0; > - int valid_data = 0; > - > -+ type = buffer_get_int(m); > - blob = buffer_get_string(m, &bloblen); > - signature = buffer_get_string(m, &signaturelen); > - data = buffer_get_string(m, &datalen); > -@@ -1476,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m) > - if (hostbased_cuser == NULL || hostbased_chost == NULL || > - !monitor_allowed_key(blob, bloblen)) > - fatal("%s: bad key, not previously allowed", __func__); > -+ if (type != key_blobtype) > -+ fatal("%s: bad key type", __func__); > - > - key = key_from_blob(blob, bloblen); > - if (key == NULL) > -@@ -1496,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m) > - if (!valid_data) > - fatal("%s: bad signature data blob", __func__); > - > -- verified = key_verify(key, signature, signaturelen, data, > datalen); > -+ switch (key_blobtype) { > -+ case MM_USERKEY: > -+ verified = user_key_verify(key, signature, signaturelen, > data, datalen); > -+ break; > -+ case MM_HOSTKEY: > -+ verified = hostbased_key_verify(key, signature, > signaturelen, data, datalen); > -+ break; > -+ default: > -+ verified = 0; > -+ break; > -+ } > - debug3("%s: key %p signature %s", > - __func__, key, (verified == 1) ? "verified" : "unverified"); > - > -@@ -1554,6 +1595,12 @@ mm_session_close(Session *s) > - debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); > - session_pty_cleanup2(s); > - } > -+#ifdef SSH_AUDIT_EVENTS > -+ if (s->command != NULL) { > -+ debug3("%s: command %d", __func__, s->command_handle); > -+ session_end_command2(s); > -+ } > -+#endif > - session_unused(s->self); > - } > - > -@@ -1836,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req) > - sshpam_cleanup(); > - #endif > - > -+ destroy_sensitive_data(0); > -+ > - while (waitpid(pmonitor->m_pid, &status, 0) == -1) > - if (errno != EINTR) > - exit(1); > -@@ -1878,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff > - { > - u_int len; > - char *cmd; > -+ Session *s; > - > - debug3("%s entering", __func__); > - cmd = buffer_get_string(m, &len); > -+ > - /* sanity check command, if so how? */ > -- audit_run_command(cmd); > -+ s = session_new(); > -+ if (s == NULL) > -+ fatal("%s: error allocating a session", __func__); > -+ s->command = cmd; > -+ s->command_handle = audit_run_command(cmd); > -+ > -+ buffer_clear(m); > -+ buffer_put_int(m, s->self); > -+ > -+ mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m); > -+ > -+ return (0); > -+} > -+ > -+int > -+mm_answer_audit_end_command(int socket, Buffer *m) > -+{ > -+ int handle; > -+ u_int len; > -+ char *cmd; > -+ Session *s; > -+ > -+ debug3("%s entering", __func__); > -+ handle = buffer_get_int(m); > -+ cmd = buffer_get_string(m, &len); > -+ > -+ s = session_by_id(handle); > -+ if (s == NULL || s->ttyfd != -1 || s->command == NULL || > -+ strcmp(s->command, cmd) != 0) > -+ fatal("%s: invalid handle", __func__); > -+ mm_session_close(s); > - free(cmd); > - return (0); > - } > -@@ -1936,6 +2017,7 @@ > - void > - mm_get_keystate(struct monitor *pmonitor) > - { > -+ Buffer m; > - debug3("%s: Waiting for new keys", __func__); > - > - if ((child_state = sshbuf_new()) == NULL) > -@@ -1946,6 +2027,21 @@ mm_get_keystate(struct monitor *pmonitor > - mm_request_receive_expect(pmonitor->m_sendfd, > MONITOR_REQ_KEYEXPORT, > - child_state); > - debug3("%s: GOT new keys", __func__); > -+ > -+#ifdef SSH_AUDIT_EVENTS > -+ if (compat20) { > -+ buffer_init(&m); > -+ mm_request_receive_expect(pmonitor->m_sendfd, > -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE > , &m); > -+ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, > &m); > -+ buffer_free(&m); > -+ } > -+#endif > -+ > -+ /* Drain any buffered messages from the child */ > -+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) > == 0) > -+ ; > -+ > - } > - > - > -@@ -2212,3 +2308,87 @@ mm_answer_gss_updatecreds(int socket, Bu > - > - #endif /* GSSAPI */ > - > -+#ifdef SSH_AUDIT_EVENTS > -+int > -+mm_answer_audit_unsupported_body(int sock, Buffer *m) > -+{ > -+ int what; > -+ > -+ what = buffer_get_int(m); > -+ > -+ audit_unsupported_body(what); > -+ > -+ buffer_clear(m); > -+ > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m); > -+ return 0; > -+} > -+ > -+int > -+mm_answer_audit_kex_body(int sock, Buffer *m) > -+{ > -+ int ctos, len; > -+ char *cipher, *mac, *compress, *pfs; > -+ pid_t pid; > -+ uid_t uid; > -+ > -+ ctos = buffer_get_int(m); > -+ cipher = buffer_get_string(m, &len); > -+ mac = buffer_get_string(m, &len); > -+ compress = buffer_get_string(m, &len); > -+ pfs = buffer_get_string(m, &len); > -+ pid = buffer_get_int64(m); > -+ uid = buffer_get_int64(m); > -+ > -+ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); > -+ > -+ free(cipher); > -+ free(mac); > -+ free(compress); > -+ free(pfs); > -+ buffer_clear(m); > -+ > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); > -+ return 0; > -+} > -+ > -+int > -+mm_answer_audit_session_key_free_body(int sock, Buffer *m) > -+{ > -+ int ctos; > -+ pid_t pid; > -+ uid_t uid; > -+ > -+ ctos = buffer_get_int(m); > -+ pid = buffer_get_int64(m); > -+ uid = buffer_get_int64(m); > -+ > -+ audit_session_key_free_body(ctos, pid, uid); > -+ > -+ buffer_clear(m); > -+ > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m); > -+ return 0; > -+} > -+ > -+int > -+mm_answer_audit_server_key_free(int sock, Buffer *m) > -+{ > -+ int len; > -+ char *fp; > -+ pid_t pid; > -+ uid_t uid; > -+ > -+ fp = buffer_get_string(m, &len); > -+ pid = buffer_get_int64(m); > -+ uid = buffer_get_int64(m); > -+ > -+ audit_destroy_sensitive_data(fp, pid, uid); > -+ > -+ free(fp); > -+ buffer_clear(m); > -+ > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m); > -+ return 0; > -+} > -+#endif /* SSH_AUDIT_EVENTS */ > -diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h > ---- openssh-6.8p1/monitor.h.audit 2015-03-20 13:41:15.072883814 > +0100 > -+++ openssh-6.8p1/monitor.h 2015-03-20 13:41:15.096883775 +0100 > -@@ -69,7 +69,13 @@ enum monitor_reqtype { > - MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, > - MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, > - MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, > -- MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, > -+ MONITOR_REQ_AUDIT_EVENT = 112, > -+ MONITOR_REQ_AUDIT_COMMAND = 114, MONITOR_ANS_AUDIT_COMMAND = 115, > -+ MONITOR_REQ_AUDIT_END_COMMAND = 116, > -+ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, > MONITOR_ANS_AUDIT_UNSUPPORTED = 119, > -+ MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, > -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, > MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, > -+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, > MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125 > - > - }; > - > -diff -up openssh-6.8p1/monitor_wrap.c.audit > openssh-6.8p1/monitor_wrap.c > ---- openssh-6.8p1/monitor_wrap.c.audit 2015-03-20 > 13:41:15.047883855 +0100 > -+++ openssh-6.8p1/monitor_wrap.c 2015-03-20 13:41:15.108883756 > +0100 > -@@ -461,7 +461,7 @@ mm_key_allowed(enum mm_keytype type, cha > - */ > - > - int > --mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int > datalen) > -+mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int > siglen, u_char *data, u_int datalen) > - { > - Buffer m; > - u_char *blob; > -@@ -475,6 +475,7 @@ mm_key_verify(Key *key, u_char *sig, u_i > - return (0); > - > - buffer_init(&m); > -+ buffer_put_int(&m, type); > - buffer_put_string(&m, blob, len); > - buffer_put_string(&m, sig, siglen); > - buffer_put_string(&m, data, datalen); > -@@ -492,6 +493,18 @@ mm_key_verify(Key *key, u_char *sig, u_i > - return (verified); > - } > - > -+int > -+mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char > *data, u_int datalen) > -+{ > -+ return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, > datalen); > -+} > -+ > -+int > -+mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, > u_int datalen) > -+{ > -+ return mm_key_verify(MM_USERKEY, key, sig, siglen, data, > datalen); > -+} > -+ > - void > - mm_send_keystate(struct monitor *monitor) > - { > -@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event) > - buffer_free(&m); > - } > - > --void > -+int > - mm_audit_run_command(const char *command) > - { > - Buffer m; > -+ int handle; > - > - debug3("%s entering command %s", __func__, command); > - > -@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command > - buffer_put_cstring(&m, command); > - > - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, > &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_COMMAND, &m); > -+ > -+ handle = buffer_get_int(&m); > -+ buffer_free(&m); > -+ > -+ return (handle); > -+} > -+ > -+void > -+mm_audit_end_command(int handle, const char *command) > -+{ > -+ Buffer m; > -+ > -+ debug3("%s entering command %s", __func__, command); > -+ > -+ buffer_init(&m); > -+ buffer_put_int(&m, handle); > -+ buffer_put_cstring(&m, command); > -+ > -+ mm_request_send(pmonitor->m_recvfd, > MONITOR_REQ_AUDIT_END_COMMAND, &m); > - buffer_free(&m); > - } > - #endif /* SSH_AUDIT_EVENTS */ > -@@ -1151,3 +1185,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc > - > - #endif /* GSSAPI */ > - > -+#ifdef SSH_AUDIT_EVENTS > -+void > -+mm_audit_unsupported_body(int what) > -+{ > -+ Buffer m; > -+ > -+ buffer_init(&m); > -+ buffer_put_int(&m, what); > -+ > -+ mm_request_send(pmonitor->m_recvfd, > MONITOR_REQ_AUDIT_UNSUPPORTED, &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_UNSUPPORTED, > -+ &m); > -+ > -+ buffer_free(&m); > -+} > -+ > -+void > -+mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, > char *fps, pid_t pid, > -+ uid_t uid) > -+{ > -+ Buffer m; > -+ > -+ buffer_init(&m); > -+ buffer_put_int(&m, ctos); > -+ buffer_put_cstring(&m, cipher); > -+ buffer_put_cstring(&m, (mac ? mac : "")); > -+ buffer_put_cstring(&m, compress); > -+ buffer_put_cstring(&m, fps); > -+ buffer_put_int64(&m, pid); > -+ buffer_put_int64(&m, uid); > -+ > -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_KEX, > -+ &m); > -+ > -+ buffer_free(&m); > -+} > -+ > -+void > -+mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+ Buffer m; > -+ > -+ buffer_init(&m); > -+ buffer_put_int(&m, ctos); > -+ buffer_put_int64(&m, pid); > -+ buffer_put_int64(&m, uid); > -+ mm_request_send(pmonitor->m_recvfd, > MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_SESSION_KEY_FREE, > -+ &m); > -+ buffer_free(&m); > -+} > -+ > -+void > -+mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > -+{ > -+ Buffer m; > -+ > -+ buffer_init(&m); > -+ buffer_put_cstring(&m, fp); > -+ buffer_put_int64(&m, pid); > -+ buffer_put_int64(&m, uid); > -+ > -+ mm_request_send(pmonitor->m_recvfd, > MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_SERVER_KEY_FREE, > -+ &m); > -+ buffer_free(&m); > -+} > -+#endif /* SSH_AUDIT_EVENTS */ > -diff -up openssh-6.8p1/monitor_wrap.h.audit > openssh-6.8p1/monitor_wrap.h > ---- openssh-6.8p1/monitor_wrap.h.audit 2015-03-20 > 13:41:15.048883853 +0100 > -+++ openssh-6.8p1/monitor_wrap.h 2015-03-20 13:41:15.096883775 > +0100 > -@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char > - int mm_user_key_allowed(struct passwd *, Key *); > - int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); > - int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, > Key *); > --int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); > -+int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int); > -+int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int); > - int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); > - int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); > - BIGNUM *mm_auth_rsa_generate_challenge(Key *); > -@@ -79,7 +80,12 @@ void mm_sshpam_free_ctx(void *); > - #ifdef SSH_AUDIT_EVENTS > - #include "audit.h" > - void mm_audit_event(ssh_audit_event_t); > --void mm_audit_run_command(const char *); > -+int mm_audit_run_command(const char *); > -+void mm_audit_end_command(int, const char *); > -+void mm_audit_unsupported_body(int); > -+void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, > uid_t); > -+void mm_audit_session_key_free_body(int, pid_t, uid_t); > -+void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); > - #endif > - > - struct Session; > -diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c > ---- openssh-6.8p1/packet.c.audit 2015-03-20 13:41:14.990883947 > +0100 > -+++ openssh-6.8p1/packet.c 2015-03-20 13:41:15.097883774 +0100 > -@@ -67,6 +67,7 @@ > - #include "key.h" /* typedefs XXX */ > - > - #include "xmalloc.h" > -+#include "audit.h" > - #include "crc32.h" > - #include "deattack.h" > - #include "compat.h" > -@@ -448,6 +449,13 @@ ssh_packet_get_connection_out(struct ssh > - return ssh->state->connection_out; > - } > - > -+static int > -+packet_state_has_keys (const struct session_state *state) > -+{ > -+ return state != NULL && > -+ (state->newkeys[MODE_IN] != NULL || state- > >newkeys[MODE_OUT] > != NULL); > -+} > -+ > - /* > - * Returns the IP-address of the remote host as a string. The > returned > - * string must not be freed. > -@@ -478,13 +486,6 @@ ssh_packet_close(struct ssh *ssh) > - if (!state->initialized) > - return; > - state->initialized = 0; > -- if (state->connection_in == state->connection_out) { > -- shutdown(state->connection_out, SHUT_RDWR); > -- close(state->connection_out); > -- } else { > -- close(state->connection_in); > -- close(state->connection_out); > -- } > - sshbuf_free(state->input); > - sshbuf_free(state->output); > - sshbuf_free(state->outgoing_packet); > -@@ -516,14 +517,24 @@ ssh_packet_close(struct ssh *ssh) > - inflateEnd(stream); > - } > - } > -- if ((r = cipher_cleanup(&state->send_context)) != 0) > -- error("%s: cipher_cleanup failed: %s", __func__, > ssh_err(r)); > -- if ((r = cipher_cleanup(&state->receive_context)) != 0) > -- error("%s: cipher_cleanup failed: %s", __func__, > ssh_err(r)); > -+ if (packet_state_has_keys(state)) { > -+ if ((r = cipher_cleanup(&state->send_context)) != 0) > -+ error("%s: cipher_cleanup failed: %s", __func__, > ssh_err(r)); > -+ if ((r = cipher_cleanup(&state->receive_context)) != 0) > -+ error("%s: cipher_cleanup failed: %s", __func__, > ssh_err(r)); > -+ audit_session_key_free(2); > -+ } > - if (ssh->remote_ipaddr) { > - free(ssh->remote_ipaddr); > - ssh->remote_ipaddr = NULL; > - } > -+ if (state->connection_in == state->connection_out) { > -+ shutdown(state->connection_out, SHUT_RDWR); > -+ close(state->connection_out); > -+ } else { > -+ close(state->connection_in); > -+ close(state->connection_out); > -+ } > - free(ssh->state); > - ssh->state = NULL; > - } > -@@ -941,6 +952,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod > - } > - if (state->newkeys[mode] != NULL) { > - debug("set_newkeys: rekeying"); > -+ audit_session_key_free(mode); > - if ((r = cipher_cleanup(cc)) != 0) > - return r; > - enc = &state->newkeys[mode]->enc; > -@@ -2263,6 +2275,75 @@ ssh_packet_get_output(struct ssh *ssh) > - return (void *)ssh->state->output; > - } > - > -+static void > -+newkeys_destroy_and_free(struct newkeys *newkeys) > -+{ > -+ if (newkeys == NULL) > -+ return; > -+ > -+ free(newkeys->enc.name); > -+ > -+ if (newkeys->mac.enabled) { > -+ mac_clear(&newkeys->mac); > -+ free(newkeys->mac.name); > -+ } > -+ > -+ free(newkeys->comp.name); > -+ > -+ newkeys_destroy(newkeys); > -+ free(newkeys); > -+} > -+ > -+static void > -+packet_destroy_state(struct session_state *state) > -+{ > -+ if (state == NULL) > -+ return; > -+ > -+ cipher_cleanup(&state->receive_context); > -+ cipher_cleanup(&state->send_context); > -+ > -+ buffer_free(state->input); > -+ state->input = NULL; > -+ buffer_free(state->output); > -+ state->output = NULL; > -+ buffer_free(state->outgoing_packet); > -+ state->outgoing_packet = NULL; > -+ buffer_free(state->incoming_packet); > -+ state->incoming_packet = NULL; > -+ if( state->compression_buffer ) { > -+ buffer_free(state->compression_buffer); > -+ state->compression_buffer = NULL; > -+ } > -+ newkeys_destroy_and_free(state->newkeys[MODE_IN]); > -+ state->newkeys[MODE_IN] = NULL; > -+ newkeys_destroy_and_free(state->newkeys[MODE_OUT]); > -+ state->newkeys[MODE_OUT] = NULL; > -+ mac_destroy(state->packet_discard_mac); > -+// TAILQ_HEAD(, packet) outgoing; > -+// memset(state, 0, sizeof(state)); > -+} > -+ > -+void > -+packet_destroy_all(int audit_it, int privsep) > -+{ > -+ if (audit_it) > -+ audit_it = (active_state != NULL && > packet_state_has_keys(active_state->state)) > -+ || (backup_state != NULL && > packet_state_has_keys(backup_state->state)); > -+ if (active_state != NULL) > -+ packet_destroy_state(active_state->state); > -+ if (backup_state != NULL) > -+ packet_destroy_state(backup_state->state); > -+ if (audit_it) { > -+#ifdef SSH_AUDIT_EVENTS > -+ if (privsep) > -+ audit_session_key_free(2); > -+ else > -+ audit_session_key_free_body(2, getpid(), getuid()); > -+#endif > -+ } > -+} > -+ > - /* XXX TODO update roaming to new API (does not work anyway) */ > - /* > - * Save the state for the real connection, and use a separate state > when > -@@ -2272,18 +2373,12 @@ void > - ssh_packet_backup_state(struct ssh *ssh, > - struct ssh *backup_state) > - { > -- struct ssh *tmp; > -- > - close(ssh->state->connection_in); > - ssh->state->connection_in = -1; > - close(ssh->state->connection_out); > - ssh->state->connection_out = -1; > -- if (backup_state) > -- tmp = backup_state; > -- else > -- tmp = ssh_alloc_session_state(); > - backup_state = ssh; > -- ssh = tmp; > -+ ssh = ssh_alloc_session_state(); > - } > - > - /* XXX FIXME FIXME FIXME */ > -@@ -2302,9 +2397,7 @@ ssh_packet_restore_state(struct ssh *ssh > - backup_state = ssh; > - ssh = tmp; > - ssh->state->connection_in = backup_state->state->connection_in; > -- backup_state->state->connection_in = -1; > - ssh->state->connection_out = backup_state->state->connection_out; > -- backup_state->state->connection_out = -1; > - len = sshbuf_len(backup_state->state->input); > - if (len > 0) { > - if ((r = sshbuf_putb(ssh->state->input, > -@@ -2313,6 +2406,11 @@ ssh_packet_restore_state(struct ssh *ssh > - sshbuf_reset(backup_state->state->input); > - add_recv_bytes(len); > - } > -+ backup_state->state->connection_in = -1; > -+ backup_state->state->connection_out = -1; > -+ packet_destroy_state(backup_state->state); > -+ free(backup_state); > -+ backup_state = NULL; > - } > - > - /* Reset after_authentication and reset compression in post-auth > privsep */ > -diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h > ---- openssh-6.8p1/packet.h.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/packet.h 2015-03-20 13:41:15.097883774 +0100 > -@@ -189,7 +189,7 @@ int sshpkt_get_end(struct ssh *ssh); > - const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); > - > - /* OLD API */ > --extern struct ssh *active_state; > -+extern struct ssh *active_state, *backup_state; > - #include "opacket.h" > - > - #if !defined(WITH_OPENSSL) > -@@ -203,4 +203,5 @@ extern struct ssh *active_state; > - # undef EC_POINT > - #endif > - > -+void packet_destroy_all(int, int); > - #endif /* PACKET_H */ > -diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c > ---- openssh-6.8p1/session.c.audit 2015-03-20 13:41:15.073883813 > +0100 > -+++ openssh-6.8p1/session.c 2015-03-20 13:41:15.097883774 +0100 > -@@ -139,7 +139,7 @@ extern int log_stderr; > - extern int debug_flag; > - extern u_int utmp_len; > - extern int startup_pipe; > --extern void destroy_sensitive_data(void); > -+extern void destroy_sensitive_data(int); > - extern Buffer loginmsg; > - > - /* original command from peer. */ > -@@ -731,6 +731,14 @@ do_exec_pty(Session *s, const char *comm > - /* Parent. Close the slave side of the pseudo tty. */ > - close(ttyfd); > - > -+#ifndef HAVE_OSF_SIA > -+ /* do_login in the child did not affect state in this process, > -+ compensate. From an architectural standpoint, this is > extremely > -+ ugly. */ > -+ if (!(options.use_login && command == NULL)) > -+ audit_count_session_open(); > -+#endif > -+ > - /* Enter interactive session. */ > - s->ptymaster = ptymaster; > - packet_set_interactive(1, > -@@ -853,15 +861,19 @@ do_exec(Session *s, const char *command) > - get_remote_port()); > - > - #ifdef SSH_AUDIT_EVENTS > -+ if (s->command != NULL || s->command_handle != -1) > -+ fatal("do_exec: command already set"); > - if (command != NULL) > -- PRIVSEP(audit_run_command(command)); > -+ s->command = xstrdup(command); > - else if (s->ttyfd == -1) { > - char *shell = s->pw->pw_shell; > - > - if (shell[0] == '\0') /* empty shell means /bin/sh */ > - shell =_PATH_BSHELL; > -- PRIVSEP(audit_run_command(shell)); > -+ s->command = xstrdup(shell); > - } > -+ if (s->command != NULL && s->ptyfd == -1) > -+ s->command_handle = PRIVSEP(audit_run_command(s->command)); > - #endif > - if (s->ttyfd != -1) > - ret = do_exec_pty(s, command); > -@@ -1704,7 +1716,10 @@ do_child(Session *s, const char *command > - int r = 0; > - > - /* remove hostkey from the child's memory */ > -- destroy_sensitive_data(); > -+ destroy_sensitive_data(1); > -+ /* Don't audit this - both us and the parent would be talking to > the > -+ monitor over a single socket, with no synchronization. */ > -+ packet_destroy_all(0, 1); > - > - /* Force a password change */ > - if (s->authctxt->force_pwchange) { > -@@ -1934,6 +1949,7 @@ session_unused(int id) > - sessions[id].ttyfd = -1; > - sessions[id].ptymaster = -1; > - sessions[id].x11_chanids = NULL; > -+ sessions[id].command_handle = -1; > - sessions[id].next_unused = sessions_first_unused; > - sessions_first_unused = id; > - } > -@@ -2016,6 +2032,19 @@ session_open(Authctxt *authctxt, int cha > - } > - > - Session * > -+session_by_id(int id) > -+{ > -+ if (id >= 0 && id < sessions_nalloc) { > -+ Session *s = &sessions[id]; > -+ if (s->used) > -+ return s; > -+ } > -+ debug("session_by_id: unknown id %d", id); > -+ session_dump(); > -+ return NULL; > -+} > -+ > -+Session * > - session_by_tty(char *tty) > - { > - int i; > -@@ -2532,6 +2561,32 @@ session_exit_message(Session *s, int sta > - chan_write_failed(c); > - } > - > -+#ifdef SSH_AUDIT_EVENTS > -+void > -+session_end_command2(Session *s) > -+{ > -+ if (s->command != NULL) { > -+ if (s->command_handle != -1) > -+ audit_end_command(s->command_handle, s->command); > -+ free(s->command); > -+ s->command = NULL; > -+ s->command_handle = -1; > -+ } > -+} > -+ > -+static void > -+session_end_command(Session *s) > -+{ > -+ if (s->command != NULL) { > -+ if (s->command_handle != -1) > -+ PRIVSEP(audit_end_command(s->command_handle, > s->command)); > -+ free(s->command); > -+ s->command = NULL; > -+ s->command_handle = -1; > -+ } > -+} > -+#endif > -+ > - void > - session_close(Session *s) > - { > -@@ -2540,6 +2593,10 @@ session_close(Session *s) > - debug("session_close: session %d pid %ld", s->self, > (long)s->pid); > - if (s->ttyfd != -1) > - session_pty_cleanup(s); > -+#ifdef SSH_AUDIT_EVENTS > -+ if (s->command) > -+ session_end_command(s); > -+#endif > - free(s->term); > - free(s->display); > - free(s->x11_chanids); > -@@ -2754,6 +2811,15 @@ do_authenticated2(Authctxt *authctxt) > - server_loop2(authctxt); > - } > - > -+static void > -+do_cleanup_one_session(Session *s) > -+{ > -+ session_pty_cleanup2(s); > -+#ifdef SSH_AUDIT_EVENTS > -+ session_end_command2(s); > -+#endif > -+} > -+ > - void > - do_cleanup(Authctxt *authctxt) > - { > -@@ -2802,5 +2868,5 @@ do_cleanup(Authctxt *authctxt) > - * or if running in monitor. > - */ > - if (!use_privsep || mm_is_monitor()) > -- session_destroy_all(session_pty_cleanup2); > -+ session_destroy_all(do_cleanup_one_session); > - } > -diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h > ---- openssh-6.8p1/session.h.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/session.h 2015-03-20 13:41:15.097883774 +0100 > -@@ -61,6 +61,12 @@ struct Session { > - char *name; > - char *val; > - } *env; > -+ > -+ /* exec */ > -+#ifdef SSH_AUDIT_EVENTS > -+ int command_handle; > -+ char *command; > -+#endif > - }; > - > - void do_authenticated(Authctxt *); > -@@ -73,8 +79,10 @@ void session_close_by_pid(pid_t, int); > - void session_close_by_channel(int, void *); > - void session_destroy_all(void (*)(Session *)); > - void session_pty_cleanup2(Session *); > -+void session_end_command2(Session *); > - > - Session *session_new(void); > -+Session *session_by_id(int); > - Session *session_by_tty(char *); > - void session_close(Session *); > - void do_setusercontext(struct passwd *); > -diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c > ---- openssh-6.8p1/sshd.c.audit 2015-03-20 13:41:15.083883796 +0100 > -+++ openssh-6.8p1/sshd.c 2015-03-20 13:41:15.110883753 +0100 > -@@ -121,6 +124,7 @@ > - #endif > - #include "monitor_wrap.h" > - #include "roaming.h" > -+#include "audit.h" > - #include "ssh-sandbox.h" > - #include "version.h" > - #include "ssherr.h" > -@@ -260,7 +264,7 @@ Buffer loginmsg; > - struct passwd *privsep_pw = NULL; > - > - /* Prototypes for various functions defined later in this file. */ > --void destroy_sensitive_data(void); > -+void destroy_sensitive_data(int); > - void demote_sensitive_data(void); > - > - #ifdef WITH_SSH1 > -@@ -281,6 +285,15 @@ close_listen_socks(void) > - num_listen_socks = -1; > - } > - > -+/* > -+ * Is this process listening for clients (i.e. not specific to any > specific > -+ * client connection?) > -+ */ > -+int listening_for_clients(void) > -+{ > -+ return num_listen_socks > 0; > -+} > -+ > - static void > - close_startup_pipes(void) > - { > -@@ -560,22 +573,45 @@ sshd_exchange_identification(int sock_in > - } > - } > - > --/* Destroy the host and server keys. They will no longer be needed. > */ > -+/* > -+ * Destroy the host and server keys. They will no longer be needed. > Careful, > -+ * this can be called from cleanup_exit() - i.e. from just about > anywhere. > -+ */ > - void > --destroy_sensitive_data(void) > -+destroy_sensitive_data(int privsep) > - { > - int i; > -+ pid_t pid; > -+ uid_t uid; > - > - if (sensitive_data.server_key) { > - key_free(sensitive_data.server_key); > - sensitive_data.server_key = NULL; > - } > -+ pid = getpid(); > -+ uid = getuid(); > - for (i = 0; i < options.num_host_key_files; i++) { > - if (sensitive_data.host_keys[i]) { > -+ char *fp; > -+ > -+ if (key_is_private(sensitive_data.host_keys[i])) > -+ fp = > sshkey_fingerprint(sensitive_data.host_keys[i], > options.fingerprint_hash, SSH_FP_HEX); > -+ else > -+ fp = NULL; > - key_free(sensitive_data.host_keys[i]); > - sensitive_data.host_keys[i] = NULL; > -+ if (fp != NULL) { > -+ if (privsep) > -+ PRIVSEP(audit_destroy_sensitive_data > (fp, > -+ pid, uid)); > -+ else > -+ audit_destroy_sensitive_data(fp, > -+ pid, uid); > -+ free(fp); > -+ } > - } > -- if (sensitive_data.host_certificates[i]) { > -+ if (sensitive_data.host_certificates > -+ && sensitive_data.host_certificates[i]) { > - key_free(sensitive_data.host_certificates[i]); > - sensitive_data.host_certificates[i] = NULL; > - } > -@@ -589,6 +625,8 @@ void > - demote_sensitive_data(void) > - { > - Key *tmp; > -+ pid_t pid; > -+ uid_t uid; > - int i; > - > - if (sensitive_data.server_key) { > -@@ -597,13 +635,25 @@ demote_sensitive_data(void) > - sensitive_data.server_key = tmp; > - } > - > -+ pid = getpid(); > -+ uid = getuid(); > - for (i = 0; i < options.num_host_key_files; i++) { > - if (sensitive_data.host_keys[i]) { > -+ char *fp; > -+ > -+ if (key_is_private(sensitive_data.host_keys[i])) > -+ fp = > sshkey_fingerprint(sensitive_data.host_keys[i], > options.fingerprint_hash, SSH_FP_HEX); > -+ else > -+ fp = NULL; > - tmp = key_demote(sensitive_data.host_keys[i]); > - key_free(sensitive_data.host_keys[i]); > - sensitive_data.host_keys[i] = tmp; > - if (tmp->type == KEY_RSA1) > - sensitive_data.ssh1_host_key = tmp; > -+ if (fp != NULL) { > -+ audit_destroy_sensitive_data(fp, pid, uid); > -+ free(fp); > -+ } > - } > - /* Certs do not need demotion */ > - } > -@@ -675,7 +725,7 @@ privsep_preauth(Authctxt *authctxt) > - > - if (use_privsep == PRIVSEP_ON) > - box = ssh_sandbox_init(pmonitor); > -- pid = fork(); > -+ pmonitor->m_pid = pid = fork(); > - if (pid == -1) { > - fatal("fork of unprivileged child failed"); > - } else if (pid != 0) { > -@@ -759,6 +811,12 @@ privsep_postauth(Authctxt *authctxt) > - else if (pmonitor->m_pid != 0) { > - verbose("User child is on pid %ld", (long)pmonitor->m_pid); > - buffer_clear(&loginmsg); > -+ if (*pmonitor->m_pkex != NULL ){ > -+ > newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]); > -+ newkeys_destroy((*pmonitor->m_pkex)- > >newkeys[MODE_IN]); > -+ audit_session_key_free_body(2, getpid(), getuid()); > -+ packet_destroy_all(0, 0); > -+ } > - monitor_child_postauth(pmonitor); > - > - /* NEVERREACHED */ > -@@ -1286,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so > - if (received_sigterm) { > - logit("Received signal %d; terminating.", > - (int) received_sigterm); > -+ destroy_sensitive_data(0); > - close_listen_socks(); > - if (options.pid_file != NULL) > - unlink(options.pid_file); > -@@ -2242,6 +2321,7 @@ main(int ac, char **av) > - */ > - if (use_privsep) { > - mm_send_keystate(pmonitor); > -+ packet_destroy_all(1, 1); > - exit(0); > - } > - > -@@ -2287,7 +2367,7 @@ main(int ac, char **av) > - privsep_postauth(authctxt); > - /* the monitor process [priv] will not return */ > - if (!compat20) > -- destroy_sensitive_data(); > -+ destroy_sensitive_data(0); > - } > - > - packet_set_timeout(options.client_alive_interval, > -@@ -2301,6 +2381,9 @@ main(int ac, char **av) > - do_authenticated(authctxt); > - > - /* The connection has been terminated. */ > -+ packet_destroy_all(1, 1); > -+ destroy_sensitive_data(1); > -+ > - packet_get_bytes(&ibytes, &obytes); > - verbose("Transferred: sent %llu, received %llu bytes", > - (unsigned long long)obytes, (unsigned long long)ibytes); > -@@ -2461,6 +2544,10 @@ do_ssh1_kex(void) > - if (cookie[i] != packet_get_char()) > - packet_disconnect("IP Spoofing check bytes do not > match."); > - > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); > -+#endif > -+ > - debug("Encryption type: %.200s", cipher_name(cipher_type)); > - > - /* Get the encrypted integer. */ > -@@ -2520,7 +2607,7 @@ do_ssh1_kex(void) > - } > - > - /* Destroy the private and public keys. No longer. */ > -- destroy_sensitive_data(); > -+ destroy_sensitive_data(1); > - > - if (use_privsep) > - mm_ssh1_session_id(session_id); > -@@ -2703,6 +2802,16 @@ do_ssh2_kex(void) > - void > - cleanup_exit(int i) > - { > -+ static int in_cleanup = 0; > -+ int is_privsep_child; > -+ > -+ /* cleanup_exit can be called at the very least from the privsep > -+ wrappers used for auditing. Make sure we don't recurse > -+ indefinitely. */ > -+ if (in_cleanup) > -+ _exit(i); > -+ in_cleanup = 1; > -+ > - if (the_authctxt) { > - do_cleanup(the_authctxt); > - if (use_privsep && privsep_is_preauth && > -@@ -2714,9 +2823,14 @@ cleanup_exit(int i) > - pmonitor->m_pid, strerror(errno)); > - } > - } > -+ is_privsep_child = use_privsep && pmonitor != NULL && > pmonitor->m_pid == 0; > -+ if (sensitive_data.host_keys != NULL) > -+ destroy_sensitive_data(is_privsep_child); > -+ packet_destroy_all(1, is_privsep_child); > - #ifdef SSH_AUDIT_EVENTS > - /* done after do_cleanup so it can cancel the PAM auth 'thread' > */ > -- if (!use_privsep || mm_is_monitor()) > -+ if ((the_authctxt == NULL || !the_authctxt->authenticated) && > -+ (!use_privsep || mm_is_monitor())) > - audit_event(SSH_CONNECTION_ABANDON); > - #endif > - _exit(i); > -diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c > ---- openssh-6.8p1/sshkey.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/sshkey.c 2015-03-20 13:41:15.111883751 +0100 > -@@ -317,6 +319,33 @@ sshkey_type_is_valid_ca(int type) > - } > - > - int > -+sshkey_is_private(const struct sshkey *k) > -+{ > -+ switch (k->type) { > -+ case KEY_RSA_CERT_V00: > -+ case KEY_RSA_CERT: > -+ case KEY_RSA1: > -+ case KEY_RSA: > -+ return k->rsa->d != NULL; > -+ case KEY_DSA_CERT_V00: > -+ case KEY_DSA_CERT: > -+ case KEY_DSA: > -+ return k->dsa->priv_key != NULL; > -+#ifdef OPENSSL_HAS_ECC > -+ case KEY_ECDSA_CERT: > -+ case KEY_ECDSA: > -+ return EC_KEY_get0_private_key(k->ecdsa) != NULL; > -+#endif > -+ case KEY_ED25519_CERT: > -+ case KEY_ED25519: > -+ return (k->ed25519_pk != NULL); > -+ default: > -+ /* fatal("key_is_private: bad key type %d", k->type); */ > -+ return 0; > -+ } > -+} > -+ > -+int > - sshkey_is_cert(const struct sshkey *k) > - { > - if (k == NULL) > -diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h > ---- openssh-6.8p1/sshkey.h.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/sshkey.h 2015-03-20 13:41:15.098883772 +0100 > -@@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey > - int sshkey_generate(int type, u_int bits, struct sshkey > **keyp); > - int sshkey_from_private(const struct sshkey *, struct > sshkey > **); > - int sshkey_type_from_name(const char *); > -+int sshkey_is_private(const struct sshkey *); > - int sshkey_is_cert(const struct sshkey *); > - int sshkey_type_is_cert(int); > - int sshkey_type_plain(int); > -diff -up openssh-6.8p1/sandbox-seccomp-filter.c.audit > openssh-6.8p1/sandbox-seccomp-filter.c > ---- openssh-6.8p1/sandbox-seccomp-filter.c.audit 2015-03-20 > 13:41:15.088883788 +0100 > -+++ openssh-6.8p1/sandbox-seccomp-filter.c 2015-03-20 > 13:41:15.097883774 +0100 > -@@ -110,6 +110,12 @@ static const struct sock_filter preauth_ > - #ifdef __NR_time /* not defined on EABI ARM */ > - SC_ALLOW(time), > - #endif > -+#ifdef SSH_AUDIT_EVENTS > -+ SC_ALLOW(getuid), > -+#ifdef __NR_getuid32 /* not defined on x86_64 */ > -+ SC_ALLOW(getuid32), > -+#endif > -+#endif > - SC_ALLOW(read), > - SC_ALLOW(write), > - SC_ALLOW(close), > diff --git a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > b/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > deleted file mode 100644 > index 4285bd9..0000000 > --- a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > +++ /dev/null > @@ -1,66 +0,0 @@ > -diff --git a/configure.ac b/configure.ac > -index 4065d0e..d59ad44 100644 > ---- a/configure.ac > -+++ b/configure.ac > -@@ -764,9 +764,12 @@ main() { if (NSVersionOfRunTimeLibrary("System") > > > > = (60 << 16)) > - i*86-*) > - seccomp_audit_arch=AUDIT_ARCH_I386 > - ;; > -- arm*-*) > -+ aarch64*-*) > -+ seccomp_audit_arch=AUDIT_ARCH_AARCH64 > -+ ;; > -+ arm*-*) > - seccomp_audit_arch=AUDIT_ARCH_ARM > -- ;; > -+ ;; > - esac > - if test "x$seccomp_audit_arch" != "x" ; then > - AC_MSG_RESULT(["$seccomp_audit_arch"]) > -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c > -index 095b04a..52f6810 100644 > ---- a/sandbox-seccomp-filter.c > -+++ b/sandbox-seccomp-filter.c > -@@ -90,8 +90,20 @@ static const struct sock_filter preauth_insns[] = { > - /* Load the syscall number for checking. */ > - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, > - offsetof(struct seccomp_data, nr)), > -- SC_DENY(open, EACCES), > -- SC_DENY(stat, EACCES), > -+ SC_DENY(openat, EACCES), > -+#ifdef __NR_open > -+ SC_DENY(open, EACCES), /* not on AArch64 */ > -+#endif > -+#ifdef __NR_fstat > -+ SC_DENY(fstat, EACCES), /* x86_64, Aarch64 */ > -+#endif > -+#if defined(__NR_stat64) && defined(__NR_fstat64) > -+ SC_DENY(stat64, EACCES), /* ix86, arm */ > -+ SC_DENY(fstat64, EACCES), > -+#endif > -+#ifdef __NR_newfstatat > -+ SC_DENY(newfstatat, EACCES), /* Aarch64 */ > -+#endif > - SC_ALLOW(getpid), > - SC_ALLOW(gettimeofday), > - SC_ALLOW(clock_gettime), > -@@ -111,12 +123,19 @@ static const struct sock_filter preauth_insns[] = > { > - SC_ALLOW(shutdown), > - #endif > - SC_ALLOW(brk), > -+#ifdef __NR_poll /* not on AArch64 */ > - SC_ALLOW(poll), > -+#endif > - #ifdef __NR__newselect > - SC_ALLOW(_newselect), > - #else > -+#ifdef __NR_select /* not on AArch64 */ > - SC_ALLOW(select), > - #endif > -+#ifdef __NR_pselect6 /* AArch64 */ > -+ SC_ALLOW(pselect6), > -+#endif > -+#endif > - SC_ALLOW(madvise), > - #ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ > - SC_ALLOW(mmap2),
Information on PCIDSS: https://en.wikipedia.org/wiki/Payment_Card_Industry_Data_Security_Standard In the United States, many small businesses process payment card payments via a web browser. They are periodically required to pass a security audit for the bank or payment processing firm which checks the security of their IT systems. This is to prevent malicious break ins and thefts via an compromised firewall, server, computer, etc. Yes, they check everything - including firewalls. Businesses whose networks do not pass may have their payment processing privileges suspended. Big cash flow problem if you accept credit or debit cards. Currently to pass a PCI audit, the openssh package on Linux must be at least version 7.4. IPFire 2 is currently at 7.3 (I believe) so it will not pass. Updating to the current 7.4 version will solve the problem. The most of the problem appears to be over key length. 7.4 will not use the shorter keys that 7.3 will. IPFire has been moving away from the older shorter keys anyway, and this is just another step in that process. Existing shorter keys might have to be regenerated. Currently the work-around is to disable exteral ssh access from IPFire and *never* turn it on. This is a *real* pain when it comes to remote support of IPFire. If this is not a priority, I completely understand. It just means moving the affected systems to different firewall software. Thanks in advance! Fred From the openssh 7.4 release notes: Potentially-incompatible changes ================================ This release includes a number of changes that may affect existing configurations: * This release removes server support for the SSH v.1 protocol. * ssh(1): Remove 3des-cbc from the client's default proposal. 64-bit block ciphers are not safe in 2016 and we don't want to wait until attacks like SWEET32 are extended to SSH. As 3des-cbc was the only mandatory cipher in the SSH RFCs, this may cause problems connecting to older devices using the default configuration, but it's highly likely that such devices already need explicit configuration for key exchange and hostkey algorithms already anyway. * sshd(8): Remove support for pre-authentication compression. Doing compression early in the protocol probably seemed reasonable in the 1990s, but today it's clearly a bad idea in terms of both cryptography (cf. multiple compression oracle attacks in TLS) and attack surface. Pre-auth compression support has been disabled by default for >10 years. Support remains in the client. * ssh-agent will refuse to load PKCS#11 modules outside a whitelist of trusted paths by default. The path whitelist may be specified at run-time. * sshd(8): When a forced-command appears in both a certificate and an authorized keys/principals command= restriction, sshd will now refuse to accept the certificate unless they are identical. The previous (documented) behaviour of having the certificate forced-command override the other could be a bit confusing and error-prone. * sshd(8): Remove the UseLogin configuration directive and support for having /bin/login manage login sessions. -----Original Message----- From: Michael Tremer [mailto:michael.tremer@ipfire.org] Sent: Wednesday, February 22, 2017 5:05 AM To: Kienker, Fred <fkienker@at4b.com>; development <development@lists.ipfire.org> Subject: Re: [PATCH] openssh: Update to 7.3p1. Hi Fred, you are referring to IPFire 3 here, but I suppose that you are rather using IPFire 2 in production. This version of IPFire comes with OpenSSH 7.3p1: http://git.ipfire.org/?p=ipfire-2.x.git;a=blob;f=lfs/openssh;h=371d0df4ac09c4106f761886fa4e3f6107bd2265;hb=HEAD It would be helpful if you could give us some more context about your environment, why PCI compliance is required and what other things probably need to be mended to comply or even comply better. Best, -Michael On Tue, 2017-02-21 at 14:39 -0500, Kienker, Fred wrote: > FYI: > > This is no longer considered "current" enough to pass a PCI Compliance > audit. Only a version > 7.4 will now pass due to CVE-2016-10009. > Anyone using an IPFire firewall system who has to pass a PCI Compliance > audit will have to disable ssh access until this is updated to at least > 7.4. > > Fred Kienker > > -----Original Message----- > From: Stefan Schantl [mailto:stefan.schantl@ipfire.org] > Sent: Wednesday, November 30, 2016 7:02 AM > To: development@lists.ipfire.org > Subject: [PATCH] openssh: Update to 7.3p1. > > This is a major update to the latest stable version of OpenSSH. > > * Drop not longer required patches. > * Drop SElinux support. > > Fixes #11218. > > Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org> > --- > openssh/openssh.nm | 8 +- > openssh/patches/openssh-6.7p1-audit.patch | 2332 > -------------------- > .../patches/openssh-6.7p1-seccomp-aarch64.patch | 66 - > 3 files changed, 3 insertions(+), 2403 deletions(-) > delete mode 100644 openssh/patches/openssh-6.7p1-audit.patch > delete mode 100644 openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > > diff --git a/openssh/openssh.nm b/openssh/openssh.nm > index 8489438..2e8de76 100644 > --- a/openssh/openssh.nm > +++ b/openssh/openssh.nm > @@ -4,8 +4,8 @@ > ####################################################################### > ######## > > name = openssh > -version = 6.8p1 > -release = 2 > +version = 7.3p1 > +release = 1 > > groups = Application/Internet > url = http://www.openssh.com/portable.html > @@ -28,10 +28,9 @@ build > automake > groff > libedit-devel > - libselinux-devel > ncurses-devel > openldap-devel > - openssl-devel >= 1.0.0d-2 > + openssl-devel >= 1.0.2 > pam-devel > util-linux > zlib-devel > @@ -51,7 +50,6 @@ build > --with-ipaddr-display \ > --with-pam \ > --with-libedit \ > - --with-selinux \ > --with-audit=linux > > prepare_cmds > diff --git a/openssh/patches/openssh-6.7p1-audit.patch > b/openssh/patches/openssh-6.7p1-audit.patch > deleted file mode 100644 > index 213ca67..0000000 > --- a/openssh/patches/openssh-6.7p1-audit.patch > +++ /dev/null > @@ -1,2332 +0,0 @@ > -diff -up openssh-6.8p1/Makefile.in.audit openssh-6.8p1/Makefile.in > ---- openssh-6.8p1/Makefile.in.audit 2015-03-20 13:41:15.065883826 > +0100 > -+++ openssh-6.8p1/Makefile.in 2015-03-20 13:41:15.100883769 +0100 > -@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ > - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o > \ > - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ > - kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ > -- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o > -+ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o > - > - SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ > - sshconnect.o sshconnect1.o sshconnect2.o mux.o \ > -diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c > ---- openssh-6.8p1/audit-bsm.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/audit-bsm.c 2015-03-20 13:41:15.092883782 +0100 > -@@ -375,10 +375,23 @@ audit_connection_from(const char *host, > - #endif > - } > - > --void > -+int > - audit_run_command(const char *command) > - { > - /* not implemented */ > -+ return 0; > -+} > -+ > -+void > -+audit_end_command(int handle, const char *command) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_count_session_open(void) > -+{ > -+ /* not necessary */ > - } > - > - void > -@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li) > - /* not implemented */ > - } > - > -+int > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > *fp, int rv) > -+{ > -+ /* not implemented */ > -+} > -+ > - void > - audit_event(ssh_audit_event_t event) > - { > -@@ -454,4 +473,40 @@ audit_event(ssh_audit_event_t event) > - debug("%s: unhandled event %d", __func__, event); > - } > - } > -+ > -+void > -+audit_unsupported_body(int what) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > *pfs, pid_t pid, uid_t uid) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_destroy_sensitive_data(const char *fp) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > -+{ > -+ /* not implemented */ > -+} > -+ > -+void > -+audit_generate_ephemeral_server_key(const char *fp) > -+{ > -+ /* not implemented */ > -+} > - #endif /* BSM */ > -diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c > ---- openssh-6.8p1/audit-linux.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/audit-linux.c 2015-03-20 13:41:15.093883780 +0100 > -@@ -35,13 +35,25 @@ > - > - #include "log.h" > - #include "audit.h" > -+#include "key.h" > -+#include "hostfile.h" > -+#include "auth.h" > -+#include "misc.h" /* servconf.h needs misc.h for struct > ForwardOptions */ > -+#include "servconf.h" > - #include "canohost.h" > -+#include "packet.h" > -+#include "cipher.h" > - > -+#define AUDIT_LOG_SIZE 256 > -+ > -+extern ServerOptions options; > -+extern Authctxt *the_authctxt; > -+extern u_int utmp_len; > - const char* audit_username(void); > - > --int > --linux_audit_record_event(int uid, const char *username, > -- const char *hostname, const char *ip, const char *ttyn, int > success) > -+static void > -+linux_audit_user_logxxx(int uid, const char *username, > -+ const char *hostname, const char *ip, const char *ttyn, int > success, int event) > - { > - int audit_fd, rc, saved_errno; > - > -@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const char > *username, > - if (audit_fd < 0) { > - if (errno == EINVAL || errno == EPROTONOSUPPORT || > - errno == EAFNOSUPPORT) > -- return 1; /* No audit support in kernel */ > -+ return; /* No audit support in kernel */ > - else > -- return 0; /* Must prevent login */ > -+ goto fatal_report; /* Must prevent login */ > - } > -- rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, > -+ rc = audit_log_acct_message(audit_fd, event, > - NULL, "login", username ? username : "(unknown)", > - username == NULL ? uid : -1, hostname, ip, ttyn, success); > - saved_errno = errno; > -@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const char > *username, > - if ((rc == -EPERM) && (geteuid() != 0)) > - rc = 0; > - errno = saved_errno; > -- return (rc >= 0); > -+ if (rc < 0) { > -+fatal_report: > -+ fatal("linux_audit_write_entry failed: %s", > strerror(errno)); > -+ } > - } > - > -+static void > -+linux_audit_user_auth(int uid, const char *username, > -+ const char *hostname, const char *ip, const char *ttyn, int > success, int event) > -+{ > -+ int audit_fd, rc, saved_errno; > -+ static const char *event_name[] = { > -+ "maxtries exceeded", > -+ "root denied", > -+ "success", > -+ "none", > -+ "password", > -+ "challenge-response", > -+ "pubkey", > -+ "hostbased", > -+ "gssapi", > -+ "invalid user", > -+ "nologin", > -+ "connection closed", > -+ "connection abandoned", > -+ "unknown" > -+ }; > -+ > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > -+ errno == EAFNOSUPPORT) > -+ return; /* No audit support in kernel */ > -+ else > -+ goto fatal_report; /* Must prevent login */ > -+ } > -+ > -+ if ((event < 0) || (event > SSH_AUDIT_UNKNOWN)) > -+ event = SSH_AUDIT_UNKNOWN; > -+ > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, > -+ NULL, event_name[event], username ? username : "(unknown)", > -+ username == NULL ? uid : -1, hostname, ip, ttyn, success); > -+ saved_errno = errno; > -+ close(audit_fd); > -+ /* > -+ * Do not report error if the error is EPERM and sshd is run as > non > -+ * root user. > -+ */ > -+ if ((rc == -EPERM) && (geteuid() != 0)) > -+ rc = 0; > -+ errno = saved_errno; > -+ if (rc < 0) { > -+fatal_report: > -+ fatal("linux_audit_write_entry failed: %s", > strerror(errno)); > -+ } > -+} > -+ > -+int > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > *fp, int rv) > -+{ > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, rc, saved_errno; > -+ > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > -+ errno == EAFNOSUPPORT) > -+ return 1; /* No audit support in kernel */ > -+ else > > > > -+ return 0; /* Must prevent login */ > -+ } > -+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? > "pubkey" : "hostbased", get_remote_port()); > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, > -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, > rv); > -+ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) > -+ goto out; > -+ /* is the fingerprint_prefix() still needed? > -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s > rport=%d", > -+ type, bits, sshkey_fingerprint_prefix(), fp, > get_remote_port()); > -+ */ > -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", > -+ type, bits, fp, get_remote_port()); > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, > -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, > rv); > -+out: > -+ saved_errno = errno; > -+ audit_close(audit_fd); > -+ errno = saved_errno; > -+ /* do not report error if the error is EPERM and sshd is run as > non root user */ > -+ return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0)); > -+} > -+ > -+static int user_login_count = 0; > -+ > - /* Below is the sshd audit API code */ > - > - void > - audit_connection_from(const char *host, int port) > - { > --} > - /* not implemented */ > -+} > - > --void > -+int > - audit_run_command(const char *command) > - { > -- /* not implemented */ > -+ if (!user_login_count++) > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_LOGIN); > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_START); > -+ return 0; > -+} > -+ > -+void > -+audit_end_command(int handle, const char *command) > -+{ > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_END); > -+ if (user_login_count && !--user_login_count) > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); > -+} > -+ > -+void > -+audit_count_session_open(void) > -+{ > -+ user_login_count++; > - } > - > - void > - audit_session_open(struct logininfo *li) > - { > -- if (linux_audit_record_event(li->uid, NULL, li->hostname, > -- NULL, li->line, 1) == 0) > -- fatal("linux_audit_write_entry failed: %s", > strerror(errno)); > -+ if (!user_login_count++) > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > -+ NULL, li->line, 1, AUDIT_USER_LOGIN); > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > -+ NULL, li->line, 1, AUDIT_USER_START); > - } > - > - void > - audit_session_close(struct logininfo *li) > - { > -- /* not implemented */ > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > -+ NULL, li->line, 1, AUDIT_USER_END); > -+ if (user_login_count && !--user_login_count) > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > -+ NULL, li->line, 1, AUDIT_USER_LOGOUT); > - } > - > - void > -@@ -101,21 +232,43 @@ audit_event(ssh_audit_event_t event) > - { > - switch(event) { > - case SSH_AUTH_SUCCESS: > -- case SSH_CONNECTION_CLOSE: > -+ linux_audit_user_auth(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 1, event); > -+ break; > -+ > - case SSH_NOLOGIN: > -- case SSH_LOGIN_EXCEED_MAXTRIES: > - case SSH_LOGIN_ROOT_DENIED: > -+ linux_audit_user_auth(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 0, event); > -+ linux_audit_user_logxxx(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); > - break; > - > -+ case SSH_LOGIN_EXCEED_MAXTRIES: > - case SSH_AUTH_FAIL_NONE: > - case SSH_AUTH_FAIL_PASSWD: > - case SSH_AUTH_FAIL_KBDINT: > - case SSH_AUTH_FAIL_PUBKEY: > - case SSH_AUTH_FAIL_HOSTBASED: > - case SSH_AUTH_FAIL_GSSAPI: > -+ linux_audit_user_auth(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 0, event); > -+ break; > -+ > -+ case SSH_CONNECTION_CLOSE: > -+ if (user_login_count) { > -+ while (user_login_count--) > -+ linux_audit_user_logxxx(the_authctxt->pw- > >pw_uid, > NULL, get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_END); > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, > NULL, > get_remote_name_or_ip(utmp_len, options.use_dns), > -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); > -+ } > -+ break; > -+ > -+ case SSH_CONNECTION_ABANDON: > - case SSH_INVALID_USER: > -- linux_audit_record_event(-1, audit_username(), NULL, > -- get_remote_ipaddr(), "sshd", 0); > -+ linux_audit_user_logxxx(-1, audit_username(), NULL, > -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); > - break; > - > - default: > -@@ -123,4 +276,135 @@ audit_event(ssh_audit_event_t event) > - } > - } > - > -+void > -+audit_unsupported_body(int what) > -+{ > -+#ifdef AUDIT_CRYPTO_SESSION > -+ char buf[AUDIT_LOG_SIZE]; > -+ const static char *name[] = { "cipher", "mac", "comp" }; > -+ char *s; > -+ int audit_fd; > -+ > -+ snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? > cipher=? ksize=? rport=%d laddr=%s lport=%d ", > -+ name[what], get_remote_port(), (s = > get_local_ipaddr(packet_get_connection_in())), > -+ get_local_port()); > -+ free(s); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) > -+ /* no problem, the next instruction will be fatal() */ > -+ return; > -+ audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, > -+ buf, NULL, get_remote_ipaddr(), NULL, 0); > -+ audit_close(audit_fd); > -+#endif > -+} > -+ > -+const static char *direction[] = { "from-server", "from-client", > "both" }; > -+ > -+void > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > *pfs, pid_t pid, > -+ uid_t uid) > -+{ > -+#ifdef AUDIT_CRYPTO_SESSION > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, audit_ok; > -+ const Cipher *cipher = cipher_by_name(enc); > -+ char *s; > -+ > -+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s > ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", > -+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, > mac, > pfs, > -+ (intmax_t)pid, (intmax_t)uid, > -+ get_remote_port(), (s = > get_local_ipaddr(packet_get_connection_in())), get_local_port()); > -+ free(s); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > -+ errno == EAFNOSUPPORT) > -+ return; /* No audit support in kernel */ > -+ else > > > > -+ fatal("cannot open audit"); /* Must prevent login */ > -+ } > -+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, > -+ buf, NULL, get_remote_ipaddr(), NULL, 1); > -+ audit_close(audit_fd); > -+ /* do not abort if the error is EPERM and sshd is run as non root > user */ > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > -+ fatal("cannot write into audit"); /* Must prevent login */ > -+#endif > -+} > -+ > -+void > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, audit_ok; > -+ char *s; > -+ > -+ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? > direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", > -+ direction[ctos], (intmax_t)pid, (intmax_t)uid, > -+ get_remote_port(), > -+ (s = get_local_ipaddr(packet_get_connection_in())), > -+ get_local_port()); > -+ free(s); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > -+ errno != EAFNOSUPPORT) > -+ error("cannot open audit"); > -+ return; > -+ } > -+ audit_ok = audit_log_user_message(audit_fd, > AUDIT_CRYPTO_KEY_USER, > -+ buf, NULL, get_remote_ipaddr(), NULL, 1); > -+ audit_close(audit_fd); > -+ /* do not abort if the error is EPERM and sshd is run as non root > user */ > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > -+ error("cannot write into audit"); > -+} > -+ > -+void > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > -+{ > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, audit_ok; > -+ > -+ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s > direction=? spid=%jd suid=%jd ", > -+ fp, (intmax_t)pid, (intmax_t)uid); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > -+ errno != EAFNOSUPPORT) > -+ error("cannot open audit"); > -+ return; > -+ } > -+ audit_ok = audit_log_user_message(audit_fd, > AUDIT_CRYPTO_KEY_USER, > -+ buf, NULL, > -+ listening_for_clients() ? get_remote_ipaddr() : > NULL, > -+ NULL, 1); > -+ audit_close(audit_fd); > -+ /* do not abort if the error is EPERM and sshd is run as non root > user */ > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > -+ error("cannot write into audit"); > -+} > -+ > -+void > -+audit_generate_ephemeral_server_key(const char *fp) > -+{ > -+ char buf[AUDIT_LOG_SIZE]; > -+ int audit_fd, audit_ok; > -+ > -+ snprintf(buf, sizeof(buf), "op=create kind=server fp=%s > direction=? ", fp); > -+ audit_fd = audit_open(); > -+ if (audit_fd < 0) { > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > -+ errno != EAFNOSUPPORT) > -+ error("cannot open audit"); > -+ return; > -+ } > -+ audit_ok = audit_log_user_message(audit_fd, > AUDIT_CRYPTO_KEY_USER, > -+ buf, NULL, 0, NULL, 1); > -+ audit_close(audit_fd); > -+ /* do not abort if the error is EPERM and sshd is run as non root > user */ > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > -+ error("cannot write into audit"); > -+} > - #endif /* USE_LINUX_AUDIT */ > -diff -up openssh-6.8p1/audit.c.audit openssh-6.8p1/audit.c > ---- openssh-6.8p1/audit.c.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/audit.c 2015-03-20 13:41:15.093883780 +0100 > -@@ -28,6 +28,7 @@ > - > - #include <stdarg.h> > - #include <string.h> > -+#include <unistd.h> > - > - #ifdef SSH_AUDIT_EVENTS > - > -@@ -36,6 +37,11 @@ > - #include "key.h" > - #include "hostfile.h" > - #include "auth.h" > -+#include "ssh-gss.h" > -+#include "monitor_wrap.h" > -+#include "xmalloc.h" > -+#include "misc.h" > -+#include "servconf.h" > - > - /* > - * Care must be taken when using this since it WILL NOT be initialized > when > -@@ -43,6 +49,7 @@ > - * audit_event(CONNECTION_ABANDON) is called. Test for NULL before > using. > - */ > - extern Authctxt *the_authctxt; > -+extern ServerOptions options; > - > - /* Maybe add the audit class to struct Authmethod? */ > - ssh_audit_event_t > -@@ -71,13 +78,10 @@ audit_classify_auth(const char *method) > - const char * > - audit_username(void) > - { > -- static const char unknownuser[] = "(unknown user)"; > -- static const char invaliduser[] = "(invalid user)"; > -+ static const char unknownuser[] = "(unknown)"; > - > -- if (the_authctxt == NULL || the_authctxt->user == NULL) > -+ if (the_authctxt == NULL || the_authctxt->user == NULL || > !the_authctxt->valid) > - return (unknownuser); > -- if (!the_authctxt->valid) > -- return (invaliduser); > - return (the_authctxt->user); > - } > - > -@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) > - return(event_lookup[i].name); > - } > - > -+void > -+audit_key(int host_user, int *rv, const Key *key) > -+{ > -+ char *fp; > -+ const char *crypto_name; > -+ > -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, > SSH_FP_HEX); > -+ if (key->type == KEY_RSA1) > -+ crypto_name = "ssh-rsa1"; > -+ else > -+ crypto_name = key_ssh_name(key); > -+ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, > *rv) == 0) > -+ *rv = 0; > -+ free(fp); > -+} > -+ > -+void > -+audit_unsupported(int what) > -+{ > -+ PRIVSEP(audit_unsupported_body(what)); > -+} > -+ > -+void > -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) > -+{ > -+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), > getuid())); > -+} > -+ > -+void > -+audit_session_key_free(int ctos) > -+{ > -+ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); > -+} > -+ > - # ifndef CUSTOM_SSH_AUDIT_EVENTS > - /* > - * Null implementations of audit functions. > -@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) > - } > - > - /* > -+ * Called when a child process has called, or will soon call, > -+ * audit_session_open. > -+ */ > -+void > -+audit_count_session_open(void) > -+{ > -+ debug("audit count session open euid %d user %s", geteuid(), > -+ audit_username()); > -+} > -+ > -+/* > - * Called when a user session is started. Argument is the tty > allocated to > - * the session, or NULL if no tty was allocated. > - * > -@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li) > - /* > - * This will be called when a user runs a non-interactive command. > Note that > - * it may be called multiple times for a single connection since SSH2 > allows > -- * multiple sessions within a single connection. > -+ * multiple sessions within a single connection. Returns a "handle" > for > -+ * audit_end_command. > - */ > --void > -+int > - audit_run_command(const char *command) > - { > - debug("audit run command euid %d user %s command '%.200s'", > geteuid(), > - audit_username(), command); > -+ return 0; > -+} > -+ > -+/* > -+ * This will be called when the non-interactive command finishes. > Note that > -+ * it may be called multiple times for a single connection since SSH2 > allows > -+ * multiple sessions within a single connection. "handle" should come > from > -+ * the corresponding audit_run_command. > -+ */ > -+void > -+audit_end_command(int handle, const char *command) > -+{ > -+ debug("audit end nopty exec euid %d user %s command '%.200s'", > geteuid(), > -+ audit_username(), command); > -+} > -+ > -+/* > -+ * This will be called when user is successfully autherized by the > RSA1/RSA/DSA key. > -+ * > -+ * Type is the key type, len is the key length(byte) and fp is the > fingerprint of the key. > -+ */ > -+int > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > *fp, int rv) > -+{ > -+ debug("audit %s key usage euid %d user %s key type %s key length > %d fingerprint %s%s, result %d", > -+ host_user ? "pubkey" : "hostbased", geteuid(), > audit_username(), type, bits, > -+ sshkey_fingerprint_prefix(), fp, rv); > -+} > -+ > -+/* > -+ * This will be called when the protocol negotiation fails. > -+ */ > -+void > -+audit_unsupported_body(int what) > -+{ > -+ debug("audit unsupported protocol euid %d type %d", geteuid(), > what); > -+} > -+ > -+/* > -+ * This will be called on succesfull protocol negotiation. > -+ */ > -+void > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > *pfs, pid_t pid, > -+ uid_t uid) > -+{ > -+ debug("audit protocol negotiation euid %d direction %d cipher %s > mac %s compresion %s pfs %s from pid %ld uid %u", > -+ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, > (long)pid, > -+ (unsigned)uid); > -+} > -+ > -+/* > -+ * This will be called on succesfull session key discard > -+ */ > -+void > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+ debug("audit session key discard euid %u direction %d from pid > %ld uid %u", > -+ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); > -+} > -+ > -+/* > -+ * This will be called on destroy private part of the server key > -+ */ > -+void > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > -+{ > -+ debug("audit destroy sensitive data euid %d fingerprint %s from > pid %ld uid %u", > -+ geteuid(), fp, (long)pid, (unsigned)uid); > -+} > -+ > -+/* > -+ * This will be called on generation of the ephemeral server key > -+ */ > -+void > -+audit_generate_ephemeral_server_key(const char *) > -+{ > -+ debug("audit create ephemeral server key euid %d fingerprint %s", > geteuid(), fp); > - } > - # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ > - #endif /* SSH_AUDIT_EVENTS */ > -diff -up openssh-6.8p1/audit.h.audit openssh-6.8p1/audit.h > ---- openssh-6.8p1/audit.h.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/audit.h 2015-03-20 13:41:15.093883780 +0100 > -@@ -28,6 +28,7 @@ > - # define _SSH_AUDIT_H > - > - #include "loginrec.h" > -+#include "key.h" > - > - enum ssh_audit_event_type { > - SSH_LOGIN_EXCEED_MAXTRIES, > -@@ -47,11 +48,25 @@ enum ssh_audit_event_type { > - }; > - typedef enum ssh_audit_event_type ssh_audit_event_t; > - > -+int listening_for_clients(void); > -+ > - void audit_connection_from(const char *, int); > - void audit_event(ssh_audit_event_t); > -+void audit_count_session_open(void); > - void audit_session_open(struct logininfo *); > - void audit_session_close(struct logininfo *); > --void audit_run_command(const char *); > -+int audit_run_command(const char *); > -+void audit_end_command(int, const char *); > - ssh_audit_event_t audit_classify_auth(const char *); > -+int audit_keyusage(int, const char *, unsigned, char *, int); > -+void audit_key(int, int *, const Key *); > -+void audit_unsupported(int); > -+void audit_kex(int, char *, char *, char *, char *); > -+void audit_unsupported_body(int); > -+void audit_kex_body(int, char *, char *, char *, char *, pid_t, > uid_t); > -+void audit_session_key_free(int ctos); > -+void audit_session_key_free_body(int ctos, pid_t, uid_t); > -+void audit_destroy_sensitive_data(const char *, pid_t, uid_t); > -+void audit_generate_ephemeral_server_key(const char *); > - > - #endif /* _SSH_AUDIT_H */ > -diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c > ---- openssh-6.8p1/auditstub.c.audit 2015-03-20 13:41:15.093883780 > +0100 > -+++ openssh-6.8p1/auditstub.c 2015-03-20 13:41:15.093883780 +0100 > -@@ -0,0 +1,50 @@ > -+/* $Id: auditstub.c,v 1.1 jfch Exp $ */ > -+ > -+/* > -+ * Copyright 2010 Red Hat, Inc. All rights reserved. > -+ * Use is subject to license terms. > -+ * > -+ * Redistribution and use in source and binary forms, with or without > -+ * modification, are permitted provided that the following conditions > -+ * are met: > -+ * 1. Redistributions of source code must retain the above copyright > -+ * notice, this list of conditions and the following disclaimer. > -+ * 2. Redistributions in binary form must reproduce the above > copyright > -+ * notice, this list of conditions and the following disclaimer in > the > -+ * documentation and/or other materials provided with the > distribution. > -+ * > -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS > OR > -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > WARRANTIES > -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > DISCLAIMED. > -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES > (INCLUDING, BUT > -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS > OF USE, > -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON > ANY > -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE > USE OF > -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > -+ * > -+ * Red Hat author: Jan F. Chadima <jchadima@redhat.com> > -+ */ > -+ > -+#include <sys/types.h> > -+ > -+void > -+audit_unsupported(int n) > -+{ > -+} > -+ > -+void > -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) > -+{ > -+} > -+ > -+void > -+audit_session_key_free(int ctos) > -+{ > -+} > -+ > -+void > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+} > -diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c > ---- openssh-6.8p1/auth-rsa.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/auth-rsa.c 2015-03-20 13:41:15.094883779 +0100 > -@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNUM > *challenge, u_char response[16]) > - { > - u_char buf[32], mdbuf[16]; > - struct ssh_digest_ctx *md; > -- int len; > -+ int len, rv; > -+#ifdef SSH_AUDIT_EVENTS > -+ char *fp; > -+#endif > - > - /* don't allow short keys */ > - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { > -@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNUM > *challenge, u_char response[16]) > - ssh_digest_free(md); > - > - /* Verify that the response is the original challenge. */ > -- if (timingsafe_bcmp(response, mdbuf, 16) != 0) { > -- /* Wrong answer. */ > -- return (0); > -+ rv = timingsafe_bcmp(response, mdbuf, 16) == 0; > -+ > -+#ifdef SSH_AUDIT_EVENTS > -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, > SSH_FP_HEX); > -+ if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) > == 0) { > -+ debug("unsuccessful audit"); > -+ rv = 0; > - } > -- /* Correct answer. */ > -- return (1); > -+ free(fp); > -+#endif > -+ > -+ return rv; > - } > - > - /* > -diff -up openssh-6.8p1/auth.c.audit openssh-6.8p1/auth.c > ---- openssh-6.8p1/auth.c.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/auth.c 2015-03-20 13:41:15.094883779 +0100 > -@@ -644,9 +644,6 @@ getpwnamallow(const char *user) > - record_failed_login(user, > - get_canonical_hostname(options.use_dns), "ssh"); > - #endif > --#ifdef SSH_AUDIT_EVENTS > -- audit_event(SSH_INVALID_USER); > --#endif /* SSH_AUDIT_EVENTS */ > - return (NULL); > - } > - if (!allowed_user(pw)) > -diff -up openssh-6.8p1/auth.h.audit openssh-6.8p1/auth.h > ---- openssh-6.8p1/auth.h.audit 2015-03-20 13:41:15.002883927 +0100 > -+++ openssh-6.8p1/auth.h 2015-03-20 13:41:15.094883779 +0100 > -@@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt > - > - char *expand_authorized_keys(const char *, struct passwd *pw); > - char *authorized_principals_file(struct passwd *); > -+int user_key_verify(const Key *, const u_char *, u_int, const > u_char *, u_int); > - > - FILE *auth_openkeyfile(const char *, struct passwd *, int); > - FILE *auth_openprincipals(const char *, struct passwd *, int); > -@@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc > - int ssh1_session_key(BIGNUM *); > - int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, > - const u_char *, size_t, u_int); > -+int hostbased_key_verify(const Key *, const u_char *, u_int, > const u_char *, u_int); > - > - /* debug messages during authentication */ > - void auth_debug_add(const char *fmt,...) > __attribute__((format(printf, 1, 2))); > -diff -up openssh-6.8p1/auth2-hostbased.c.audit > openssh-6.8p1/auth2-hostbased.c > ---- openssh-6.8p1/auth2-hostbased.c.audit 2015-03-20 > 13:41:15.002883927 +0100 > -+++ openssh-6.8p1/auth2-hostbased.c 2015-03-20 13:41:15.093883780 > +0100 > -@@ -147,7 +147,7 @@ userauth_hostbased(Authctxt *authctxt) > - /* test for allowed key and correct signature */ > - authenticated = 0; > - if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, > key)) && > -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), > -+ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b), > - buffer_len(&b))) == 1) > - authenticated = 1; > - > -@@ -164,6 +164,18 @@ done: > - return authenticated; > - } > - > -+int > -+hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, > const u_char *data, u_int datalen) > -+{ > -+ int rv; > -+ > -+ rv = key_verify(key, sig, slen, data, datalen); > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_key(0, &rv, key); > -+#endif > -+ return rv; > -+} > -+ > - /* return 1 if given hostkey is allowed */ > - int > - hostbased_key_allowed(struct passwd *pw, const char *cuser, char > *chost, > -diff -up openssh-6.8p1/auth2-pubkey.c.audit > openssh-6.8p1/auth2-pubkey.c > ---- openssh-6.8p1/auth2-pubkey.c.audit 2015-03-20 > 13:41:15.013883910 +0100 > -+++ openssh-6.8p1/auth2-pubkey.c 2015-03-20 13:41:15.094883779 > +0100 > -@@ -172,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt) > - /* test for correct signature */ > - authenticated = 0; > - if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && > -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), > -+ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), > - buffer_len(&b))) == 1) { > - authenticated = 1; > - /* Record the successful key to prevent reuse */ > -@@ -250,6 +250,18 @@ pubkey_auth_info(Authctxt *authctxt, con > - free(extra); > - } > - > -+int > -+user_key_verify(const Key *key, const u_char *sig, u_int slen, const > u_char *data, u_int datalen) > -+{ > -+ int rv; > -+ > -+ rv = key_verify(key, sig, slen, data, datalen); > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_key(1, &rv, key); > -+#endif > -+ return rv; > -+} > -+ > - static int > - match_principals_option(const char *principal_list, struct sshkey_cert > *cert) > - { > -diff -up openssh-6.8p1/auth2.c.audit openssh-6.8p1/auth2.c > ---- openssh-6.8p1/auth2.c.audit 2015-03-20 13:41:15.044883860 +0100 > -+++ openssh-6.8p1/auth2.c 2015-03-20 13:41:15.093883780 +0100 > -@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 > - } else { > - logit("input_userauth_request: invalid user %s", > user); > - authctxt->pw = fakepw(); > --#ifdef SSH_AUDIT_EVENTS > -- PRIVSEP(audit_event(SSH_INVALID_USER)); > --#endif > - } > - #ifdef USE_PAM > - if (options.use_pam) > -diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c > ---- openssh-6.8p1/cipher.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/cipher.c 2015-03-20 13:41:15.101883767 +0100 > -@@ -57,26 +59,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v > - extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); > - #endif > - > --struct sshcipher { > -- char *name; > -- int number; /* for ssh1 only */ > -- u_int block_size; > -- u_int key_len; > -- u_int iv_len; /* defaults to block_size */ > -- u_int auth_len; > -- u_int discard_len; > -- u_int flags; > --#define CFLAG_CBC (1<<0) > --#define CFLAG_CHACHAPOLY (1<<1) > --#define CFLAG_AESCTR (1<<2) > --#define CFLAG_NONE (1<<3) > --#ifdef WITH_OPENSSL > -- const EVP_CIPHER *(*evptype)(void); > --#else > -- void *ignored; > --#endif > --}; > -- > - static const struct sshcipher ciphers[] = { > - #ifdef WITH_SSH1 > - { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, > -diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h > ---- openssh-6.8p1/cipher.h.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/cipher.h 2015-03-20 13:41:15.094883779 +0100 > -@@ -62,7 +62,26 @@ > - #define CIPHER_ENCRYPT 1 > - #define CIPHER_DECRYPT 0 > - > --struct sshcipher; > -+struct sshcipher { > -+ char *name; > -+ int number; /* for ssh1 only */ > -+ u_int block_size; > -+ u_int key_len; > -+ u_int iv_len; /* defaults to block_size */ > -+ u_int auth_len; > -+ u_int discard_len; > -+ u_int flags; > -+#define CFLAG_CBC (1<<0) > -+#define CFLAG_CHACHAPOLY (1<<1) > -+#define CFLAG_AESCTR (1<<2) > -+#define CFLAG_NONE (1<<3) > -+#ifdef WITH_OPENSSL > -+ const EVP_CIPHER *(*evptype)(void); > -+#else > -+ void *ignored; > -+#endif > -+}; > -+ > - struct sshcipher_ctx { > - int plaintext; > - int encrypt; > -diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c > ---- openssh-6.8p1/kex.c.audit 2015-03-20 13:41:15.046883856 +0100 > -+++ openssh-6.8p1/kex.c 2015-03-20 13:41:15.101883767 +0100 > -@@ -54,6 +55,7 @@ > - #include "ssherr.h" > - #include "sshbuf.h" > - #include "digest.h" > -+#include "audit.h" > - > - #ifdef GSSAPI > - #include "ssh-gss.h" > -@@ -484,8 +508,12 @@ choose_enc(struct sshenc *enc, char *cli > - { > - char *name = match_list(client, server, NULL); > - > -- if (name == NULL) > -+ if (name == NULL) { > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_unsupported(0); > -+#endif > - return SSH_ERR_NO_CIPHER_ALG_MATCH; > -+ } > - if ((enc->cipher = cipher_by_name(name)) == NULL) > - return SSH_ERR_INTERNAL_ERROR; > - enc->name = name; > -@@ -503,8 +531,12 @@ choose_mac(struct ssh *ssh, struct sshma > - { > - char *name = match_list(client, server, NULL); > - > -- if (name == NULL) > -+ if (name == NULL) { > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_unsupported(1); > -+#endif > - return SSH_ERR_NO_MAC_ALG_MATCH; > -+ } > - if (mac_setup(mac, name) < 0) > - return SSH_ERR_INTERNAL_ERROR; > - /* truncate the key */ > -@@ -521,8 +553,12 @@ choose_comp(struct sshcomp *comp, char * > - { > - char *name = match_list(client, server, NULL); > - > -- if (name == NULL) > -+ if (name == NULL) { > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_unsupported(2); > -+#endif > - return SSH_ERR_NO_COMPRESS_ALG_MATCH; > -+ } > - if (strcmp(name, "zlib@openssh.com") == 0) { > - comp->type = COMP_DELAYED; > - } else if (strcmp(name, "zlib") == 0) { > -@@ -672,6 +708,10 @@ kex_choose_conf(struct ssh *ssh) > - dh_need = MAX(dh_need, newkeys->enc.block_size); > - dh_need = MAX(dh_need, newkeys->enc.iv_len); > - dh_need = MAX(dh_need, newkeys->mac.key_len); > -+ debug("kex: %s need=%d dh_need=%d", kex->name, need, > dh_need); > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_kex(mode, newkeys->enc.name, newkeys->mac.name, > newkeys->comp.name, kex->name); > -+#endif > - } > - /* XXX need runden? */ > - kex->we_need = need; > -@@ -847,3 +887,34 @@ dump_digest(char *msg, u_char *digest, i > - sshbuf_dump_data(digest, len, stderr); > - } > - #endif > -+ > -+static void > -+enc_destroy(struct sshenc *enc) > -+{ > -+ if (enc == NULL) > -+ return; > -+ > -+ if (enc->key) { > -+ memset(enc->key, 0, enc->key_len); > -+ free(enc->key); > -+ } > -+ > -+ if (enc->iv) { > -+ memset(enc->iv, 0, enc->block_size); > -+ free(enc->iv); > -+ } > -+ > -+ memset(enc, 0, sizeof(*enc)); > -+} > -+ > -+void > -+newkeys_destroy(struct newkeys *newkeys) > -+{ > -+ if (newkeys == NULL) > -+ return; > -+ > -+ enc_destroy(&newkeys->enc); > -+ mac_destroy(&newkeys->mac); > -+ memset(&newkeys->comp, 0, sizeof(newkeys->comp)); > -+} > -+ > -diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h > ---- openssh-6.8p1/kex.h.audit 2015-03-20 13:41:15.046883856 +0100 > -+++ openssh-6.8p1/kex.h 2015-03-20 13:41:15.095883777 +0100 > -@@ -199,6 +199,8 @@ int kexgss_client(struct ssh *); > - int kexgss_server(struct ssh *); > - #endif > - > -+void newkeys_destroy(struct newkeys *newkeys); > -+ > - int kex_dh_hash(const char *, const char *, > - const u_char *, size_t, const u_char *, size_t, const u_char *, > size_t, > - const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t > *); > -diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h > ---- openssh-6.8p1/key.h.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/key.h 2015-03-20 13:41:15.095883777 +0100 > -@@ -50,6 +50,7 @@ typedef struct sshkey Key; > - #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid > - #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid > - #define key_is_cert sshkey_is_cert > -+#define key_is_private sshkey_is_private > - #define key_type_plain sshkey_type_plain > - #define key_cert_is_legacy sshkey_cert_is_legacy > - #define key_curve_name_to_nid sshkey_curve_name_to_nid > -diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c > ---- openssh-6.8p1/mac.c.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/mac.c 2015-03-20 13:41:15.102883766 +0100 > -@@ -226,6 +246,20 @@ mac_clear(struct sshmac *mac) > - mac->umac_ctx = NULL; > - } > - > -+void > -+mac_destroy(struct sshmac *mac) > -+{ > -+ if (mac == NULL) > -+ return; > -+ > -+ if (mac->key) { > -+ memset(mac->key, 0, mac->key_len); > -+ free(mac->key); > -+ } > -+ > -+ memset(mac, 0, sizeof(*mac)); > -+} > -+ > - /* XXX copied from ciphers_valid */ > - #define MAC_SEP "," > - int > -diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h > ---- openssh-6.8p1/mac.h.audit 2015-03-17 06:49:20.000000000 +0100 > -+++ openssh-6.8p1/mac.h 2015-03-20 13:41:15.095883777 +0100 > -@@ -47,5 +47,6 @@ int mac_init(struct sshmac *); > - int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, > - u_char *, size_t); > - void mac_clear(struct sshmac *); > -+void mac_destroy(struct sshmac *); > - > - #endif /* SSHMAC_H */ > -diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c > ---- openssh-6.8p1/monitor.c.audit 2015-03-20 13:41:15.072883814 > +0100 > -+++ openssh-6.8p1/monitor.c 2015-03-20 13:41:15.107883758 +0100 > -@@ -102,6 +102,7 @@ > - #include "ssh2.h" > - #include "roaming.h" > - #include "authfd.h" > -+#include "audit.h" > - #include "match.h" > - #include "ssherr.h" > - > -@@ -117,6 +118,8 @@ extern Buffer auth_debug; > - extern int auth_debug_init; > - extern Buffer loginmsg; > - > -+extern void destroy_sensitive_data(int); > -+ > - /* State exported from the child */ > - static struct sshbuf *child_state; > - > -@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe > - #ifdef SSH_AUDIT_EVENTS > - int mm_answer_audit_event(int, Buffer *); > - int mm_answer_audit_command(int, Buffer *); > -+int mm_answer_audit_end_command(int, Buffer *); > -+int mm_answer_audit_unsupported_body(int, Buffer *); > -+int mm_answer_audit_kex_body(int, Buffer *); > -+int mm_answer_audit_session_key_free_body(int, Buffer *); > -+int mm_answer_audit_server_key_free(int, Buffer *); > - #endif > - > - static int monitor_read_log(struct monitor *); > -@@ -226,6 +234,10 @@ struct mon_table mon_dispatch_proto20[] > - #endif > - #ifdef SSH_AUDIT_EVENTS > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > mm_answer_audit_unsupported_body}, > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > mm_answer_audit_session_key_free_body}, > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > mm_answer_audit_server_key_free}, > - #endif > - #ifdef BSD_AUTH > - {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, > -@@ -264,6 +276,11 @@ struct mon_table mon_dispatch_postauth20 > - #ifdef SSH_AUDIT_EVENTS > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > - {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, > -+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, > mm_answer_audit_end_command}, > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > mm_answer_audit_unsupported_body}, > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > mm_answer_audit_session_key_free_body}, > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > mm_answer_audit_server_key_free}, > - #endif > - {0, 0, NULL} > - }; > -@@ -296,6 +313,10 @@ struct mon_table mon_dispatch_proto15[] > - #endif > - #ifdef SSH_AUDIT_EVENTS > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > mm_answer_audit_unsupported_body}, > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > mm_answer_audit_session_key_free_body}, > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > mm_answer_audit_server_key_free}, > - #endif > - #endif /* WITH_SSH1 */ > - {0, 0, NULL} > -@@ -309,6 +330,11 @@ struct mon_table mon_dispatch_postauth15 > - #ifdef SSH_AUDIT_EVENTS > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > - {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, > mm_answer_audit_command}, > -+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, > mm_answer_audit_end_command}, > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > mm_answer_audit_unsupported_body}, > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > mm_answer_audit_session_key_free_body}, > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > mm_answer_audit_server_key_free}, > - #endif > - #endif /* WITH_SSH1 */ > - {0, 0, NULL} > -@@ -1466,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m) > - Key *key; > - u_char *signature, *data, *blob; > - u_int signaturelen, datalen, bloblen; > -+ int type = 0; > - int verified = 0; > - int valid_data = 0; > - > -+ type = buffer_get_int(m); > - blob = buffer_get_string(m, &bloblen); > - signature = buffer_get_string(m, &signaturelen); > - data = buffer_get_string(m, &datalen); > -@@ -1476,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m) > - if (hostbased_cuser == NULL || hostbased_chost == NULL || > - !monitor_allowed_key(blob, bloblen)) > - fatal("%s: bad key, not previously allowed", __func__); > -+ if (type != key_blobtype) > -+ fatal("%s: bad key type", __func__); > - > - key = key_from_blob(blob, bloblen); > - if (key == NULL) > -@@ -1496,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m) > - if (!valid_data) > - fatal("%s: bad signature data blob", __func__); > - > -- verified = key_verify(key, signature, signaturelen, data, > datalen); > -+ switch (key_blobtype) { > -+ case MM_USERKEY: > -+ verified = user_key_verify(key, signature, signaturelen, > data, datalen); > -+ break; > -+ case MM_HOSTKEY: > -+ verified = hostbased_key_verify(key, signature, > signaturelen, data, datalen); > -+ break; > -+ default: > -+ verified = 0; > -+ break; > -+ } > - debug3("%s: key %p signature %s", > - __func__, key, (verified == 1) ? "verified" : "unverified"); > - > -@@ -1554,6 +1595,12 @@ mm_session_close(Session *s) > - debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); > - session_pty_cleanup2(s); > - } > -+#ifdef SSH_AUDIT_EVENTS > -+ if (s->command != NULL) { > -+ debug3("%s: command %d", __func__, s->command_handle); > -+ session_end_command2(s); > -+ } > -+#endif > - session_unused(s->self); > - } > - > -@@ -1836,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req) > - sshpam_cleanup(); > - #endif > - > -+ destroy_sensitive_data(0); > -+ > - while (waitpid(pmonitor->m_pid, &status, 0) == -1) > - if (errno != EINTR) > - exit(1); > -@@ -1878,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff > - { > - u_int len; > - char *cmd; > -+ Session *s; > - > - debug3("%s entering", __func__); > - cmd = buffer_get_string(m, &len); > -+ > - /* sanity check command, if so how? */ > -- audit_run_command(cmd); > -+ s = session_new(); > -+ if (s == NULL) > -+ fatal("%s: error allocating a session", __func__); > -+ s->command = cmd; > -+ s->command_handle = audit_run_command(cmd); > -+ > -+ buffer_clear(m); > -+ buffer_put_int(m, s->self); > -+ > -+ mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m); > -+ > -+ return (0); > -+} > -+ > -+int > -+mm_answer_audit_end_command(int socket, Buffer *m) > -+{ > -+ int handle; > -+ u_int len; > -+ char *cmd; > -+ Session *s; > -+ > -+ debug3("%s entering", __func__); > -+ handle = buffer_get_int(m); > -+ cmd = buffer_get_string(m, &len); > -+ > -+ s = session_by_id(handle); > -+ if (s == NULL || s->ttyfd != -1 || s->command == NULL || > -+ strcmp(s->command, cmd) != 0) > -+ fatal("%s: invalid handle", __func__); > -+ mm_session_close(s); > - free(cmd); > - return (0); > - } > -@@ -1936,6 +2017,7 @@ > - void > - mm_get_keystate(struct monitor *pmonitor) > - { > -+ Buffer m; > - debug3("%s: Waiting for new keys", __func__); > - > - if ((child_state = sshbuf_new()) == NULL) > -@@ -1946,6 +2027,21 @@ mm_get_keystate(struct monitor *pmonitor > - mm_request_receive_expect(pmonitor->m_sendfd, > MONITOR_REQ_KEYEXPORT, > - child_state); > - debug3("%s: GOT new keys", __func__); > -+ > -+#ifdef SSH_AUDIT_EVENTS > -+ if (compat20) { > -+ buffer_init(&m); > -+ mm_request_receive_expect(pmonitor->m_sendfd, > -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE > , &m); > -+ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, > &m); > -+ buffer_free(&m); > -+ } > -+#endif > -+ > -+ /* Drain any buffered messages from the child */ > -+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) > == 0) > -+ ; > -+ > - } > - > - > -@@ -2212,3 +2308,87 @@ mm_answer_gss_updatecreds(int socket, Bu > - > - #endif /* GSSAPI */ > - > -+#ifdef SSH_AUDIT_EVENTS > -+int > -+mm_answer_audit_unsupported_body(int sock, Buffer *m) > -+{ > -+ int what; > -+ > -+ what = buffer_get_int(m); > -+ > -+ audit_unsupported_body(what); > -+ > -+ buffer_clear(m); > -+ > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m); > -+ return 0; > -+} > -+ > -+int > -+mm_answer_audit_kex_body(int sock, Buffer *m) > -+{ > -+ int ctos, len; > -+ char *cipher, *mac, *compress, *pfs; > -+ pid_t pid; > -+ uid_t uid; > -+ > -+ ctos = buffer_get_int(m); > -+ cipher = buffer_get_string(m, &len); > -+ mac = buffer_get_string(m, &len); > -+ compress = buffer_get_string(m, &len); > -+ pfs = buffer_get_string(m, &len); > -+ pid = buffer_get_int64(m); > -+ uid = buffer_get_int64(m); > -+ > -+ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); > -+ > -+ free(cipher); > -+ free(mac); > -+ free(compress); > -+ free(pfs); > -+ buffer_clear(m); > -+ > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); > -+ return 0; > -+} > -+ > -+int > -+mm_answer_audit_session_key_free_body(int sock, Buffer *m) > -+{ > -+ int ctos; > -+ pid_t pid; > -+ uid_t uid; > -+ > -+ ctos = buffer_get_int(m); > -+ pid = buffer_get_int64(m); > -+ uid = buffer_get_int64(m); > -+ > -+ audit_session_key_free_body(ctos, pid, uid); > -+ > -+ buffer_clear(m); > -+ > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m); > -+ return 0; > -+} > -+ > -+int > -+mm_answer_audit_server_key_free(int sock, Buffer *m) > -+{ > -+ int len; > -+ char *fp; > -+ pid_t pid; > -+ uid_t uid; > -+ > -+ fp = buffer_get_string(m, &len); > -+ pid = buffer_get_int64(m); > -+ uid = buffer_get_int64(m); > -+ > -+ audit_destroy_sensitive_data(fp, pid, uid); > -+ > -+ free(fp); > -+ buffer_clear(m); > -+ > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m); > -+ return 0; > -+} > -+#endif /* SSH_AUDIT_EVENTS */ > -diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h > ---- openssh-6.8p1/monitor.h.audit 2015-03-20 13:41:15.072883814 > +0100 > -+++ openssh-6.8p1/monitor.h 2015-03-20 13:41:15.096883775 +0100 > -@@ -69,7 +69,13 @@ enum monitor_reqtype { > - MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, > - MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, > - MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, > -- MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, > -+ MONITOR_REQ_AUDIT_EVENT = 112, > -+ MONITOR_REQ_AUDIT_COMMAND = 114, MONITOR_ANS_AUDIT_COMMAND = 115, > -+ MONITOR_REQ_AUDIT_END_COMMAND = 116, > -+ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, > MONITOR_ANS_AUDIT_UNSUPPORTED = 119, > -+ MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, > -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, > MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, > -+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, > MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125 > - > - }; > - > -diff -up openssh-6.8p1/monitor_wrap.c.audit > openssh-6.8p1/monitor_wrap.c > ---- openssh-6.8p1/monitor_wrap.c.audit 2015-03-20 > 13:41:15.047883855 +0100 > -+++ openssh-6.8p1/monitor_wrap.c 2015-03-20 13:41:15.108883756 > +0100 > -@@ -461,7 +461,7 @@ mm_key_allowed(enum mm_keytype type, cha > - */ > - > - int > --mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int > datalen) > -+mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int > siglen, u_char *data, u_int datalen) > - { > - Buffer m; > - u_char *blob; > -@@ -475,6 +475,7 @@ mm_key_verify(Key *key, u_char *sig, u_i > - return (0); > - > - buffer_init(&m); > -+ buffer_put_int(&m, type); > - buffer_put_string(&m, blob, len); > - buffer_put_string(&m, sig, siglen); > - buffer_put_string(&m, data, datalen); > -@@ -492,6 +493,18 @@ mm_key_verify(Key *key, u_char *sig, u_i > - return (verified); > - } > - > -+int > -+mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char > *data, u_int datalen) > -+{ > -+ return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, > datalen); > -+} > -+ > -+int > -+mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, > u_int datalen) > -+{ > -+ return mm_key_verify(MM_USERKEY, key, sig, siglen, data, > datalen); > -+} > -+ > - void > - mm_send_keystate(struct monitor *monitor) > - { > -@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event) > - buffer_free(&m); > - } > - > --void > -+int > - mm_audit_run_command(const char *command) > - { > - Buffer m; > -+ int handle; > - > - debug3("%s entering command %s", __func__, command); > - > -@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command > - buffer_put_cstring(&m, command); > - > - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, > &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_COMMAND, &m); > -+ > -+ handle = buffer_get_int(&m); > -+ buffer_free(&m); > -+ > -+ return (handle); > -+} > -+ > -+void > -+mm_audit_end_command(int handle, const char *command) > -+{ > -+ Buffer m; > -+ > -+ debug3("%s entering command %s", __func__, command); > -+ > -+ buffer_init(&m); > -+ buffer_put_int(&m, handle); > -+ buffer_put_cstring(&m, command); > -+ > -+ mm_request_send(pmonitor->m_recvfd, > MONITOR_REQ_AUDIT_END_COMMAND, &m); > - buffer_free(&m); > - } > - #endif /* SSH_AUDIT_EVENTS */ > -@@ -1151,3 +1185,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc > - > - #endif /* GSSAPI */ > - > -+#ifdef SSH_AUDIT_EVENTS > -+void > -+mm_audit_unsupported_body(int what) > -+{ > -+ Buffer m; > -+ > -+ buffer_init(&m); > -+ buffer_put_int(&m, what); > -+ > -+ mm_request_send(pmonitor->m_recvfd, > MONITOR_REQ_AUDIT_UNSUPPORTED, &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_UNSUPPORTED, > -+ &m); > -+ > -+ buffer_free(&m); > -+} > -+ > -+void > -+mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, > char *fps, pid_t pid, > -+ uid_t uid) > -+{ > -+ Buffer m; > -+ > -+ buffer_init(&m); > -+ buffer_put_int(&m, ctos); > -+ buffer_put_cstring(&m, cipher); > -+ buffer_put_cstring(&m, (mac ? mac : "")); > -+ buffer_put_cstring(&m, compress); > -+ buffer_put_cstring(&m, fps); > -+ buffer_put_int64(&m, pid); > -+ buffer_put_int64(&m, uid); > -+ > -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_KEX, > -+ &m); > -+ > -+ buffer_free(&m); > -+} > -+ > -+void > -+mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > -+{ > -+ Buffer m; > -+ > -+ buffer_init(&m); > -+ buffer_put_int(&m, ctos); > -+ buffer_put_int64(&m, pid); > -+ buffer_put_int64(&m, uid); > -+ mm_request_send(pmonitor->m_recvfd, > MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_SESSION_KEY_FREE, > -+ &m); > -+ buffer_free(&m); > -+} > -+ > -+void > -+mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > -+{ > -+ Buffer m; > -+ > -+ buffer_init(&m); > -+ buffer_put_cstring(&m, fp); > -+ buffer_put_int64(&m, pid); > -+ buffer_put_int64(&m, uid); > -+ > -+ mm_request_send(pmonitor->m_recvfd, > MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); > -+ mm_request_receive_expect(pmonitor->m_recvfd, > MONITOR_ANS_AUDIT_SERVER_KEY_FREE, > -+ &m); > -+ buffer_free(&m); > -+} > -+#endif /* SSH_AUDIT_EVENTS */ > -diff -up openssh-6.8p1/monitor_wrap.h.audit > openssh-6.8p1/monitor_wrap.h > ---- openssh-6.8p1/monitor_wrap.h.audit 2015-03-20 > 13:41:15.048883853 +0100 > -+++ openssh-6.8p1/monitor_wrap.h 2015-03-20 13:41:15.096883775 > +0100 > -@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char > - int mm_user_key_allowed(struct passwd *, Key *); > - int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); > - int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, > Key *); > --int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); > -+int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int); > -+int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int); > - int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); > - int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); > - BIGNUM *mm_auth_rsa_generate_challenge(Key *); > -@@ -79,7 +80,12 @@ void mm_sshpam_free_ctx(void *); > - #ifdef SSH_AUDIT_EVENTS > - #include "audit.h" > - void mm_audit_event(ssh_audit_event_t); > --void mm_audit_run_command(const char *); > -+int mm_audit_run_command(const char *); > -+void mm_audit_end_command(int, const char *); > -+void mm_audit_unsupported_body(int); > -+void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, > uid_t); > -+void mm_audit_session_key_free_body(int, pid_t, uid_t); > -+void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); > - #endif > - > - struct Session; > -diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c > ---- openssh-6.8p1/packet.c.audit 2015-03-20 13:41:14.990883947 > +0100 > -+++ openssh-6.8p1/packet.c 2015-03-20 13:41:15.097883774 +0100 > -@@ -67,6 +67,7 @@ > - #include "key.h" /* typedefs XXX */ > - > - #include "xmalloc.h" > -+#include "audit.h" > - #include "crc32.h" > - #include "deattack.h" > - #include "compat.h" > -@@ -448,6 +449,13 @@ ssh_packet_get_connection_out(struct ssh > - return ssh->state->connection_out; > - } > - > -+static int > -+packet_state_has_keys (const struct session_state *state) > -+{ > -+ return state != NULL && > -+ (state->newkeys[MODE_IN] != NULL || state- > >newkeys[MODE_OUT] > != NULL); > -+} > -+ > - /* > - * Returns the IP-address of the remote host as a string. The > returned > - * string must not be freed. > -@@ -478,13 +486,6 @@ ssh_packet_close(struct ssh *ssh) > - if (!state->initialized) > - return; > - state->initialized = 0; > -- if (state->connection_in == state->connection_out) { > -- shutdown(state->connection_out, SHUT_RDWR); > -- close(state->connection_out); > -- } else { > -- close(state->connection_in); > -- close(state->connection_out); > -- } > - sshbuf_free(state->input); > - sshbuf_free(state->output); > - sshbuf_free(state->outgoing_packet); > -@@ -516,14 +517,24 @@ ssh_packet_close(struct ssh *ssh) > - inflateEnd(stream); > - } > - } > -- if ((r = cipher_cleanup(&state->send_context)) != 0) > -- error("%s: cipher_cleanup failed: %s", __func__, > ssh_err(r)); > -- if ((r = cipher_cleanup(&state->receive_context)) != 0) > -- error("%s: cipher_cleanup failed: %s", __func__, > ssh_err(r)); > -+ if (packet_state_has_keys(state)) { > -+ if ((r = cipher_cleanup(&state->send_context)) != 0) > -+ error("%s: cipher_cleanup failed: %s", __func__, > ssh_err(r)); > -+ if ((r = cipher_cleanup(&state->receive_context)) != 0) > -+ error("%s: cipher_cleanup failed: %s", __func__, > ssh_err(r)); > -+ audit_session_key_free(2); > -+ } > - if (ssh->remote_ipaddr) { > - free(ssh->remote_ipaddr); > - ssh->remote_ipaddr = NULL; > - } > -+ if (state->connection_in == state->connection_out) { > -+ shutdown(state->connection_out, SHUT_RDWR); > -+ close(state->connection_out); > -+ } else { > -+ close(state->connection_in); > -+ close(state->connection_out); > -+ } > - free(ssh->state); > - ssh->state = NULL; > - } > -@@ -941,6 +952,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod > - } > - if (state->newkeys[mode] != NULL) { > - debug("set_newkeys: rekeying"); > -+ audit_session_key_free(mode); > - if ((r = cipher_cleanup(cc)) != 0) > - return r; > - enc = &state->newkeys[mode]->enc; > -@@ -2263,6 +2275,75 @@ ssh_packet_get_output(struct ssh *ssh) > - return (void *)ssh->state->output; > - } > - > -+static void > -+newkeys_destroy_and_free(struct newkeys *newkeys) > -+{ > -+ if (newkeys == NULL) > -+ return; > -+ > -+ free(newkeys->enc.name); > -+ > -+ if (newkeys->mac.enabled) { > -+ mac_clear(&newkeys->mac); > -+ free(newkeys->mac.name); > -+ } > -+ > -+ free(newkeys->comp.name); > -+ > -+ newkeys_destroy(newkeys); > -+ free(newkeys); > -+} > -+ > -+static void > -+packet_destroy_state(struct session_state *state) > -+{ > -+ if (state == NULL) > -+ return; > -+ > -+ cipher_cleanup(&state->receive_context); > -+ cipher_cleanup(&state->send_context); > -+ > -+ buffer_free(state->input); > -+ state->input = NULL; > -+ buffer_free(state->output); > -+ state->output = NULL; > -+ buffer_free(state->outgoing_packet); > -+ state->outgoing_packet = NULL; > -+ buffer_free(state->incoming_packet); > -+ state->incoming_packet = NULL; > -+ if( state->compression_buffer ) { > -+ buffer_free(state->compression_buffer); > -+ state->compression_buffer = NULL; > -+ } > -+ newkeys_destroy_and_free(state->newkeys[MODE_IN]); > -+ state->newkeys[MODE_IN] = NULL; > -+ newkeys_destroy_and_free(state->newkeys[MODE_OUT]); > -+ state->newkeys[MODE_OUT] = NULL; > -+ mac_destroy(state->packet_discard_mac); > -+// TAILQ_HEAD(, packet) outgoing; > -+// memset(state, 0, sizeof(state)); > -+} > -+ > -+void > -+packet_destroy_all(int audit_it, int privsep) > -+{ > -+ if (audit_it) > -+ audit_it = (active_state != NULL && > packet_state_has_keys(active_state->state)) > -+ || (backup_state != NULL && > packet_state_has_keys(backup_state->state)); > -+ if (active_state != NULL) > -+ packet_destroy_state(active_state->state); > -+ if (backup_state != NULL) > -+ packet_destroy_state(backup_state->state); > -+ if (audit_it) { > -+#ifdef SSH_AUDIT_EVENTS > -+ if (privsep) > -+ audit_session_key_free(2); > -+ else > -+ audit_session_key_free_body(2, getpid(), getuid()); > -+#endif > -+ } > -+} > -+ > - /* XXX TODO update roaming to new API (does not work anyway) */ > - /* > - * Save the state for the real connection, and use a separate state > when > -@@ -2272,18 +2373,12 @@ void > - ssh_packet_backup_state(struct ssh *ssh, > - struct ssh *backup_state) > - { > -- struct ssh *tmp; > -- > - close(ssh->state->connection_in); > - ssh->state->connection_in = -1; > - close(ssh->state->connection_out); > - ssh->state->connection_out = -1; > -- if (backup_state) > -- tmp = backup_state; > -- else > -- tmp = ssh_alloc_session_state(); > - backup_state = ssh; > -- ssh = tmp; > -+ ssh = ssh_alloc_session_state(); > - } > - > - /* XXX FIXME FIXME FIXME */ > -@@ -2302,9 +2397,7 @@ ssh_packet_restore_state(struct ssh *ssh > - backup_state = ssh; > - ssh = tmp; > - ssh->state->connection_in = backup_state->state->connection_in; > -- backup_state->state->connection_in = -1; > - ssh->state->connection_out = backup_state->state->connection_out; > -- backup_state->state->connection_out = -1; > - len = sshbuf_len(backup_state->state->input); > - if (len > 0) { > - if ((r = sshbuf_putb(ssh->state->input, > -@@ -2313,6 +2406,11 @@ ssh_packet_restore_state(struct ssh *ssh > - sshbuf_reset(backup_state->state->input); > - add_recv_bytes(len); > - } > -+ backup_state->state->connection_in = -1; > -+ backup_state->state->connection_out = -1; > -+ packet_destroy_state(backup_state->state); > -+ free(backup_state); > -+ backup_state = NULL; > - } > - > - /* Reset after_authentication and reset compression in post-auth > privsep */ > -diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h > ---- openssh-6.8p1/packet.h.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/packet.h 2015-03-20 13:41:15.097883774 +0100 > -@@ -189,7 +189,7 @@ int sshpkt_get_end(struct ssh *ssh); > - const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); > - > - /* OLD API */ > --extern struct ssh *active_state; > -+extern struct ssh *active_state, *backup_state; > - #include "opacket.h" > - > - #if !defined(WITH_OPENSSL) > -@@ -203,4 +203,5 @@ extern struct ssh *active_state; > - # undef EC_POINT > - #endif > - > -+void packet_destroy_all(int, int); > - #endif /* PACKET_H */ > -diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c > ---- openssh-6.8p1/session.c.audit 2015-03-20 13:41:15.073883813 > +0100 > -+++ openssh-6.8p1/session.c 2015-03-20 13:41:15.097883774 +0100 > -@@ -139,7 +139,7 @@ extern int log_stderr; > - extern int debug_flag; > - extern u_int utmp_len; > - extern int startup_pipe; > --extern void destroy_sensitive_data(void); > -+extern void destroy_sensitive_data(int); > - extern Buffer loginmsg; > - > - /* original command from peer. */ > -@@ -731,6 +731,14 @@ do_exec_pty(Session *s, const char *comm > - /* Parent. Close the slave side of the pseudo tty. */ > - close(ttyfd); > - > -+#ifndef HAVE_OSF_SIA > -+ /* do_login in the child did not affect state in this process, > -+ compensate. From an architectural standpoint, this is > extremely > -+ ugly. */ > -+ if (!(options.use_login && command == NULL)) > -+ audit_count_session_open(); > -+#endif > -+ > - /* Enter interactive session. */ > - s->ptymaster = ptymaster; > - packet_set_interactive(1, > -@@ -853,15 +861,19 @@ do_exec(Session *s, const char *command) > - get_remote_port()); > - > - #ifdef SSH_AUDIT_EVENTS > -+ if (s->command != NULL || s->command_handle != -1) > -+ fatal("do_exec: command already set"); > - if (command != NULL) > -- PRIVSEP(audit_run_command(command)); > -+ s->command = xstrdup(command); > - else if (s->ttyfd == -1) { > - char *shell = s->pw->pw_shell; > - > - if (shell[0] == '\0') /* empty shell means /bin/sh */ > - shell =_PATH_BSHELL; > -- PRIVSEP(audit_run_command(shell)); > -+ s->command = xstrdup(shell); > - } > -+ if (s->command != NULL && s->ptyfd == -1) > -+ s->command_handle = PRIVSEP(audit_run_command(s->command)); > - #endif > - if (s->ttyfd != -1) > - ret = do_exec_pty(s, command); > -@@ -1704,7 +1716,10 @@ do_child(Session *s, const char *command > - int r = 0; > - > - /* remove hostkey from the child's memory */ > -- destroy_sensitive_data(); > -+ destroy_sensitive_data(1); > -+ /* Don't audit this - both us and the parent would be talking to > the > -+ monitor over a single socket, with no synchronization. */ > -+ packet_destroy_all(0, 1); > - > - /* Force a password change */ > - if (s->authctxt->force_pwchange) { > -@@ -1934,6 +1949,7 @@ session_unused(int id) > - sessions[id].ttyfd = -1; > - sessions[id].ptymaster = -1; > - sessions[id].x11_chanids = NULL; > -+ sessions[id].command_handle = -1; > - sessions[id].next_unused = sessions_first_unused; > - sessions_first_unused = id; > - } > -@@ -2016,6 +2032,19 @@ session_open(Authctxt *authctxt, int cha > - } > - > - Session * > -+session_by_id(int id) > -+{ > -+ if (id >= 0 && id < sessions_nalloc) { > -+ Session *s = &sessions[id]; > -+ if (s->used) > -+ return s; > -+ } > -+ debug("session_by_id: unknown id %d", id); > -+ session_dump(); > -+ return NULL; > -+} > -+ > -+Session * > - session_by_tty(char *tty) > - { > - int i; > -@@ -2532,6 +2561,32 @@ session_exit_message(Session *s, int sta > - chan_write_failed(c); > - } > - > -+#ifdef SSH_AUDIT_EVENTS > -+void > -+session_end_command2(Session *s) > -+{ > -+ if (s->command != NULL) { > -+ if (s->command_handle != -1) > -+ audit_end_command(s->command_handle, s->command); > -+ free(s->command); > -+ s->command = NULL; > -+ s->command_handle = -1; > -+ } > -+} > -+ > -+static void > -+session_end_command(Session *s) > -+{ > -+ if (s->command != NULL) { > -+ if (s->command_handle != -1) > -+ PRIVSEP(audit_end_command(s->command_handle, > s->command)); > -+ free(s->command); > -+ s->command = NULL; > -+ s->command_handle = -1; > -+ } > -+} > -+#endif > -+ > - void > - session_close(Session *s) > - { > -@@ -2540,6 +2593,10 @@ session_close(Session *s) > - debug("session_close: session %d pid %ld", s->self, > (long)s->pid); > - if (s->ttyfd != -1) > - session_pty_cleanup(s); > -+#ifdef SSH_AUDIT_EVENTS > -+ if (s->command) > -+ session_end_command(s); > -+#endif > - free(s->term); > - free(s->display); > - free(s->x11_chanids); > -@@ -2754,6 +2811,15 @@ do_authenticated2(Authctxt *authctxt) > - server_loop2(authctxt); > - } > - > -+static void > -+do_cleanup_one_session(Session *s) > -+{ > -+ session_pty_cleanup2(s); > -+#ifdef SSH_AUDIT_EVENTS > -+ session_end_command2(s); > -+#endif > -+} > -+ > - void > - do_cleanup(Authctxt *authctxt) > - { > -@@ -2802,5 +2868,5 @@ do_cleanup(Authctxt *authctxt) > - * or if running in monitor. > - */ > - if (!use_privsep || mm_is_monitor()) > -- session_destroy_all(session_pty_cleanup2); > -+ session_destroy_all(do_cleanup_one_session); > - } > -diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h > ---- openssh-6.8p1/session.h.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/session.h 2015-03-20 13:41:15.097883774 +0100 > -@@ -61,6 +61,12 @@ struct Session { > - char *name; > - char *val; > - } *env; > -+ > -+ /* exec */ > -+#ifdef SSH_AUDIT_EVENTS > -+ int command_handle; > -+ char *command; > -+#endif > - }; > - > - void do_authenticated(Authctxt *); > -@@ -73,8 +79,10 @@ void session_close_by_pid(pid_t, int); > - void session_close_by_channel(int, void *); > - void session_destroy_all(void (*)(Session *)); > - void session_pty_cleanup2(Session *); > -+void session_end_command2(Session *); > - > - Session *session_new(void); > -+Session *session_by_id(int); > - Session *session_by_tty(char *); > - void session_close(Session *); > - void do_setusercontext(struct passwd *); > -diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c > ---- openssh-6.8p1/sshd.c.audit 2015-03-20 13:41:15.083883796 +0100 > -+++ openssh-6.8p1/sshd.c 2015-03-20 13:41:15.110883753 +0100 > -@@ -121,6 +124,7 @@ > - #endif > - #include "monitor_wrap.h" > - #include "roaming.h" > -+#include "audit.h" > - #include "ssh-sandbox.h" > - #include "version.h" > - #include "ssherr.h" > -@@ -260,7 +264,7 @@ Buffer loginmsg; > - struct passwd *privsep_pw = NULL; > - > - /* Prototypes for various functions defined later in this file. */ > --void destroy_sensitive_data(void); > -+void destroy_sensitive_data(int); > - void demote_sensitive_data(void); > - > - #ifdef WITH_SSH1 > -@@ -281,6 +285,15 @@ close_listen_socks(void) > - num_listen_socks = -1; > - } > - > -+/* > -+ * Is this process listening for clients (i.e. not specific to any > specific > -+ * client connection?) > -+ */ > -+int listening_for_clients(void) > -+{ > -+ return num_listen_socks > 0; > -+} > -+ > - static void > - close_startup_pipes(void) > - { > -@@ -560,22 +573,45 @@ sshd_exchange_identification(int sock_in > - } > - } > - > --/* Destroy the host and server keys. They will no longer be needed. > */ > -+/* > -+ * Destroy the host and server keys. They will no longer be needed. > Careful, > -+ * this can be called from cleanup_exit() - i.e. from just about > anywhere. > -+ */ > - void > --destroy_sensitive_data(void) > -+destroy_sensitive_data(int privsep) > - { > - int i; > -+ pid_t pid; > -+ uid_t uid; > - > - if (sensitive_data.server_key) { > - key_free(sensitive_data.server_key); > - sensitive_data.server_key = NULL; > - } > -+ pid = getpid(); > -+ uid = getuid(); > - for (i = 0; i < options.num_host_key_files; i++) { > - if (sensitive_data.host_keys[i]) { > -+ char *fp; > -+ > -+ if (key_is_private(sensitive_data.host_keys[i])) > -+ fp = > sshkey_fingerprint(sensitive_data.host_keys[i], > options.fingerprint_hash, SSH_FP_HEX); > -+ else > -+ fp = NULL; > - key_free(sensitive_data.host_keys[i]); > - sensitive_data.host_keys[i] = NULL; > -+ if (fp != NULL) { > -+ if (privsep) > -+ PRIVSEP(audit_destroy_sensitive_data > (fp, > -+ pid, uid)); > -+ else > -+ audit_destroy_sensitive_data(fp, > -+ pid, uid); > -+ free(fp); > -+ } > - } > -- if (sensitive_data.host_certificates[i]) { > -+ if (sensitive_data.host_certificates > -+ && sensitive_data.host_certificates[i]) { > - key_free(sensitive_data.host_certificates[i]); > - sensitive_data.host_certificates[i] = NULL; > - } > -@@ -589,6 +625,8 @@ void > - demote_sensitive_data(void) > - { > - Key *tmp; > -+ pid_t pid; > -+ uid_t uid; > - int i; > - > - if (sensitive_data.server_key) { > -@@ -597,13 +635,25 @@ demote_sensitive_data(void) > - sensitive_data.server_key = tmp; > - } > - > -+ pid = getpid(); > -+ uid = getuid(); > - for (i = 0; i < options.num_host_key_files; i++) { > - if (sensitive_data.host_keys[i]) { > -+ char *fp; > -+ > -+ if (key_is_private(sensitive_data.host_keys[i])) > -+ fp = > sshkey_fingerprint(sensitive_data.host_keys[i], > options.fingerprint_hash, SSH_FP_HEX); > -+ else > -+ fp = NULL; > - tmp = key_demote(sensitive_data.host_keys[i]); > - key_free(sensitive_data.host_keys[i]); > - sensitive_data.host_keys[i] = tmp; > - if (tmp->type == KEY_RSA1) > - sensitive_data.ssh1_host_key = tmp; > -+ if (fp != NULL) { > -+ audit_destroy_sensitive_data(fp, pid, uid); > -+ free(fp); > -+ } > - } > - /* Certs do not need demotion */ > - } > -@@ -675,7 +725,7 @@ privsep_preauth(Authctxt *authctxt) > - > - if (use_privsep == PRIVSEP_ON) > - box = ssh_sandbox_init(pmonitor); > -- pid = fork(); > -+ pmonitor->m_pid = pid = fork(); > - if (pid == -1) { > - fatal("fork of unprivileged child failed"); > - } else if (pid != 0) { > -@@ -759,6 +811,12 @@ privsep_postauth(Authctxt *authctxt) > - else if (pmonitor->m_pid != 0) { > - verbose("User child is on pid %ld", (long)pmonitor->m_pid); > - buffer_clear(&loginmsg); > -+ if (*pmonitor->m_pkex != NULL ){ > -+ > newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]); > -+ newkeys_destroy((*pmonitor->m_pkex)- > >newkeys[MODE_IN]); > -+ audit_session_key_free_body(2, getpid(), getuid()); > -+ packet_destroy_all(0, 0); > -+ } > - monitor_child_postauth(pmonitor); > - > - /* NEVERREACHED */ > -@@ -1286,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so > - if (received_sigterm) { > - logit("Received signal %d; terminating.", > - (int) received_sigterm); > -+ destroy_sensitive_data(0); > - close_listen_socks(); > - if (options.pid_file != NULL) > - unlink(options.pid_file); > -@@ -2242,6 +2321,7 @@ main(int ac, char **av) > - */ > - if (use_privsep) { > - mm_send_keystate(pmonitor); > -+ packet_destroy_all(1, 1); > - exit(0); > - } > - > -@@ -2287,7 +2367,7 @@ main(int ac, char **av) > - privsep_postauth(authctxt); > - /* the monitor process [priv] will not return */ > - if (!compat20) > -- destroy_sensitive_data(); > -+ destroy_sensitive_data(0); > - } > - > - packet_set_timeout(options.client_alive_interval, > -@@ -2301,6 +2381,9 @@ main(int ac, char **av) > - do_authenticated(authctxt); > - > - /* The connection has been terminated. */ > -+ packet_destroy_all(1, 1); > -+ destroy_sensitive_data(1); > -+ > - packet_get_bytes(&ibytes, &obytes); > - verbose("Transferred: sent %llu, received %llu bytes", > - (unsigned long long)obytes, (unsigned long long)ibytes); > -@@ -2461,6 +2544,10 @@ do_ssh1_kex(void) > - if (cookie[i] != packet_get_char()) > - packet_disconnect("IP Spoofing check bytes do not > match."); > - > -+#ifdef SSH_AUDIT_EVENTS > -+ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); > -+#endif > -+ > - debug("Encryption type: %.200s", cipher_name(cipher_type)); > - > - /* Get the encrypted integer. */ > -@@ -2520,7 +2607,7 @@ do_ssh1_kex(void) > - } > - > - /* Destroy the private and public keys. No longer. */ > -- destroy_sensitive_data(); > -+ destroy_sensitive_data(1); > - > - if (use_privsep) > - mm_ssh1_session_id(session_id); > -@@ -2703,6 +2802,16 @@ do_ssh2_kex(void) > - void > - cleanup_exit(int i) > - { > -+ static int in_cleanup = 0; > -+ int is_privsep_child; > -+ > -+ /* cleanup_exit can be called at the very least from the privsep > -+ wrappers used for auditing. Make sure we don't recurse > -+ indefinitely. */ > -+ if (in_cleanup) > -+ _exit(i); > -+ in_cleanup = 1; > -+ > - if (the_authctxt) { > - do_cleanup(the_authctxt); > - if (use_privsep && privsep_is_preauth && > -@@ -2714,9 +2823,14 @@ cleanup_exit(int i) > - pmonitor->m_pid, strerror(errno)); > - } > - } > -+ is_privsep_child = use_privsep && pmonitor != NULL && > pmonitor->m_pid == 0; > -+ if (sensitive_data.host_keys != NULL) > -+ destroy_sensitive_data(is_privsep_child); > -+ packet_destroy_all(1, is_privsep_child); > - #ifdef SSH_AUDIT_EVENTS > - /* done after do_cleanup so it can cancel the PAM auth 'thread' > */ > -- if (!use_privsep || mm_is_monitor()) > -+ if ((the_authctxt == NULL || !the_authctxt->authenticated) && > -+ (!use_privsep || mm_is_monitor())) > - audit_event(SSH_CONNECTION_ABANDON); > - #endif > - _exit(i); > -diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c > ---- openssh-6.8p1/sshkey.c.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/sshkey.c 2015-03-20 13:41:15.111883751 +0100 > -@@ -317,6 +319,33 @@ sshkey_type_is_valid_ca(int type) > - } > - > - int > -+sshkey_is_private(const struct sshkey *k) > -+{ > -+ switch (k->type) { > -+ case KEY_RSA_CERT_V00: > -+ case KEY_RSA_CERT: > -+ case KEY_RSA1: > -+ case KEY_RSA: > -+ return k->rsa->d != NULL; > -+ case KEY_DSA_CERT_V00: > -+ case KEY_DSA_CERT: > -+ case KEY_DSA: > -+ return k->dsa->priv_key != NULL; > -+#ifdef OPENSSL_HAS_ECC > -+ case KEY_ECDSA_CERT: > -+ case KEY_ECDSA: > -+ return EC_KEY_get0_private_key(k->ecdsa) != NULL; > -+#endif > -+ case KEY_ED25519_CERT: > -+ case KEY_ED25519: > -+ return (k->ed25519_pk != NULL); > -+ default: > -+ /* fatal("key_is_private: bad key type %d", k->type); */ > -+ return 0; > -+ } > -+} > -+ > -+int > - sshkey_is_cert(const struct sshkey *k) > - { > - if (k == NULL) > -diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h > ---- openssh-6.8p1/sshkey.h.audit 2015-03-17 06:49:20.000000000 > +0100 > -+++ openssh-6.8p1/sshkey.h 2015-03-20 13:41:15.098883772 +0100 > -@@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey > - int sshkey_generate(int type, u_int bits, struct sshkey > **keyp); > - int sshkey_from_private(const struct sshkey *, struct > sshkey > **); > - int sshkey_type_from_name(const char *); > -+int sshkey_is_private(const struct sshkey *); > - int sshkey_is_cert(const struct sshkey *); > - int sshkey_type_is_cert(int); > - int sshkey_type_plain(int); > -diff -up openssh-6.8p1/sandbox-seccomp-filter.c.audit > openssh-6.8p1/sandbox-seccomp-filter.c > ---- openssh-6.8p1/sandbox-seccomp-filter.c.audit 2015-03-20 > 13:41:15.088883788 +0100 > -+++ openssh-6.8p1/sandbox-seccomp-filter.c 2015-03-20 > 13:41:15.097883774 +0100 > -@@ -110,6 +110,12 @@ static const struct sock_filter preauth_ > - #ifdef __NR_time /* not defined on EABI ARM */ > - SC_ALLOW(time), > - #endif > -+#ifdef SSH_AUDIT_EVENTS > -+ SC_ALLOW(getuid), > -+#ifdef __NR_getuid32 /* not defined on x86_64 */ > -+ SC_ALLOW(getuid32), > -+#endif > -+#endif > - SC_ALLOW(read), > - SC_ALLOW(write), > - SC_ALLOW(close), > diff --git a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > b/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > deleted file mode 100644 > index 4285bd9..0000000 > --- a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > +++ /dev/null > @@ -1,66 +0,0 @@ > -diff --git a/configure.ac b/configure.ac > -index 4065d0e..d59ad44 100644 > ---- a/configure.ac > -+++ b/configure.ac > -@@ -764,9 +764,12 @@ main() { if (NSVersionOfRunTimeLibrary("System") > > > > = (60 << 16)) > - i*86-*) > - seccomp_audit_arch=AUDIT_ARCH_I386 > - ;; > -- arm*-*) > -+ aarch64*-*) > -+ seccomp_audit_arch=AUDIT_ARCH_AARCH64 > -+ ;; > -+ arm*-*) > - seccomp_audit_arch=AUDIT_ARCH_ARM > -- ;; > -+ ;; > - esac > - if test "x$seccomp_audit_arch" != "x" ; then > - AC_MSG_RESULT(["$seccomp_audit_arch"]) > -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c > -index 095b04a..52f6810 100644 > ---- a/sandbox-seccomp-filter.c > -+++ b/sandbox-seccomp-filter.c > -@@ -90,8 +90,20 @@ static const struct sock_filter preauth_insns[] = { > - /* Load the syscall number for checking. */ > - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, > - offsetof(struct seccomp_data, nr)), > -- SC_DENY(open, EACCES), > -- SC_DENY(stat, EACCES), > -+ SC_DENY(openat, EACCES), > -+#ifdef __NR_open > -+ SC_DENY(open, EACCES), /* not on AArch64 */ > -+#endif > -+#ifdef __NR_fstat > -+ SC_DENY(fstat, EACCES), /* x86_64, Aarch64 */ > -+#endif > -+#if defined(__NR_stat64) && defined(__NR_fstat64) > -+ SC_DENY(stat64, EACCES), /* ix86, arm */ > -+ SC_DENY(fstat64, EACCES), > -+#endif > -+#ifdef __NR_newfstatat > -+ SC_DENY(newfstatat, EACCES), /* Aarch64 */ > -+#endif > - SC_ALLOW(getpid), > - SC_ALLOW(gettimeofday), > - SC_ALLOW(clock_gettime), > -@@ -111,12 +123,19 @@ static const struct sock_filter preauth_insns[] = > { > - SC_ALLOW(shutdown), > - #endif > - SC_ALLOW(brk), > -+#ifdef __NR_poll /* not on AArch64 */ > - SC_ALLOW(poll), > -+#endif > - #ifdef __NR__newselect > - SC_ALLOW(_newselect), > - #else > -+#ifdef __NR_select /* not on AArch64 */ > - SC_ALLOW(select), > - #endif > -+#ifdef __NR_pselect6 /* AArch64 */ > -+ SC_ALLOW(pselect6), > -+#endif > -+#endif > - SC_ALLOW(madvise), > - #ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ > - SC_ALLOW(mmap2),
On Wed, 2017-02-22 at 14:25 -0500, Kienker, Fred wrote: > Information on PCIDSS: > https://en.wikipedia.org/wiki/Payment_Card_Industry_Data_Security_Standard > > In the United States, many small businesses process payment card > payments via a web browser. They are periodically required to pass a > security audit for the bank or payment processing firm which checks the > security of their IT systems. This is to prevent malicious break ins and > thefts via an compromised firewall, server, computer, etc. Yes, they > check everything - including firewalls. Businesses whose networks do not > pass may have their payment processing privileges suspended. Big cash > flow problem if you accept credit or debit cards. > > Currently to pass a PCI audit, the openssh package on Linux must be at > least version 7.4. IPFire 2 is currently at 7.3 (I believe) so it will > not pass. Updating to the current 7.4 version will solve the problem. > The most of the problem appears to be over key length. 7.4 will not use > the shorter keys that 7.3 will. IPFire has been moving away from the > older shorter keys anyway, and this is just another step in that > process. Existing shorter keys might have to be regenerated. Well, we change the standard configuration of OpenSSH and do not allow old/bad keys, but for the certification it is probably easier to require a certain version. We can easily update and ship this with the next core update. > Currently the work-around is to disable exteral ssh access from IPFire > and *never* turn it on. This is a *real* pain when it comes to remote > support of IPFire. Agreed. > If this is not a priority, I completely understand. It just means moving > the affected systems to different firewall software. I don't think that there is any need to do that. Best, -Michael > > Thanks in advance! > Fred > > > From the openssh 7.4 release notes: > > Potentially-incompatible changes > ================================ > > This release includes a number of changes that may affect existing > configurations: > > * This release removes server support for the SSH v.1 protocol. > > * ssh(1): Remove 3des-cbc from the client's default proposal. 64-bit > block ciphers are not safe in 2016 and we don't want to wait until > attacks like SWEET32 are extended to SSH. As 3des-cbc was the > only mandatory cipher in the SSH RFCs, this may cause problems > connecting to older devices using the default configuration, > but it's highly likely that such devices already need explicit > configuration for key exchange and hostkey algorithms already > anyway. > > * sshd(8): Remove support for pre-authentication compression. > Doing compression early in the protocol probably seemed reasonable > in the 1990s, but today it's clearly a bad idea in terms of both > cryptography (cf. multiple compression oracle attacks in TLS) and > attack surface. Pre-auth compression support has been disabled by > default for >10 years. Support remains in the client. > > * ssh-agent will refuse to load PKCS#11 modules outside a whitelist > of trusted paths by default. The path whitelist may be specified > at run-time. > > * sshd(8): When a forced-command appears in both a certificate and > an authorized keys/principals command= restriction, sshd will now > refuse to accept the certificate unless they are identical. > The previous (documented) behaviour of having the certificate > forced-command override the other could be a bit confusing and > error-prone. > > * sshd(8): Remove the UseLogin configuration directive and support > for having /bin/login manage login sessions. > > > -----Original Message----- > From: Michael Tremer [mailto:michael.tremer@ipfire.org] > Sent: Wednesday, February 22, 2017 5:05 AM > To: Kienker, Fred <fkienker@at4b.com>; development > <development@lists.ipfire.org> > Subject: Re: [PATCH] openssh: Update to 7.3p1. > > Hi Fred, > > you are referring to IPFire 3 here, but I suppose that you are rather > using > IPFire 2 in production. > > This version of IPFire comes with OpenSSH 7.3p1: > > > http://git.ipfire.org/?p=ipfire-2.x.git;a=blob;f=lfs/openssh;h=371d0df4ac09c41 > 06f761886fa4e3f6107bd2265;hb=HEAD > > It would be helpful if you could give us some more context about your > environment, why PCI compliance is required and what other things > probably need > to be mended to comply or even comply better. > > Best, > -Michael > > On Tue, 2017-02-21 at 14:39 -0500, Kienker, Fred wrote: > > > > FYI: > > > > This is no longer considered "current" enough to pass a PCI > Compliance > > > > audit. Only a version > 7.4 will now pass due to CVE-2016-10009. > > Anyone using an IPFire firewall system who has to pass a PCI > Compliance > > > > audit will have to disable ssh access until this is updated to at > least > > > > 7.4. > > > > Fred Kienker > > > > -----Original Message----- > > From: Stefan Schantl [mailto:stefan.schantl@ipfire.org] > > Sent: Wednesday, November 30, 2016 7:02 AM > > To: development@lists.ipfire.org > > Subject: [PATCH] openssh: Update to 7.3p1. > > > > This is a major update to the latest stable version of OpenSSH. > > > > * Drop not longer required patches. > > * Drop SElinux support. > > > > Fixes #11218. > > > > Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org> > > --- > > openssh/openssh.nm | 8 +- > > openssh/patches/openssh-6.7p1-audit.patch | 2332 > > -------------------- > > .../patches/openssh-6.7p1-seccomp-aarch64.patch | 66 - > > 3 files changed, 3 insertions(+), 2403 deletions(-) > > delete mode 100644 openssh/patches/openssh-6.7p1-audit.patch > > delete mode 100644 > openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > > > > > > diff --git a/openssh/openssh.nm b/openssh/openssh.nm > > index 8489438..2e8de76 100644 > > --- a/openssh/openssh.nm > > +++ b/openssh/openssh.nm > > @@ -4,8 +4,8 @@ > > > ####################################################################### > > > > ######## > > > > name = openssh > > -version = 6.8p1 > > -release = 2 > > +version = 7.3p1 > > +release = 1 > > > > groups = Application/Internet > > url = http://www.openssh.com/portable.html > > @@ -28,10 +28,9 @@ build > > automake > > groff > > libedit-devel > > - libselinux-devel > > ncurses-devel > > openldap-devel > > - openssl-devel >= 1.0.0d-2 > > + openssl-devel >= 1.0.2 > > pam-devel > > util-linux > > zlib-devel > > @@ -51,7 +50,6 @@ build > > --with-ipaddr-display \ > > --with-pam \ > > --with-libedit \ > > - --with-selinux \ > > --with-audit=linux > > > > prepare_cmds > > diff --git a/openssh/patches/openssh-6.7p1-audit.patch > > b/openssh/patches/openssh-6.7p1-audit.patch > > deleted file mode 100644 > > index 213ca67..0000000 > > --- a/openssh/patches/openssh-6.7p1-audit.patch > > +++ /dev/null > > @@ -1,2332 +0,0 @@ > > -diff -up openssh-6.8p1/Makefile.in.audit openssh-6.8p1/Makefile.in > > ---- openssh-6.8p1/Makefile.in.audit 2015-03-20 > 13:41:15.065883826 > > > > +0100 > > -+++ openssh-6.8p1/Makefile.in 2015-03-20 13:41:15.100883769 +0100 > > -@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ > > - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o > blocks.o > > > > \ > > - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ > > - kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ > > -- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o > > -+ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o > > - > > - SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ > > - sshconnect.o sshconnect1.o sshconnect2.o mux.o \ > > -diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c > > ---- openssh-6.8p1/audit-bsm.c.audit 2015-03-17 > 06:49:20.000000000 > > > > +0100 > > -+++ openssh-6.8p1/audit-bsm.c 2015-03-20 13:41:15.092883782 +0100 > > -@@ -375,10 +375,23 @@ audit_connection_from(const char *host, > > - #endif > > - } > > - > > --void > > -+int > > - audit_run_command(const char *command) > > - { > > - /* not implemented */ > > -+ return 0; > > -+} > > -+ > > -+void > > -+audit_end_command(int handle, const char *command) > > -+{ > > -+ /* not implemented */ > > -+} > > -+ > > -+void > > -+audit_count_session_open(void) > > -+{ > > -+ /* not necessary */ > > - } > > - > > - void > > -@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li) > > - /* not implemented */ > > - } > > - > > -+int > > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > > *fp, int rv) > > -+{ > > -+ /* not implemented */ > > -+} > > -+ > > - void > > - audit_event(ssh_audit_event_t event) > > - { > > -@@ -454,4 +473,40 @@ audit_event(ssh_audit_event_t event) > > - debug("%s: unhandled event %d", __func__, event); > > - } > > - } > > -+ > > -+void > > -+audit_unsupported_body(int what) > > -+{ > > -+ /* not implemented */ > > -+} > > -+ > > -+void > > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > > *pfs, pid_t pid, uid_t uid) > > -+{ > > -+ /* not implemented */ > > -+} > > -+ > > -+void > > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > > -+{ > > -+ /* not implemented */ > > -+} > > -+ > > -+void > > -+audit_destroy_sensitive_data(const char *fp) > > -+{ > > -+ /* not implemented */ > > -+} > > -+ > > -+void > > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > > -+{ > > -+ /* not implemented */ > > -+} > > -+ > > -+void > > -+audit_generate_ephemeral_server_key(const char *fp) > > -+{ > > -+ /* not implemented */ > > -+} > > - #endif /* BSM */ > > -diff -up openssh-6.8p1/audit-linux.c.audit > openssh-6.8p1/audit-linux.c > > > > ---- openssh-6.8p1/audit-linux.c.audit 2015-03-17 > 06:49:20.000000000 > > > > +0100 > > -+++ openssh-6.8p1/audit-linux.c 2015-03-20 13:41:15.093883780 > +0100 > > > > -@@ -35,13 +35,25 @@ > > - > > - #include "log.h" > > - #include "audit.h" > > -+#include "key.h" > > -+#include "hostfile.h" > > -+#include "auth.h" > > -+#include "misc.h" /* servconf.h needs misc.h for struct > > ForwardOptions */ > > -+#include "servconf.h" > > - #include "canohost.h" > > -+#include "packet.h" > > -+#include "cipher.h" > > - > > -+#define AUDIT_LOG_SIZE 256 > > -+ > > -+extern ServerOptions options; > > -+extern Authctxt *the_authctxt; > > -+extern u_int utmp_len; > > - const char* audit_username(void); > > - > > --int > > --linux_audit_record_event(int uid, const char *username, > > -- const char *hostname, const char *ip, const char *ttyn, int > > success) > > -+static void > > -+linux_audit_user_logxxx(int uid, const char *username, > > -+ const char *hostname, const char *ip, const char *ttyn, int > > success, int event) > > - { > > - int audit_fd, rc, saved_errno; > > - > > -@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const char > > *username, > > - if (audit_fd < 0) { > > - if (errno == EINVAL || errno == EPROTONOSUPPORT || > > - errno == EAFNOSUPPORT) > > -- return 1; /* No audit support in kernel */ > > -+ return; /* No audit support in kernel */ > > - else > > -- return 0; /* Must prevent login */ > > -+ goto fatal_report; /* Must prevent login */ > > - } > > -- rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, > > -+ rc = audit_log_acct_message(audit_fd, event, > > - NULL, "login", username ? username : "(unknown)", > > - username == NULL ? uid : -1, hostname, ip, ttyn, success); > > - saved_errno = errno; > > -@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const char > > *username, > > - if ((rc == -EPERM) && (geteuid() != 0)) > > - rc = 0; > > - errno = saved_errno; > > -- return (rc >= 0); > > -+ if (rc < 0) { > > -+fatal_report: > > -+ fatal("linux_audit_write_entry failed: %s", > > strerror(errno)); > > -+ } > > - } > > - > > -+static void > > -+linux_audit_user_auth(int uid, const char *username, > > -+ const char *hostname, const char *ip, const char *ttyn, int > > success, int event) > > -+{ > > -+ int audit_fd, rc, saved_errno; > > -+ static const char *event_name[] = { > > -+ "maxtries exceeded", > > -+ "root denied", > > -+ "success", > > -+ "none", > > -+ "password", > > -+ "challenge-response", > > -+ "pubkey", > > -+ "hostbased", > > -+ "gssapi", > > -+ "invalid user", > > -+ "nologin", > > -+ "connection closed", > > -+ "connection abandoned", > > -+ "unknown" > > -+ }; > > -+ > > -+ audit_fd = audit_open(); > > -+ if (audit_fd < 0) { > > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > > -+ errno == EAFNOSUPPORT) > > -+ return; /* No audit support in kernel */ > > -+ else > > -+ goto fatal_report; /* Must prevent login */ > > -+ } > > -+ > > -+ if ((event < 0) || (event > SSH_AUDIT_UNKNOWN)) > > -+ event = SSH_AUDIT_UNKNOWN; > > -+ > > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, > > -+ NULL, event_name[event], username ? username : "(unknown)", > > -+ username == NULL ? uid : -1, hostname, ip, ttyn, success); > > -+ saved_errno = errno; > > -+ close(audit_fd); > > -+ /* > > -+ * Do not report error if the error is EPERM and sshd is run > as > > > > non > > -+ * root user. > > -+ */ > > -+ if ((rc == -EPERM) && (geteuid() != 0)) > > -+ rc = 0; > > -+ errno = saved_errno; > > -+ if (rc < 0) { > > -+fatal_report: > > -+ fatal("linux_audit_write_entry failed: %s", > > strerror(errno)); > > -+ } > > -+} > > -+ > > -+int > > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > > *fp, int rv) > > -+{ > > -+ char buf[AUDIT_LOG_SIZE]; > > -+ int audit_fd, rc, saved_errno; > > -+ > > -+ audit_fd = audit_open(); > > -+ if (audit_fd < 0) { > > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > > -+ errno == EAFNOSUPPORT) > > -+ return 1; /* No audit support in kernel */ > > -+ > else > > > > > > > > > > > > > > -+ return 0; /* Must prevent login */ > > -+ } > > -+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? > > "pubkey" : "hostbased", get_remote_port()); > > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, > > -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), > NULL, > > > > rv); > > -+ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) > > -+ goto out; > > -+ /* is the fingerprint_prefix() still needed? > > -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s > > rport=%d", > > -+ type, bits, sshkey_fingerprint_prefix(), fp, > > get_remote_port()); > > -+ */ > > -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s > rport=%d", > > > > -+ type, bits, fp, get_remote_port()); > > -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, > > -+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), > NULL, > > > > rv); > > -+out: > > -+ saved_errno = errno; > > -+ audit_close(audit_fd); > > -+ errno = saved_errno; > > -+ /* do not report error if the error is EPERM and sshd is run > as > > > > non root user */ > > -+ return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0)); > > -+} > > -+ > > -+static int user_login_count = 0; > > -+ > > - /* Below is the sshd audit API code */ > > - > > - void > > - audit_connection_from(const char *host, int port) > > - { > > --} > > - /* not implemented */ > > -+} > > - > > --void > > -+int > > - audit_run_command(const char *command) > > - { > > -- /* not implemented */ > > -+ if (!user_login_count++) > > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > > get_remote_name_or_ip(utmp_len, options.use_dns), > > -+ NULL, "ssh", 1, AUDIT_USER_LOGIN); > > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > > get_remote_name_or_ip(utmp_len, options.use_dns), > > -+ NULL, "ssh", 1, AUDIT_USER_START); > > -+ return 0; > > -+} > > -+ > > -+void > > -+audit_end_command(int handle, const char *command) > > -+{ > > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > > get_remote_name_or_ip(utmp_len, options.use_dns), > > -+ NULL, "ssh", 1, AUDIT_USER_END); > > -+ if (user_login_count && !--user_login_count) > > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, > > get_remote_name_or_ip(utmp_len, options.use_dns), > > -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); > > -+} > > -+ > > -+void > > -+audit_count_session_open(void) > > -+{ > > -+ user_login_count++; > > - } > > - > > - void > > - audit_session_open(struct logininfo *li) > > - { > > -- if (linux_audit_record_event(li->uid, NULL, li->hostname, > > -- NULL, li->line, 1) == 0) > > -- fatal("linux_audit_write_entry failed: %s", > > strerror(errno)); > > -+ if (!user_login_count++) > > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > > -+ NULL, li->line, 1, AUDIT_USER_LOGIN); > > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > > -+ NULL, li->line, 1, AUDIT_USER_START); > > - } > > - > > - void > > - audit_session_close(struct logininfo *li) > > - { > > -- /* not implemented */ > > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > > -+ NULL, li->line, 1, AUDIT_USER_END); > > -+ if (user_login_count && !--user_login_count) > > -+ linux_audit_user_logxxx(li->uid, NULL, li->hostname, > > -+ NULL, li->line, 1, AUDIT_USER_LOGOUT); > > - } > > - > > - void > > -@@ -101,21 +232,43 @@ audit_event(ssh_audit_event_t event) > > - { > > - switch(event) { > > - case SSH_AUTH_SUCCESS: > > -- case SSH_CONNECTION_CLOSE: > > -+ linux_audit_user_auth(-1, audit_username(), NULL, > > -+ get_remote_ipaddr(), "ssh", 1, event); > > -+ break; > > -+ > > - case SSH_NOLOGIN: > > -- case SSH_LOGIN_EXCEED_MAXTRIES: > > - case SSH_LOGIN_ROOT_DENIED: > > -+ linux_audit_user_auth(-1, audit_username(), NULL, > > -+ get_remote_ipaddr(), "ssh", 0, event); > > -+ linux_audit_user_logxxx(-1, audit_username(), NULL, > > -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); > > - break; > > - > > -+ case SSH_LOGIN_EXCEED_MAXTRIES: > > - case SSH_AUTH_FAIL_NONE: > > - case SSH_AUTH_FAIL_PASSWD: > > - case SSH_AUTH_FAIL_KBDINT: > > - case SSH_AUTH_FAIL_PUBKEY: > > - case SSH_AUTH_FAIL_HOSTBASED: > > - case SSH_AUTH_FAIL_GSSAPI: > > -+ linux_audit_user_auth(-1, audit_username(), NULL, > > -+ get_remote_ipaddr(), "ssh", 0, event); > > -+ break; > > -+ > > -+ case SSH_CONNECTION_CLOSE: > > -+ if (user_login_count) { > > -+ while (user_login_count--) > > -+ linux_audit_user_logxxx(the_authctxt->pw- > > > > > > pw_uid, > > NULL, get_remote_name_or_ip(utmp_len, options.use_dns), > > -+ NULL, "ssh", 1, AUDIT_USER_END); > > -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, > > NULL, > > get_remote_name_or_ip(utmp_len, options.use_dns), > > -+ NULL, "ssh", 1, AUDIT_USER_LOGOUT); > > -+ } > > -+ break; > > -+ > > -+ case SSH_CONNECTION_ABANDON: > > - case SSH_INVALID_USER: > > -- linux_audit_record_event(-1, audit_username(), NULL, > > -- get_remote_ipaddr(), "sshd", 0); > > -+ linux_audit_user_logxxx(-1, audit_username(), NULL, > > -+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); > > - break; > > - > > - default: > > -@@ -123,4 +276,135 @@ audit_event(ssh_audit_event_t event) > > - } > > - } > > - > > -+void > > -+audit_unsupported_body(int what) > > -+{ > > -+#ifdef AUDIT_CRYPTO_SESSION > > -+ char buf[AUDIT_LOG_SIZE]; > > -+ const static char *name[] = { "cipher", "mac", "comp" }; > > -+ char *s; > > -+ int audit_fd; > > -+ > > -+ snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? > > cipher=? ksize=? rport=%d laddr=%s lport=%d ", > > -+ name[what], get_remote_port(), (s = > > get_local_ipaddr(packet_get_connection_in())), > > -+ get_local_port()); > > -+ free(s); > > -+ audit_fd = audit_open(); > > -+ if (audit_fd < 0) > > -+ /* no problem, the next instruction will be fatal() */ > > -+ return; > > -+ audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, > > -+ buf, NULL, get_remote_ipaddr(), NULL, 0); > > -+ audit_close(audit_fd); > > -+#endif > > -+} > > -+ > > -+const static char *direction[] = { "from-server", "from-client", > > "both" }; > > -+ > > -+void > > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > > *pfs, pid_t pid, > > -+ uid_t uid) > > -+{ > > -+#ifdef AUDIT_CRYPTO_SESSION > > -+ char buf[AUDIT_LOG_SIZE]; > > -+ int audit_fd, audit_ok; > > -+ const Cipher *cipher = cipher_by_name(enc); > > -+ char *s; > > -+ > > -+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s > > ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", > > -+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, > > mac, > > pfs, > > -+ (intmax_t)pid, (intmax_t)uid, > > -+ get_remote_port(), (s = > > get_local_ipaddr(packet_get_connection_in())), get_local_port()); > > -+ free(s); > > -+ audit_fd = audit_open(); > > -+ if (audit_fd < 0) { > > -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || > > -+ errno == EAFNOSUPPORT) > > -+ return; /* No audit support in kernel */ > > -+ > else > > > > > > > > > > > > > > -+ fatal("cannot open audit"); /* Must prevent login > > */ > > -+ } > > -+ audit_ok = audit_log_user_message(audit_fd, > AUDIT_CRYPTO_SESSION, > > > > -+ buf, NULL, get_remote_ipaddr(), NULL, 1); > > -+ audit_close(audit_fd); > > -+ /* do not abort if the error is EPERM and sshd is run as non > root > > > > user */ > > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > > -+ fatal("cannot write into audit"); /* Must prevent login */ > > -+#endif > > -+} > > -+ > > -+void > > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > > -+{ > > -+ char buf[AUDIT_LOG_SIZE]; > > -+ int audit_fd, audit_ok; > > -+ char *s; > > -+ > > -+ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? > > direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", > > -+ direction[ctos], (intmax_t)pid, (intmax_t)uid, > > -+ get_remote_port(), > > -+ (s = get_local_ipaddr(packet_get_connection_in())), > > -+ get_local_port()); > > -+ free(s); > > -+ audit_fd = audit_open(); > > -+ if (audit_fd < 0) { > > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > > -+ errno != EAFNOSUPPORT) > > -+ error("cannot open audit"); > > -+ return; > > -+ } > > -+ audit_ok = audit_log_user_message(audit_fd, > > AUDIT_CRYPTO_KEY_USER, > > -+ buf, NULL, get_remote_ipaddr(), NULL, 1); > > -+ audit_close(audit_fd); > > -+ /* do not abort if the error is EPERM and sshd is run as non > root > > > > user */ > > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > > -+ error("cannot write into audit"); > > -+} > > -+ > > -+void > > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > > -+{ > > -+ char buf[AUDIT_LOG_SIZE]; > > -+ int audit_fd, audit_ok; > > -+ > > -+ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s > > direction=? spid=%jd suid=%jd ", > > -+ fp, (intmax_t)pid, (intmax_t)uid); > > -+ audit_fd = audit_open(); > > -+ if (audit_fd < 0) { > > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > > -+ errno != EAFNOSUPPORT) > > -+ error("cannot open audit"); > > -+ return; > > -+ } > > -+ audit_ok = audit_log_user_message(audit_fd, > > AUDIT_CRYPTO_KEY_USER, > > -+ buf, NULL, > > -+ listening_for_clients() ? get_remote_ipaddr() : > > NULL, > > -+ NULL, 1); > > -+ audit_close(audit_fd); > > -+ /* do not abort if the error is EPERM and sshd is run as non > root > > > > user */ > > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > > -+ error("cannot write into audit"); > > -+} > > -+ > > -+void > > -+audit_generate_ephemeral_server_key(const char *fp) > > -+{ > > -+ char buf[AUDIT_LOG_SIZE]; > > -+ int audit_fd, audit_ok; > > -+ > > -+ snprintf(buf, sizeof(buf), "op=create kind=server fp=%s > > direction=? ", fp); > > -+ audit_fd = audit_open(); > > -+ if (audit_fd < 0) { > > -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && > > -+ errno != EAFNOSUPPORT) > > -+ error("cannot open audit"); > > -+ return; > > -+ } > > -+ audit_ok = audit_log_user_message(audit_fd, > > AUDIT_CRYPTO_KEY_USER, > > -+ buf, NULL, 0, NULL, 1); > > -+ audit_close(audit_fd); > > -+ /* do not abort if the error is EPERM and sshd is run as non > root > > > > user */ > > -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) > > -+ error("cannot write into audit"); > > -+} > > - #endif /* USE_LINUX_AUDIT */ > > -diff -up openssh-6.8p1/audit.c.audit openssh-6.8p1/audit.c > > ---- openssh-6.8p1/audit.c.audit 2015-03-17 06:49:20.000000000 > +0100 > > > > -+++ openssh-6.8p1/audit.c 2015-03-20 13:41:15.093883780 +0100 > > -@@ -28,6 +28,7 @@ > > - > > - #include <stdarg.h> > > - #include <string.h> > > -+#include <unistd.h> > > - > > - #ifdef SSH_AUDIT_EVENTS > > - > > -@@ -36,6 +37,11 @@ > > - #include "key.h" > > - #include "hostfile.h" > > - #include "auth.h" > > -+#include "ssh-gss.h" > > -+#include "monitor_wrap.h" > > -+#include "xmalloc.h" > > -+#include "misc.h" > > -+#include "servconf.h" > > - > > - /* > > - * Care must be taken when using this since it WILL NOT be > initialized > > > > when > > -@@ -43,6 +49,7 @@ > > - * audit_event(CONNECTION_ABANDON) is called. Test for NULL before > > using. > > - */ > > - extern Authctxt *the_authctxt; > > -+extern ServerOptions options; > > - > > - /* Maybe add the audit class to struct Authmethod? */ > > - ssh_audit_event_t > > -@@ -71,13 +78,10 @@ audit_classify_auth(const char *method) > > - const char * > > - audit_username(void) > > - { > > -- static const char unknownuser[] = "(unknown user)"; > > -- static const char invaliduser[] = "(invalid user)"; > > -+ static const char unknownuser[] = "(unknown)"; > > - > > -- if (the_authctxt == NULL || the_authctxt->user == NULL) > > -+ if (the_authctxt == NULL || the_authctxt->user == NULL || > > !the_authctxt->valid) > > - return (unknownuser); > > -- if (!the_authctxt->valid) > > -- return (invaliduser); > > - return (the_authctxt->user); > > - } > > - > > -@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) > > - return(event_lookup[i].name); > > - } > > - > > -+void > > -+audit_key(int host_user, int *rv, const Key *key) > > -+{ > > -+ char *fp; > > -+ const char *crypto_name; > > -+ > > -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, > > SSH_FP_HEX); > > -+ if (key->type == KEY_RSA1) > > -+ crypto_name = "ssh-rsa1"; > > -+ else > > -+ crypto_name = key_ssh_name(key); > > -+ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, > > *rv) == 0) > > -+ *rv = 0; > > -+ free(fp); > > -+} > > -+ > > -+void > > -+audit_unsupported(int what) > > -+{ > > -+ PRIVSEP(audit_unsupported_body(what)); > > -+} > > -+ > > -+void > > -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) > > -+{ > > -+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), > > getuid())); > > -+} > > -+ > > -+void > > -+audit_session_key_free(int ctos) > > -+{ > > -+ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); > > -+} > > -+ > > - # ifndef CUSTOM_SSH_AUDIT_EVENTS > > - /* > > - * Null implementations of audit functions. > > -@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) > > - } > > - > > - /* > > -+ * Called when a child process has called, or will soon call, > > -+ * audit_session_open. > > -+ */ > > -+void > > -+audit_count_session_open(void) > > -+{ > > -+ debug("audit count session open euid %d user %s", geteuid(), > > -+ audit_username()); > > -+} > > -+ > > -+/* > > - * Called when a user session is started. Argument is the tty > > allocated to > > - * the session, or NULL if no tty was allocated. > > - * > > -@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li) > > - /* > > - * This will be called when a user runs a non-interactive command. > > Note that > > - * it may be called multiple times for a single connection since > SSH2 > > > > allows > > -- * multiple sessions within a single connection. > > -+ * multiple sessions within a single connection. Returns a > "handle" > > > > for > > -+ * audit_end_command. > > - */ > > --void > > -+int > > - audit_run_command(const char *command) > > - { > > - debug("audit run command euid %d user %s command '%.200s'", > > geteuid(), > > - audit_username(), command); > > -+ return 0; > > -+} > > -+ > > -+/* > > -+ * This will be called when the non-interactive command finishes. > > Note that > > -+ * it may be called multiple times for a single connection since > SSH2 > > > > allows > > -+ * multiple sessions within a single connection. "handle" should > come > > > > from > > -+ * the corresponding audit_run_command. > > -+ */ > > -+void > > -+audit_end_command(int handle, const char *command) > > -+{ > > -+ debug("audit end nopty exec euid %d user %s command > '%.200s'", > > > > geteuid(), > > -+ audit_username(), command); > > -+} > > -+ > > -+/* > > -+ * This will be called when user is successfully autherized by the > > RSA1/RSA/DSA key. > > -+ * > > -+ * Type is the key type, len is the key length(byte) and fp is the > > fingerprint of the key. > > -+ */ > > -+int > > -+audit_keyusage(int host_user, const char *type, unsigned bits, char > > *fp, int rv) > > -+{ > > -+ debug("audit %s key usage euid %d user %s key type %s key > length > > > > %d fingerprint %s%s, result %d", > > -+ host_user ? "pubkey" : "hostbased", geteuid(), > > audit_username(), type, bits, > > -+ sshkey_fingerprint_prefix(), fp, rv); > > -+} > > -+ > > -+/* > > -+ * This will be called when the protocol negotiation fails. > > -+ */ > > -+void > > -+audit_unsupported_body(int what) > > -+{ > > -+ debug("audit unsupported protocol euid %d type %d", geteuid(), > > what); > > -+} > > -+ > > -+/* > > -+ * This will be called on succesfull protocol negotiation. > > -+ */ > > -+void > > -+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char > > *pfs, pid_t pid, > > -+ uid_t uid) > > -+{ > > -+ debug("audit protocol negotiation euid %d direction %d cipher > %s > > > > mac %s compresion %s pfs %s from pid %ld uid %u", > > -+ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, > > (long)pid, > > -+ (unsigned)uid); > > -+} > > -+ > > -+/* > > -+ * This will be called on succesfull session key discard > > -+ */ > > -+void > > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > > -+{ > > -+ debug("audit session key discard euid %u direction %d from pid > > %ld uid %u", > > -+ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); > > -+} > > -+ > > -+/* > > -+ * This will be called on destroy private part of the server key > > -+ */ > > -+void > > -+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) > > -+{ > > -+ debug("audit destroy sensitive data euid %d fingerprint %s > from > > > > pid %ld uid %u", > > -+ geteuid(), fp, (long)pid, (unsigned)uid); > > -+} > > -+ > > -+/* > > -+ * This will be called on generation of the ephemeral server key > > -+ */ > > -+void > > -+audit_generate_ephemeral_server_key(const char *) > > -+{ > > -+ debug("audit create ephemeral server key euid %d fingerprint > %s", > > > > geteuid(), fp); > > - } > > - # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ > > - #endif /* SSH_AUDIT_EVENTS */ > > -diff -up openssh-6.8p1/audit.h.audit openssh-6.8p1/audit.h > > ---- openssh-6.8p1/audit.h.audit 2015-03-17 06:49:20.000000000 > +0100 > > > > -+++ openssh-6.8p1/audit.h 2015-03-20 13:41:15.093883780 +0100 > > -@@ -28,6 +28,7 @@ > > - # define _SSH_AUDIT_H > > - > > - #include "loginrec.h" > > -+#include "key.h" > > - > > - enum ssh_audit_event_type { > > - SSH_LOGIN_EXCEED_MAXTRIES, > > -@@ -47,11 +48,25 @@ enum ssh_audit_event_type { > > - }; > > - typedef enum ssh_audit_event_type ssh_audit_event_t; > > - > > -+int listening_for_clients(void); > > -+ > > - void audit_connection_from(const char *, int); > > - void audit_event(ssh_audit_event_t); > > -+void audit_count_session_open(void); > > - void audit_session_open(struct logininfo *); > > - void audit_session_close(struct logininfo *); > > --void audit_run_command(const char *); > > -+int audit_run_command(const char *); > > -+void audit_end_command(int, const char *); > > - ssh_audit_event_t audit_classify_auth(const char *); > > -+int audit_keyusage(int, const char *, unsigned, char *, int); > > -+void audit_key(int, int *, const Key *); > > -+void audit_unsupported(int); > > -+void audit_kex(int, char *, char *, char *, char *); > > -+void audit_unsupported_body(int); > > -+void audit_kex_body(int, char *, char *, char *, char *, pid_t, > > uid_t); > > -+void audit_session_key_free(int ctos); > > -+void audit_session_key_free_body(int ctos, pid_t, uid_t); > > -+void audit_destroy_sensitive_data(const char *, pid_t, uid_t); > > -+void audit_generate_ephemeral_server_key(const char *); > > - > > - #endif /* _SSH_AUDIT_H */ > > -diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c > > ---- openssh-6.8p1/auditstub.c.audit 2015-03-20 > 13:41:15.093883780 > > > > +0100 > > -+++ openssh-6.8p1/auditstub.c 2015-03-20 13:41:15.093883780 +0100 > > -@@ -0,0 +1,50 @@ > > -+/* $Id: auditstub.c,v 1.1 jfch Exp $ */ > > -+ > > -+/* > > -+ * Copyright 2010 Red Hat, Inc. All rights reserved. > > -+ * Use is subject to license terms. > > -+ * > > -+ * Redistribution and use in source and binary forms, with or > without > > > > -+ * modification, are permitted provided that the following > conditions > > > > -+ * are met: > > -+ * 1. Redistributions of source code must retain the above copyright > > -+ * notice, this list of conditions and the following disclaimer. > > -+ * 2. Redistributions in binary form must reproduce the above > > copyright > > -+ * notice, this list of conditions and the following disclaimer > in > > > > the > > -+ * documentation and/or other materials provided with the > > distribution. > > -+ * > > -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY > EXPRESS > > > > OR > > -+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > > WARRANTIES > > -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > > DISCLAIMED. > > -+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > > -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES > > (INCLUDING, BUT > > -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; > LOSS > > > > OF USE, > > -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND > ON > > > > ANY > > -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR > TORT > > > > -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF > THE > > > > USE OF > > -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > > -+ * > > -+ * Red Hat author: Jan F. Chadima <jchadima@redhat.com> > > -+ */ > > -+ > > -+#include <sys/types.h> > > -+ > > -+void > > -+audit_unsupported(int n) > > -+{ > > -+} > > -+ > > -+void > > -+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) > > -+{ > > -+} > > -+ > > -+void > > -+audit_session_key_free(int ctos) > > -+{ > > -+} > > -+ > > -+void > > -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > > -+{ > > -+} > > -diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c > > ---- openssh-6.8p1/auth-rsa.c.audit 2015-03-17 06:49:20.000000000 > > +0100 > > -+++ openssh-6.8p1/auth-rsa.c 2015-03-20 13:41:15.094883779 +0100 > > -@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNUM > > *challenge, u_char response[16]) > > - { > > - u_char buf[32], mdbuf[16]; > > - struct ssh_digest_ctx *md; > > -- int len; > > -+ int len, rv; > > -+#ifdef SSH_AUDIT_EVENTS > > -+ char *fp; > > -+#endif > > - > > - /* don't allow short keys */ > > - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { > > -@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNUM > > *challenge, u_char response[16]) > > - ssh_digest_free(md); > > - > > - /* Verify that the response is the original challenge. */ > > -- if (timingsafe_bcmp(response, mdbuf, 16) != 0) { > > -- /* Wrong answer. */ > > -- return (0); > > -+ rv = timingsafe_bcmp(response, mdbuf, 16) == 0; > > -+ > > -+#ifdef SSH_AUDIT_EVENTS > > -+ fp = sshkey_fingerprint(key, options.fingerprint_hash, > > SSH_FP_HEX); > > -+ if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, > rv) > > > > == 0) { > > -+ debug("unsuccessful audit"); > > -+ rv = 0; > > - } > > -- /* Correct answer. */ > > -- return (1); > > -+ free(fp); > > -+#endif > > -+ > > -+ return rv; > > - } > > - > > - /* > > -diff -up openssh-6.8p1/auth.c.audit openssh-6.8p1/auth.c > > ---- openssh-6.8p1/auth.c.audit 2015-03-17 06:49:20.000000000 > +0100 > > > > -+++ openssh-6.8p1/auth.c 2015-03-20 13:41:15.094883779 +0100 > > -@@ -644,9 +644,6 @@ getpwnamallow(const char *user) > > - record_failed_login(user, > > - get_canonical_hostname(options.use_dns), "ssh"); > > - #endif > > --#ifdef SSH_AUDIT_EVENTS > > -- audit_event(SSH_INVALID_USER); > > --#endif /* SSH_AUDIT_EVENTS */ > > - return (NULL); > > - } > > - if (!allowed_user(pw)) > > -diff -up openssh-6.8p1/auth.h.audit openssh-6.8p1/auth.h > > ---- openssh-6.8p1/auth.h.audit 2015-03-20 13:41:15.002883927 > +0100 > > > > -+++ openssh-6.8p1/auth.h 2015-03-20 13:41:15.094883779 +0100 > > -@@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt > > - > > - char *expand_authorized_keys(const char *, struct passwd *pw); > > - char *authorized_principals_file(struct passwd *); > > -+int user_key_verify(const Key *, const u_char *, u_int, const > > u_char *, u_int); > > - > > - FILE *auth_openkeyfile(const char *, struct passwd *, int); > > - FILE *auth_openprincipals(const char *, struct passwd *, int); > > -@@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc > > - int ssh1_session_key(BIGNUM *); > > - int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, > > - const u_char *, size_t, u_int); > > -+int hostbased_key_verify(const Key *, const u_char *, u_int, > > const u_char *, u_int); > > - > > - /* debug messages during authentication */ > > - void auth_debug_add(const char *fmt,...) > > __attribute__((format(printf, 1, 2))); > > -diff -up openssh-6.8p1/auth2-hostbased.c.audit > > openssh-6.8p1/auth2-hostbased.c > > ---- openssh-6.8p1/auth2-hostbased.c.audit 2015-03-20 > > 13:41:15.002883927 +0100 > > -+++ openssh-6.8p1/auth2-hostbased.c 2015-03-20 > 13:41:15.093883780 > > > > +0100 > > -@@ -147,7 +147,7 @@ userauth_hostbased(Authctxt *authctxt) > > - /* test for allowed key and correct signature */ > > - authenticated = 0; > > - if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, > > key)) && > > -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), > > -+ PRIVSEP(hostbased_key_verify(key, sig, slen, > buffer_ptr(&b), > > > > - buffer_len(&b))) == 1) > > - authenticated = 1; > > - > > -@@ -164,6 +164,18 @@ done: > > - return authenticated; > > - } > > - > > -+int > > -+hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, > > const u_char *data, u_int datalen) > > -+{ > > -+ int rv; > > -+ > > -+ rv = key_verify(key, sig, slen, data, datalen); > > -+#ifdef SSH_AUDIT_EVENTS > > -+ audit_key(0, &rv, key); > > -+#endif > > -+ return rv; > > -+} > > -+ > > - /* return 1 if given hostkey is allowed */ > > - int > > - hostbased_key_allowed(struct passwd *pw, const char *cuser, char > > *chost, > > -diff -up openssh-6.8p1/auth2-pubkey.c.audit > > openssh-6.8p1/auth2-pubkey.c > > ---- openssh-6.8p1/auth2-pubkey.c.audit 2015-03-20 > > 13:41:15.013883910 +0100 > > -+++ openssh-6.8p1/auth2-pubkey.c 2015-03-20 13:41:15.094883779 > > +0100 > > -@@ -172,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt) > > - /* test for correct signature */ > > - authenticated = 0; > > - if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && > > -- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), > > -+ PRIVSEP(user_key_verify(key, sig, slen, > buffer_ptr(&b), > > > > - buffer_len(&b))) == 1) { > > - authenticated = 1; > > - /* Record the successful key to prevent reuse */ > > -@@ -250,6 +250,18 @@ pubkey_auth_info(Authctxt *authctxt, con > > - free(extra); > > - } > > - > > -+int > > -+user_key_verify(const Key *key, const u_char *sig, u_int slen, > const > > > > u_char *data, u_int datalen) > > -+{ > > -+ int rv; > > -+ > > -+ rv = key_verify(key, sig, slen, data, datalen); > > -+#ifdef SSH_AUDIT_EVENTS > > -+ audit_key(1, &rv, key); > > -+#endif > > -+ return rv; > > -+} > > -+ > > - static int > > - match_principals_option(const char *principal_list, struct > sshkey_cert > > > > *cert) > > - { > > -diff -up openssh-6.8p1/auth2.c.audit openssh-6.8p1/auth2.c > > ---- openssh-6.8p1/auth2.c.audit 2015-03-20 13:41:15.044883860 > +0100 > > > > -+++ openssh-6.8p1/auth2.c 2015-03-20 13:41:15.093883780 +0100 > > -@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 > > - } else { > > - logit("input_userauth_request: invalid user %s", > > user); > > - authctxt->pw = fakepw(); > > --#ifdef SSH_AUDIT_EVENTS > > -- PRIVSEP(audit_event(SSH_INVALID_USER)); > > --#endif > > - } > > - #ifdef USE_PAM > > - if (options.use_pam) > > -diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c > > ---- openssh-6.8p1/cipher.c.audit 2015-03-17 06:49:20.000000000 > > +0100 > > -+++ openssh-6.8p1/cipher.c 2015-03-20 13:41:15.101883767 +0100 > > -@@ -57,26 +59,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v > > - extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); > > - #endif > > - > > --struct sshcipher { > > -- char *name; > > -- int number; /* for ssh1 only */ > > -- u_int block_size; > > -- u_int key_len; > > -- u_int iv_len; /* defaults to block_size */ > > -- u_int auth_len; > > -- u_int discard_len; > > -- u_int flags; > > --#define CFLAG_CBC (1<<0) > > --#define CFLAG_CHACHAPOLY (1<<1) > > --#define CFLAG_AESCTR (1<<2) > > --#define CFLAG_NONE (1<<3) > > --#ifdef WITH_OPENSSL > > -- const EVP_CIPHER *(*evptype)(void); > > --#else > > -- void *ignored; > > --#endif > > --}; > > -- > > - static const struct sshcipher ciphers[] = { > > - #ifdef WITH_SSH1 > > - { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, > > -diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h > > ---- openssh-6.8p1/cipher.h.audit 2015-03-17 06:49:20.000000000 > > +0100 > > -+++ openssh-6.8p1/cipher.h 2015-03-20 13:41:15.094883779 +0100 > > -@@ -62,7 +62,26 @@ > > - #define CIPHER_ENCRYPT 1 > > - #define CIPHER_DECRYPT 0 > > - > > --struct sshcipher; > > -+struct sshcipher { > > -+ char *name; > > -+ int number; /* for ssh1 only */ > > -+ u_int block_size; > > -+ u_int key_len; > > -+ u_int iv_len; /* defaults to block_size */ > > -+ u_int auth_len; > > -+ u_int discard_len; > > -+ u_int flags; > > -+#define CFLAG_CBC (1<<0) > > -+#define CFLAG_CHACHAPOLY (1<<1) > > -+#define CFLAG_AESCTR (1<<2) > > -+#define CFLAG_NONE (1<<3) > > -+#ifdef WITH_OPENSSL > > -+ const EVP_CIPHER *(*evptype)(void); > > -+#else > > -+ void *ignored; > > -+#endif > > -+}; > > -+ > > - struct sshcipher_ctx { > > - int plaintext; > > - int encrypt; > > -diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c > > ---- openssh-6.8p1/kex.c.audit 2015-03-20 13:41:15.046883856 +0100 > > -+++ openssh-6.8p1/kex.c 2015-03-20 13:41:15.101883767 +0100 > > -@@ -54,6 +55,7 @@ > > - #include "ssherr.h" > > - #include "sshbuf.h" > > - #include "digest.h" > > -+#include "audit.h" > > - > > - #ifdef GSSAPI > > - #include "ssh-gss.h" > > -@@ -484,8 +508,12 @@ choose_enc(struct sshenc *enc, char *cli > > - { > > - char *name = match_list(client, server, NULL); > > - > > -- if (name == NULL) > > -+ if (name == NULL) { > > -+#ifdef SSH_AUDIT_EVENTS > > -+ audit_unsupported(0); > > -+#endif > > - return SSH_ERR_NO_CIPHER_ALG_MATCH; > > -+ } > > - if ((enc->cipher = cipher_by_name(name)) == NULL) > > - return SSH_ERR_INTERNAL_ERROR; > > - enc->name = name; > > -@@ -503,8 +531,12 @@ choose_mac(struct ssh *ssh, struct sshma > > - { > > - char *name = match_list(client, server, NULL); > > - > > -- if (name == NULL) > > -+ if (name == NULL) { > > -+#ifdef SSH_AUDIT_EVENTS > > -+ audit_unsupported(1); > > -+#endif > > - return SSH_ERR_NO_MAC_ALG_MATCH; > > -+ } > > - if (mac_setup(mac, name) < 0) > > - return SSH_ERR_INTERNAL_ERROR; > > - /* truncate the key */ > > -@@ -521,8 +553,12 @@ choose_comp(struct sshcomp *comp, char * > > - { > > - char *name = match_list(client, server, NULL); > > - > > -- if (name == NULL) > > -+ if (name == NULL) { > > -+#ifdef SSH_AUDIT_EVENTS > > -+ audit_unsupported(2); > > -+#endif > > - return SSH_ERR_NO_COMPRESS_ALG_MATCH; > > -+ } > > - if (strcmp(name, "zlib@openssh.com") == 0) { > > - comp->type = COMP_DELAYED; > > - } else if (strcmp(name, "zlib") == 0) { > > -@@ -672,6 +708,10 @@ kex_choose_conf(struct ssh *ssh) > > - dh_need = MAX(dh_need, newkeys->enc.block_size); > > - dh_need = MAX(dh_need, newkeys->enc.iv_len); > > - dh_need = MAX(dh_need, newkeys->mac.key_len); > > -+ debug("kex: %s need=%d dh_need=%d", kex->name, need, > > dh_need); > > -+#ifdef SSH_AUDIT_EVENTS > > -+ audit_kex(mode, newkeys->enc.name, newkeys->mac.name, > > newkeys->comp.name, kex->name); > > -+#endif > > - } > > - /* XXX need runden? */ > > - kex->we_need = need; > > -@@ -847,3 +887,34 @@ dump_digest(char *msg, u_char *digest, i > > - sshbuf_dump_data(digest, len, stderr); > > - } > > - #endif > > -+ > > -+static void > > -+enc_destroy(struct sshenc *enc) > > -+{ > > -+ if (enc == NULL) > > -+ return; > > -+ > > -+ if (enc->key) { > > -+ memset(enc->key, 0, enc->key_len); > > -+ free(enc->key); > > -+ } > > -+ > > -+ if (enc->iv) { > > -+ memset(enc->iv, 0, enc->block_size); > > -+ free(enc->iv); > > -+ } > > -+ > > -+ memset(enc, 0, sizeof(*enc)); > > -+} > > -+ > > -+void > > -+newkeys_destroy(struct newkeys *newkeys) > > -+{ > > -+ if (newkeys == NULL) > > -+ return; > > -+ > > -+ enc_destroy(&newkeys->enc); > > -+ mac_destroy(&newkeys->mac); > > -+ memset(&newkeys->comp, 0, sizeof(newkeys->comp)); > > -+} > > -+ > > -diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h > > ---- openssh-6.8p1/kex.h.audit 2015-03-20 13:41:15.046883856 +0100 > > -+++ openssh-6.8p1/kex.h 2015-03-20 13:41:15.095883777 +0100 > > -@@ -199,6 +199,8 @@ int kexgss_client(struct ssh *); > > - int kexgss_server(struct ssh *); > > - #endif > > - > > -+void newkeys_destroy(struct newkeys *newkeys); > > -+ > > - int kex_dh_hash(const char *, const char *, > > - const u_char *, size_t, const u_char *, size_t, const u_char *, > > size_t, > > - const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, > size_t > > > > *); > > -diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h > > ---- openssh-6.8p1/key.h.audit 2015-03-17 06:49:20.000000000 +0100 > > -+++ openssh-6.8p1/key.h 2015-03-20 13:41:15.095883777 +0100 > > -@@ -50,6 +50,7 @@ typedef struct sshkey Key; > > - #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid > > - #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid > > - #define key_is_cert sshkey_is_cert > > -+#define key_is_private sshkey_is_private > > - #define key_type_plain sshkey_type_plain > > - #define key_cert_is_legacy sshkey_cert_is_legacy > > - #define key_curve_name_to_nid sshkey_curve_name_to_nid > > -diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c > > ---- openssh-6.8p1/mac.c.audit 2015-03-17 06:49:20.000000000 +0100 > > -+++ openssh-6.8p1/mac.c 2015-03-20 13:41:15.102883766 +0100 > > -@@ -226,6 +246,20 @@ mac_clear(struct sshmac *mac) > > - mac->umac_ctx = NULL; > > - } > > - > > -+void > > -+mac_destroy(struct sshmac *mac) > > -+{ > > -+ if (mac == NULL) > > -+ return; > > -+ > > -+ if (mac->key) { > > -+ memset(mac->key, 0, mac->key_len); > > -+ free(mac->key); > > -+ } > > -+ > > -+ memset(mac, 0, sizeof(*mac)); > > -+} > > -+ > > - /* XXX copied from ciphers_valid */ > > - #define MAC_SEP "," > > - int > > -diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h > > ---- openssh-6.8p1/mac.h.audit 2015-03-17 06:49:20.000000000 +0100 > > -+++ openssh-6.8p1/mac.h 2015-03-20 13:41:15.095883777 +0100 > > -@@ -47,5 +47,6 @@ int mac_init(struct sshmac *); > > - int mac_compute(struct sshmac *, u_int32_t, const u_char *, > int, > > > > - u_char *, size_t); > > - void mac_clear(struct sshmac *); > > -+void mac_destroy(struct sshmac *); > > - > > - #endif /* SSHMAC_H */ > > -diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c > > ---- openssh-6.8p1/monitor.c.audit 2015-03-20 13:41:15.072883814 > > +0100 > > -+++ openssh-6.8p1/monitor.c 2015-03-20 13:41:15.107883758 +0100 > > -@@ -102,6 +102,7 @@ > > - #include "ssh2.h" > > - #include "roaming.h" > > - #include "authfd.h" > > -+#include "audit.h" > > - #include "match.h" > > - #include "ssherr.h" > > - > > -@@ -117,6 +118,8 @@ extern Buffer auth_debug; > > - extern int auth_debug_init; > > - extern Buffer loginmsg; > > - > > -+extern void destroy_sensitive_data(int); > > -+ > > - /* State exported from the child */ > > - static struct sshbuf *child_state; > > - > > -@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe > > - #ifdef SSH_AUDIT_EVENTS > > - int mm_answer_audit_event(int, Buffer *); > > - int mm_answer_audit_command(int, Buffer *); > > -+int mm_answer_audit_end_command(int, Buffer *); > > -+int mm_answer_audit_unsupported_body(int, Buffer *); > > -+int mm_answer_audit_kex_body(int, Buffer *); > > -+int mm_answer_audit_session_key_free_body(int, Buffer *); > > -+int mm_answer_audit_server_key_free(int, Buffer *); > > - #endif > > - > > - static int monitor_read_log(struct monitor *); > > -@@ -226,6 +234,10 @@ struct mon_table mon_dispatch_proto20[] > > - #endif > > - #ifdef SSH_AUDIT_EVENTS > > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > > mm_answer_audit_unsupported_body}, > > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > > mm_answer_audit_session_key_free_body}, > > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > > mm_answer_audit_server_key_free}, > > - #endif > > - #ifdef BSD_AUTH > > - {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, > > -@@ -264,6 +276,11 @@ struct mon_table mon_dispatch_postauth20 > > - #ifdef SSH_AUDIT_EVENTS > > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > > - {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, > mm_answer_audit_command}, > > > > -+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, > > mm_answer_audit_end_command}, > > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > > mm_answer_audit_unsupported_body}, > > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > > mm_answer_audit_session_key_free_body}, > > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > > mm_answer_audit_server_key_free}, > > - #endif > > - {0, 0, NULL} > > - }; > > -@@ -296,6 +313,10 @@ struct mon_table mon_dispatch_proto15[] > > - #endif > > - #ifdef SSH_AUDIT_EVENTS > > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > > mm_answer_audit_unsupported_body}, > > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > > mm_answer_audit_session_key_free_body}, > > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > > mm_answer_audit_server_key_free}, > > - #endif > > - #endif /* WITH_SSH1 */ > > - {0, 0, NULL} > > -@@ -309,6 +330,11 @@ struct mon_table mon_dispatch_postauth15 > > - #ifdef SSH_AUDIT_EVENTS > > - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, > > - {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, > > mm_answer_audit_command}, > > -+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, > > mm_answer_audit_end_command}, > > -+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, > > mm_answer_audit_unsupported_body}, > > -+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > > -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, > > mm_answer_audit_session_key_free_body}, > > -+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, > > mm_answer_audit_server_key_free}, > > - #endif > > - #endif /* WITH_SSH1 */ > > - {0, 0, NULL} > > -@@ -1466,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m) > > - Key *key; > > - u_char *signature, *data, *blob; > > - u_int signaturelen, datalen, bloblen; > > -+ int type = 0; > > - int verified = 0; > > - int valid_data = 0; > > - > > -+ type = buffer_get_int(m); > > - blob = buffer_get_string(m, &bloblen); > > - signature = buffer_get_string(m, &signaturelen); > > - data = buffer_get_string(m, &datalen); > > -@@ -1476,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m) > > - if (hostbased_cuser == NULL || hostbased_chost == NULL || > > - !monitor_allowed_key(blob, bloblen)) > > - fatal("%s: bad key, not previously allowed", __func__); > > -+ if (type != key_blobtype) > > -+ fatal("%s: bad key type", __func__); > > - > > - key = key_from_blob(blob, bloblen); > > - if (key == NULL) > > -@@ -1496,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m) > > - if (!valid_data) > > - fatal("%s: bad signature data blob", __func__); > > - > > -- verified = key_verify(key, signature, signaturelen, data, > > datalen); > > -+ switch (key_blobtype) { > > -+ case MM_USERKEY: > > -+ verified = user_key_verify(key, signature, signaturelen, > > data, datalen); > > -+ break; > > -+ case MM_HOSTKEY: > > -+ verified = hostbased_key_verify(key, signature, > > signaturelen, data, datalen); > > -+ break; > > -+ default: > > -+ verified = 0; > > -+ break; > > -+ } > > - debug3("%s: key %p signature %s", > > - __func__, key, (verified == 1) ? "verified" : > "unverified"); > > > > - > > -@@ -1554,6 +1595,12 @@ mm_session_close(Session *s) > > - debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); > > - session_pty_cleanup2(s); > > - } > > -+#ifdef SSH_AUDIT_EVENTS > > -+ if (s->command != NULL) { > > -+ debug3("%s: command %d", __func__, s->command_handle); > > -+ session_end_command2(s); > > -+ } > > -+#endif > > - session_unused(s->self); > > - } > > - > > -@@ -1836,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req) > > - sshpam_cleanup(); > > - #endif > > - > > -+ destroy_sensitive_data(0); > > -+ > > - while (waitpid(pmonitor->m_pid, &status, 0) == -1) > > - if (errno != EINTR) > > - exit(1); > > -@@ -1878,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff > > - { > > - u_int len; > > - char *cmd; > > -+ Session *s; > > - > > - debug3("%s entering", __func__); > > - cmd = buffer_get_string(m, &len); > > -+ > > - /* sanity check command, if so how? */ > > -- audit_run_command(cmd); > > -+ s = session_new(); > > -+ if (s == NULL) > > -+ fatal("%s: error allocating a session", __func__); > > -+ s->command = cmd; > > -+ s->command_handle = audit_run_command(cmd); > > -+ > > -+ buffer_clear(m); > > -+ buffer_put_int(m, s->self); > > -+ > > -+ mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m); > > -+ > > -+ return (0); > > -+} > > -+ > > -+int > > -+mm_answer_audit_end_command(int socket, Buffer *m) > > -+{ > > -+ int handle; > > -+ u_int len; > > -+ char *cmd; > > -+ Session *s; > > -+ > > -+ debug3("%s entering", __func__); > > -+ handle = buffer_get_int(m); > > -+ cmd = buffer_get_string(m, &len); > > -+ > > -+ s = session_by_id(handle); > > -+ if (s == NULL || s->ttyfd != -1 || s->command == NULL || > > -+ strcmp(s->command, cmd) != 0) > > -+ fatal("%s: invalid handle", __func__); > > -+ mm_session_close(s); > > - free(cmd); > > - return (0); > > - } > > -@@ -1936,6 +2017,7 @@ > > - void > > - mm_get_keystate(struct monitor *pmonitor) > > - { > > -+ Buffer m; > > - debug3("%s: Waiting for new keys", __func__); > > - > > - if ((child_state = sshbuf_new()) == NULL) > > -@@ -1946,6 +2027,21 @@ mm_get_keystate(struct monitor *pmonitor > > - mm_request_receive_expect(pmonitor->m_sendfd, > > MONITOR_REQ_KEYEXPORT, > > - child_state); > > - debug3("%s: GOT new keys", __func__); > > -+ > > -+#ifdef SSH_AUDIT_EVENTS > > -+ if (compat20) { > > -+ buffer_init(&m); > > -+ mm_request_receive_expect(pmonitor->m_sendfd, > > -+ MONITOR_REQ_AUDIT_SESSION_KEY_FR > > EE > > , &m); > > -+ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, > > &m); > > -+ buffer_free(&m); > > -+ } > > -+#endif > > -+ > > -+ /* Drain any buffered messages from the child */ > > -+ while (pmonitor->m_log_recvfd >= 0 && > monitor_read_log(pmonitor) > > > > == 0) > > -+ ; > > -+ > > - } > > - > > - > > -@@ -2212,3 +2308,87 @@ mm_answer_gss_updatecreds(int socket, Bu > > - > > - #endif /* GSSAPI */ > > - > > -+#ifdef SSH_AUDIT_EVENTS > > -+int > > -+mm_answer_audit_unsupported_body(int sock, Buffer *m) > > -+{ > > -+ int what; > > -+ > > -+ what = buffer_get_int(m); > > -+ > > -+ audit_unsupported_body(what); > > -+ > > -+ buffer_clear(m); > > -+ > > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m); > > -+ return 0; > > -+} > > -+ > > -+int > > -+mm_answer_audit_kex_body(int sock, Buffer *m) > > -+{ > > -+ int ctos, len; > > -+ char *cipher, *mac, *compress, *pfs; > > -+ pid_t pid; > > -+ uid_t uid; > > -+ > > -+ ctos = buffer_get_int(m); > > -+ cipher = buffer_get_string(m, &len); > > -+ mac = buffer_get_string(m, &len); > > -+ compress = buffer_get_string(m, &len); > > -+ pfs = buffer_get_string(m, &len); > > -+ pid = buffer_get_int64(m); > > -+ uid = buffer_get_int64(m); > > -+ > > -+ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); > > -+ > > -+ free(cipher); > > -+ free(mac); > > -+ free(compress); > > -+ free(pfs); > > -+ buffer_clear(m); > > -+ > > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); > > -+ return 0; > > -+} > > -+ > > -+int > > -+mm_answer_audit_session_key_free_body(int sock, Buffer *m) > > -+{ > > -+ int ctos; > > -+ pid_t pid; > > -+ uid_t uid; > > -+ > > -+ ctos = buffer_get_int(m); > > -+ pid = buffer_get_int64(m); > > -+ uid = buffer_get_int64(m); > > -+ > > -+ audit_session_key_free_body(ctos, pid, uid); > > -+ > > -+ buffer_clear(m); > > -+ > > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m); > > -+ return 0; > > -+} > > -+ > > -+int > > -+mm_answer_audit_server_key_free(int sock, Buffer *m) > > -+{ > > -+ int len; > > -+ char *fp; > > -+ pid_t pid; > > -+ uid_t uid; > > -+ > > -+ fp = buffer_get_string(m, &len); > > -+ pid = buffer_get_int64(m); > > -+ uid = buffer_get_int64(m); > > -+ > > -+ audit_destroy_sensitive_data(fp, pid, uid); > > -+ > > -+ free(fp); > > -+ buffer_clear(m); > > -+ > > -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m); > > -+ return 0; > > -+} > > -+#endif /* SSH_AUDIT_EVENTS */ > > -diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h > > ---- openssh-6.8p1/monitor.h.audit 2015-03-20 13:41:15.072883814 > > +0100 > > -+++ openssh-6.8p1/monitor.h 2015-03-20 13:41:15.096883775 +0100 > > -@@ -69,7 +69,13 @@ enum monitor_reqtype { > > - MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, > > - MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, > > - MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, > > -- MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, > > -+ MONITOR_REQ_AUDIT_EVENT = 112, > > -+ MONITOR_REQ_AUDIT_COMMAND = 114, MONITOR_ANS_AUDIT_COMMAND = > 115, > > > > -+ MONITOR_REQ_AUDIT_END_COMMAND = 116, > > -+ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, > > MONITOR_ANS_AUDIT_UNSUPPORTED = 119, > > -+ MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, > > -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, > > MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, > > -+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, > > MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125 > > - > > - }; > > - > > -diff -up openssh-6.8p1/monitor_wrap.c.audit > > openssh-6.8p1/monitor_wrap.c > > ---- openssh-6.8p1/monitor_wrap.c.audit 2015-03-20 > > 13:41:15.047883855 +0100 > > -+++ openssh-6.8p1/monitor_wrap.c 2015-03-20 13:41:15.108883756 > > +0100 > > -@@ -461,7 +461,7 @@ mm_key_allowed(enum mm_keytype type, cha > > - */ > > - > > - int > > --mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, > u_int > > > > datalen) > > -+mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int > > siglen, u_char *data, u_int datalen) > > - { > > - Buffer m; > > - u_char *blob; > > -@@ -475,6 +475,7 @@ mm_key_verify(Key *key, u_char *sig, u_i > > - return (0); > > - > > - buffer_init(&m); > > -+ buffer_put_int(&m, type); > > - buffer_put_string(&m, blob, len); > > - buffer_put_string(&m, sig, siglen); > > - buffer_put_string(&m, data, datalen); > > -@@ -492,6 +493,18 @@ mm_key_verify(Key *key, u_char *sig, u_i > > - return (verified); > > - } > > - > > -+int > > -+mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char > > *data, u_int datalen) > > -+{ > > -+ return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, > > datalen); > > -+} > > -+ > > -+int > > -+mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char > *data, > > > > u_int datalen) > > -+{ > > -+ return mm_key_verify(MM_USERKEY, key, sig, siglen, data, > > datalen); > > -+} > > -+ > > - void > > - mm_send_keystate(struct monitor *monitor) > > - { > > -@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event) > > - buffer_free(&m); > > - } > > - > > --void > > -+int > > - mm_audit_run_command(const char *command) > > - { > > - Buffer m; > > -+ int handle; > > - > > - debug3("%s entering command %s", __func__, command); > > - > > -@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command > > - buffer_put_cstring(&m, command); > > - > > - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, > > &m); > > -+ mm_request_receive_expect(pmonitor->m_recvfd, > > MONITOR_ANS_AUDIT_COMMAND, &m); > > -+ > > -+ handle = buffer_get_int(&m); > > -+ buffer_free(&m); > > -+ > > -+ return (handle); > > -+} > > -+ > > -+void > > -+mm_audit_end_command(int handle, const char *command) > > -+{ > > -+ Buffer m; > > -+ > > -+ debug3("%s entering command %s", __func__, command); > > -+ > > -+ buffer_init(&m); > > -+ buffer_put_int(&m, handle); > > -+ buffer_put_cstring(&m, command); > > -+ > > -+ mm_request_send(pmonitor->m_recvfd, > > MONITOR_REQ_AUDIT_END_COMMAND, &m); > > - buffer_free(&m); > > - } > > - #endif /* SSH_AUDIT_EVENTS */ > > -@@ -1151,3 +1185,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc > > - > > - #endif /* GSSAPI */ > > - > > -+#ifdef SSH_AUDIT_EVENTS > > -+void > > -+mm_audit_unsupported_body(int what) > > -+{ > > -+ Buffer m; > > -+ > > -+ buffer_init(&m); > > -+ buffer_put_int(&m, what); > > -+ > > -+ mm_request_send(pmonitor->m_recvfd, > > MONITOR_REQ_AUDIT_UNSUPPORTED, &m); > > -+ mm_request_receive_expect(pmonitor->m_recvfd, > > MONITOR_ANS_AUDIT_UNSUPPORTED, > > -+ &m); > > -+ > > -+ buffer_free(&m); > > -+} > > -+ > > -+void > > -+mm_audit_kex_body(int ctos, char *cipher, char *mac, char > *compress, > > > > char *fps, pid_t pid, > > -+ uid_t uid) > > -+{ > > -+ Buffer m; > > -+ > > -+ buffer_init(&m); > > -+ buffer_put_int(&m, ctos); > > -+ buffer_put_cstring(&m, cipher); > > -+ buffer_put_cstring(&m, (mac ? mac : "")); > > -+ buffer_put_cstring(&m, compress); > > -+ buffer_put_cstring(&m, fps); > > -+ buffer_put_int64(&m, pid); > > -+ buffer_put_int64(&m, uid); > > -+ > > -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m); > > -+ mm_request_receive_expect(pmonitor->m_recvfd, > > MONITOR_ANS_AUDIT_KEX, > > -+ &m); > > -+ > > -+ buffer_free(&m); > > -+} > > -+ > > -+void > > -+mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) > > -+{ > > -+ Buffer m; > > -+ > > -+ buffer_init(&m); > > -+ buffer_put_int(&m, ctos); > > -+ buffer_put_int64(&m, pid); > > -+ buffer_put_int64(&m, uid); > > -+ mm_request_send(pmonitor->m_recvfd, > > MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); > > -+ mm_request_receive_expect(pmonitor->m_recvfd, > > MONITOR_ANS_AUDIT_SESSION_KEY_FREE, > > -+ &m); > > -+ buffer_free(&m); > > -+} > > -+ > > -+void > > -+mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t > uid) > > > > -+{ > > -+ Buffer m; > > -+ > > -+ buffer_init(&m); > > -+ buffer_put_cstring(&m, fp); > > -+ buffer_put_int64(&m, pid); > > -+ buffer_put_int64(&m, uid); > > -+ > > -+ mm_request_send(pmonitor->m_recvfd, > > MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); > > -+ mm_request_receive_expect(pmonitor->m_recvfd, > > MONITOR_ANS_AUDIT_SERVER_KEY_FREE, > > -+ &m); > > -+ buffer_free(&m); > > -+} > > -+#endif /* SSH_AUDIT_EVENTS */ > > -diff -up openssh-6.8p1/monitor_wrap.h.audit > > openssh-6.8p1/monitor_wrap.h > > ---- openssh-6.8p1/monitor_wrap.h.audit 2015-03-20 > > 13:41:15.048883853 +0100 > > -+++ openssh-6.8p1/monitor_wrap.h 2015-03-20 13:41:15.096883775 > > +0100 > > -@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char > > - int mm_user_key_allowed(struct passwd *, Key *); > > - int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key > *); > > > > - int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, > > Key *); > > --int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); > > -+int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, > u_int); > > > > -+int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int); > > - int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); > > - int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); > > - BIGNUM *mm_auth_rsa_generate_challenge(Key *); > > -@@ -79,7 +80,12 @@ void mm_sshpam_free_ctx(void *); > > - #ifdef SSH_AUDIT_EVENTS > > - #include "audit.h" > > - void mm_audit_event(ssh_audit_event_t); > > --void mm_audit_run_command(const char *); > > -+int mm_audit_run_command(const char *); > > -+void mm_audit_end_command(int, const char *); > > -+void mm_audit_unsupported_body(int); > > -+void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, > > uid_t); > > -+void mm_audit_session_key_free_body(int, pid_t, uid_t); > > -+void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); > > - #endif > > - > > - struct Session; > > -diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c > > ---- openssh-6.8p1/packet.c.audit 2015-03-20 13:41:14.990883947 > > +0100 > > -+++ openssh-6.8p1/packet.c 2015-03-20 13:41:15.097883774 +0100 > > -@@ -67,6 +67,7 @@ > > - #include "key.h" /* typedefs XXX */ > > - > > - #include "xmalloc.h" > > -+#include "audit.h" > > - #include "crc32.h" > > - #include "deattack.h" > > - #include "compat.h" > > -@@ -448,6 +449,13 @@ ssh_packet_get_connection_out(struct ssh > > - return ssh->state->connection_out; > > - } > > - > > -+static int > > -+packet_state_has_keys (const struct session_state *state) > > -+{ > > -+ return state != NULL && > > -+ (state->newkeys[MODE_IN] != NULL || state- > > > > > > newkeys[MODE_OUT] > > != NULL); > > -+} > > -+ > > - /* > > - * Returns the IP-address of the remote host as a string. The > > returned > > - * string must not be freed. > > -@@ -478,13 +486,6 @@ ssh_packet_close(struct ssh *ssh) > > - if (!state->initialized) > > - return; > > - state->initialized = 0; > > -- if (state->connection_in == state->connection_out) { > > -- shutdown(state->connection_out, SHUT_RDWR); > > -- close(state->connection_out); > > -- } else { > > -- close(state->connection_in); > > -- close(state->connection_out); > > -- } > > - sshbuf_free(state->input); > > - sshbuf_free(state->output); > > - sshbuf_free(state->outgoing_packet); > > -@@ -516,14 +517,24 @@ ssh_packet_close(struct ssh *ssh) > > - inflateEnd(stream); > > - } > > - } > > -- if ((r = cipher_cleanup(&state->send_context)) != 0) > > -- error("%s: cipher_cleanup failed: %s", __func__, > > ssh_err(r)); > > -- if ((r = cipher_cleanup(&state->receive_context)) != 0) > > -- error("%s: cipher_cleanup failed: %s", __func__, > > ssh_err(r)); > > -+ if (packet_state_has_keys(state)) { > > -+ if ((r = cipher_cleanup(&state->send_context)) != 0) > > -+ error("%s: cipher_cleanup failed: %s", __func__, > > ssh_err(r)); > > -+ if ((r = cipher_cleanup(&state->receive_context)) != 0) > > -+ error("%s: cipher_cleanup failed: %s", __func__, > > ssh_err(r)); > > -+ audit_session_key_free(2); > > -+ } > > - if (ssh->remote_ipaddr) { > > - free(ssh->remote_ipaddr); > > - ssh->remote_ipaddr = NULL; > > - } > > -+ if (state->connection_in == state->connection_out) { > > -+ shutdown(state->connection_out, SHUT_RDWR); > > -+ close(state->connection_out); > > -+ } else { > > -+ close(state->connection_in); > > -+ close(state->connection_out); > > -+ } > > - free(ssh->state); > > - ssh->state = NULL; > > - } > > -@@ -941,6 +952,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod > > - } > > - if (state->newkeys[mode] != NULL) { > > - debug("set_newkeys: rekeying"); > > -+ audit_session_key_free(mode); > > - if ((r = cipher_cleanup(cc)) != 0) > > - return r; > > - enc = &state->newkeys[mode]->enc; > > -@@ -2263,6 +2275,75 @@ ssh_packet_get_output(struct ssh *ssh) > > - return (void *)ssh->state->output; > > - } > > - > > -+static void > > -+newkeys_destroy_and_free(struct newkeys *newkeys) > > -+{ > > -+ if (newkeys == NULL) > > -+ return; > > -+ > > -+ free(newkeys->enc.name); > > -+ > > -+ if (newkeys->mac.enabled) { > > -+ mac_clear(&newkeys->mac); > > -+ free(newkeys->mac.name); > > -+ } > > -+ > > -+ free(newkeys->comp.name); > > -+ > > -+ newkeys_destroy(newkeys); > > -+ free(newkeys); > > -+} > > -+ > > -+static void > > -+packet_destroy_state(struct session_state *state) > > -+{ > > -+ if (state == NULL) > > -+ return; > > -+ > > -+ cipher_cleanup(&state->receive_context); > > -+ cipher_cleanup(&state->send_context); > > -+ > > -+ buffer_free(state->input); > > -+ state->input = NULL; > > -+ buffer_free(state->output); > > -+ state->output = NULL; > > -+ buffer_free(state->outgoing_packet); > > -+ state->outgoing_packet = NULL; > > -+ buffer_free(state->incoming_packet); > > -+ state->incoming_packet = NULL; > > -+ if( state->compression_buffer ) { > > -+ buffer_free(state->compression_buffer); > > -+ state->compression_buffer = NULL; > > -+ } > > -+ newkeys_destroy_and_free(state->newkeys[MODE_IN]); > > -+ state->newkeys[MODE_IN] = NULL; > > -+ newkeys_destroy_and_free(state->newkeys[MODE_OUT]); > > -+ state->newkeys[MODE_OUT] = NULL; > > -+ mac_destroy(state->packet_discard_mac); > > -+// TAILQ_HEAD(, packet) outgoing; > > -+// memset(state, 0, sizeof(state)); > > -+} > > -+ > > -+void > > -+packet_destroy_all(int audit_it, int privsep) > > -+{ > > -+ if (audit_it) > > -+ audit_it = (active_state != NULL && > > packet_state_has_keys(active_state->state)) > > -+ || (backup_state != NULL && > > packet_state_has_keys(backup_state->state)); > > -+ if (active_state != NULL) > > -+ packet_destroy_state(active_state->state); > > -+ if (backup_state != NULL) > > -+ packet_destroy_state(backup_state->state); > > -+ if (audit_it) { > > -+#ifdef SSH_AUDIT_EVENTS > > -+ if (privsep) > > -+ audit_session_key_free(2); > > -+ else > > -+ audit_session_key_free_body(2, getpid(), > > getuid()); > > -+#endif > > -+ } > > -+} > > -+ > > - /* XXX TODO update roaming to new API (does not work anyway) */ > > - /* > > - * Save the state for the real connection, and use a separate state > > when > > -@@ -2272,18 +2373,12 @@ void > > - ssh_packet_backup_state(struct ssh *ssh, > > - struct ssh *backup_state) > > - { > > -- struct ssh *tmp; > > -- > > - close(ssh->state->connection_in); > > - ssh->state->connection_in = -1; > > - close(ssh->state->connection_out); > > - ssh->state->connection_out = -1; > > -- if (backup_state) > > -- tmp = backup_state; > > -- else > > -- tmp = ssh_alloc_session_state(); > > - backup_state = ssh; > > -- ssh = tmp; > > -+ ssh = ssh_alloc_session_state(); > > - } > > - > > - /* XXX FIXME FIXME FIXME */ > > -@@ -2302,9 +2397,7 @@ ssh_packet_restore_state(struct ssh *ssh > > - backup_state = ssh; > > - ssh = tmp; > > - ssh->state->connection_in = backup_state->state->connection_in; > > -- backup_state->state->connection_in = -1; > > - ssh->state->connection_out = > backup_state->state->connection_out; > > > > -- backup_state->state->connection_out = -1; > > - len = sshbuf_len(backup_state->state->input); > > - if (len > 0) { > > - if ((r = sshbuf_putb(ssh->state->input, > > -@@ -2313,6 +2406,11 @@ ssh_packet_restore_state(struct ssh *ssh > > - sshbuf_reset(backup_state->state->input); > > - add_recv_bytes(len); > > - } > > -+ backup_state->state->connection_in = -1; > > -+ backup_state->state->connection_out = -1; > > -+ packet_destroy_state(backup_state->state); > > -+ free(backup_state); > > -+ backup_state = NULL; > > - } > > - > > - /* Reset after_authentication and reset compression in post-auth > > privsep */ > > -diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h > > ---- openssh-6.8p1/packet.h.audit 2015-03-17 06:49:20.000000000 > > +0100 > > -+++ openssh-6.8p1/packet.h 2015-03-20 13:41:15.097883774 +0100 > > -@@ -189,7 +189,7 @@ int sshpkt_get_end(struct ssh *ssh); > > - const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); > > - > > - /* OLD API */ > > --extern struct ssh *active_state; > > -+extern struct ssh *active_state, *backup_state; > > - #include "opacket.h" > > - > > - #if !defined(WITH_OPENSSL) > > -@@ -203,4 +203,5 @@ extern struct ssh *active_state; > > - # undef EC_POINT > > - #endif > > - > > -+void packet_destroy_all(int, int); > > - #endif /* PACKET_H */ > > -diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c > > ---- openssh-6.8p1/session.c.audit 2015-03-20 13:41:15.073883813 > > +0100 > > -+++ openssh-6.8p1/session.c 2015-03-20 13:41:15.097883774 +0100 > > -@@ -139,7 +139,7 @@ extern int log_stderr; > > - extern int debug_flag; > > - extern u_int utmp_len; > > - extern int startup_pipe; > > --extern void destroy_sensitive_data(void); > > -+extern void destroy_sensitive_data(int); > > - extern Buffer loginmsg; > > - > > - /* original command from peer. */ > > -@@ -731,6 +731,14 @@ do_exec_pty(Session *s, const char *comm > > - /* Parent. Close the slave side of the pseudo tty. */ > > - close(ttyfd); > > - > > -+#ifndef HAVE_OSF_SIA > > -+ /* do_login in the child did not affect state in this process, > > -+ compensate. From an architectural standpoint, this is > > extremely > > -+ ugly. */ > > -+ if (!(options.use_login && command == NULL)) > > -+ audit_count_session_open(); > > -+#endif > > -+ > > - /* Enter interactive session. */ > > - s->ptymaster = ptymaster; > > - packet_set_interactive(1, > > -@@ -853,15 +861,19 @@ do_exec(Session *s, const char *command) > > - get_remote_port()); > > - > > - #ifdef SSH_AUDIT_EVENTS > > -+ if (s->command != NULL || s->command_handle != -1) > > -+ fatal("do_exec: command already set"); > > - if (command != NULL) > > -- PRIVSEP(audit_run_command(command)); > > -+ s->command = xstrdup(command); > > - else if (s->ttyfd == -1) { > > - char *shell = s->pw->pw_shell; > > - > > - if (shell[0] == '\0') /* empty shell means /bin/sh > > */ > > - shell =_PATH_BSHELL; > > -- PRIVSEP(audit_run_command(shell)); > > -+ s->command = xstrdup(shell); > > - } > > -+ if (s->command != NULL && s->ptyfd == -1) > > -+ s->command_handle = > PRIVSEP(audit_run_command(s->command)); > > > > - #endif > > - if (s->ttyfd != -1) > > - ret = do_exec_pty(s, command); > > -@@ -1704,7 +1716,10 @@ do_child(Session *s, const char *command > > - int r = 0; > > - > > - /* remove hostkey from the child's memory */ > > -- destroy_sensitive_data(); > > -+ destroy_sensitive_data(1); > > -+ /* Don't audit this - both us and the parent would be talking > to > > > > the > > -+ monitor over a single socket, with no synchronization. */ > > -+ packet_destroy_all(0, 1); > > - > > - /* Force a password change */ > > - if (s->authctxt->force_pwchange) { > > -@@ -1934,6 +1949,7 @@ session_unused(int id) > > - sessions[id].ttyfd = -1; > > - sessions[id].ptymaster = -1; > > - sessions[id].x11_chanids = NULL; > > -+ sessions[id].command_handle = -1; > > - sessions[id].next_unused = sessions_first_unused; > > - sessions_first_unused = id; > > - } > > -@@ -2016,6 +2032,19 @@ session_open(Authctxt *authctxt, int cha > > - } > > - > > - Session * > > -+session_by_id(int id) > > -+{ > > -+ if (id >= 0 && id < sessions_nalloc) { > > -+ Session *s = &sessions[id]; > > -+ if (s->used) > > -+ return s; > > -+ } > > -+ debug("session_by_id: unknown id %d", id); > > -+ session_dump(); > > -+ return NULL; > > -+} > > -+ > > -+Session * > > - session_by_tty(char *tty) > > - { > > - int i; > > -@@ -2532,6 +2561,32 @@ session_exit_message(Session *s, int sta > > - chan_write_failed(c); > > - } > > - > > -+#ifdef SSH_AUDIT_EVENTS > > -+void > > -+session_end_command2(Session *s) > > -+{ > > -+ if (s->command != NULL) { > > -+ if (s->command_handle != -1) > > -+ audit_end_command(s->command_handle, s->command); > > -+ free(s->command); > > -+ s->command = NULL; > > -+ s->command_handle = -1; > > -+ } > > -+} > > -+ > > -+static void > > -+session_end_command(Session *s) > > -+{ > > -+ if (s->command != NULL) { > > -+ if (s->command_handle != -1) > > -+ PRIVSEP(audit_end_command(s->command_handle, > > s->command)); > > -+ free(s->command); > > -+ s->command = NULL; > > -+ s->command_handle = -1; > > -+ } > > -+} > > -+#endif > > -+ > > - void > > - session_close(Session *s) > > - { > > -@@ -2540,6 +2593,10 @@ session_close(Session *s) > > - debug("session_close: session %d pid %ld", s->self, > > (long)s->pid); > > - if (s->ttyfd != -1) > > - session_pty_cleanup(s); > > -+#ifdef SSH_AUDIT_EVENTS > > -+ if (s->command) > > -+ session_end_command(s); > > -+#endif > > - free(s->term); > > - free(s->display); > > - free(s->x11_chanids); > > -@@ -2754,6 +2811,15 @@ do_authenticated2(Authctxt *authctxt) > > - server_loop2(authctxt); > > - } > > - > > -+static void > > -+do_cleanup_one_session(Session *s) > > -+{ > > -+ session_pty_cleanup2(s); > > -+#ifdef SSH_AUDIT_EVENTS > > -+ session_end_command2(s); > > -+#endif > > -+} > > -+ > > - void > > - do_cleanup(Authctxt *authctxt) > > - { > > -@@ -2802,5 +2868,5 @@ do_cleanup(Authctxt *authctxt) > > - * or if running in monitor. > > - */ > > - if (!use_privsep || mm_is_monitor()) > > -- session_destroy_all(session_pty_cleanup2); > > -+ session_destroy_all(do_cleanup_one_session); > > - } > > -diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h > > ---- openssh-6.8p1/session.h.audit 2015-03-17 06:49:20.000000000 > > +0100 > > -+++ openssh-6.8p1/session.h 2015-03-20 13:41:15.097883774 +0100 > > -@@ -61,6 +61,12 @@ struct Session { > > - char *name; > > - char *val; > > - } *env; > > -+ > > -+ /* exec */ > > -+#ifdef SSH_AUDIT_EVENTS > > -+ int command_handle; > > -+ char *command; > > -+#endif > > - }; > > - > > - void do_authenticated(Authctxt *); > > -@@ -73,8 +79,10 @@ void session_close_by_pid(pid_t, int); > > - void session_close_by_channel(int, void *); > > - void session_destroy_all(void (*)(Session *)); > > - void session_pty_cleanup2(Session *); > > -+void session_end_command2(Session *); > > - > > - Session *session_new(void); > > -+Session *session_by_id(int); > > - Session *session_by_tty(char *); > > - void session_close(Session *); > > - void do_setusercontext(struct passwd *); > > -diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c > > ---- openssh-6.8p1/sshd.c.audit 2015-03-20 13:41:15.083883796 > +0100 > > > > -+++ openssh-6.8p1/sshd.c 2015-03-20 13:41:15.110883753 +0100 > > -@@ -121,6 +124,7 @@ > > - #endif > > - #include "monitor_wrap.h" > > - #include "roaming.h" > > -+#include "audit.h" > > - #include "ssh-sandbox.h" > > - #include "version.h" > > - #include "ssherr.h" > > -@@ -260,7 +264,7 @@ Buffer loginmsg; > > - struct passwd *privsep_pw = NULL; > > - > > - /* Prototypes for various functions defined later in this file. */ > > --void destroy_sensitive_data(void); > > -+void destroy_sensitive_data(int); > > - void demote_sensitive_data(void); > > - > > - #ifdef WITH_SSH1 > > -@@ -281,6 +285,15 @@ close_listen_socks(void) > > - num_listen_socks = -1; > > - } > > - > > -+/* > > -+ * Is this process listening for clients (i.e. not specific to any > > specific > > -+ * client connection?) > > -+ */ > > -+int listening_for_clients(void) > > -+{ > > -+ return num_listen_socks > 0; > > -+} > > -+ > > - static void > > - close_startup_pipes(void) > > - { > > -@@ -560,22 +573,45 @@ sshd_exchange_identification(int sock_in > > - } > > - } > > - > > --/* Destroy the host and server keys. They will no longer be > needed. > > > > */ > > -+/* > > -+ * Destroy the host and server keys. They will no longer be > needed. > > > > Careful, > > -+ * this can be called from cleanup_exit() - i.e. from just about > > anywhere. > > -+ */ > > - void > > --destroy_sensitive_data(void) > > -+destroy_sensitive_data(int privsep) > > - { > > - int i; > > -+ pid_t pid; > > -+ uid_t uid; > > - > > - if (sensitive_data.server_key) { > > - key_free(sensitive_data.server_key); > > - sensitive_data.server_key = NULL; > > - } > > -+ pid = getpid(); > > -+ uid = getuid(); > > - for (i = 0; i < options.num_host_key_files; i++) { > > - if (sensitive_data.host_keys[i]) { > > -+ char *fp; > > -+ > > -+ if (key_is_private(sensitive_data.host_keys[i])) > > -+ fp = > > sshkey_fingerprint(sensitive_data.host_keys[i], > > options.fingerprint_hash, SSH_FP_HEX); > > -+ else > > -+ fp = NULL; > > - key_free(sensitive_data.host_keys[i]); > > - sensitive_data.host_keys[i] = NULL; > > -+ if (fp != NULL) { > > -+ if (privsep) > > -+ PRIVSEP(audit_destroy_sensitive_da > > ta > > (fp, > > -+ pid, uid)); > > -+ else > > -+ audit_destroy_sensitive_data(fp, > > -+ pid, uid); > > -+ free(fp); > > -+ } > > - } > > -- if (sensitive_data.host_certificates[i]) { > > -+ if (sensitive_data.host_certificates > > -+ && sensitive_data.host_certificates[i]) { > > - key_free(sensitive_data.host_certificates[i]); > > - sensitive_data.host_certificates[i] = NULL; > > - } > > -@@ -589,6 +625,8 @@ void > > - demote_sensitive_data(void) > > - { > > - Key *tmp; > > -+ pid_t pid; > > -+ uid_t uid; > > - int i; > > - > > - if (sensitive_data.server_key) { > > -@@ -597,13 +635,25 @@ demote_sensitive_data(void) > > - sensitive_data.server_key = tmp; > > - } > > - > > -+ pid = getpid(); > > -+ uid = getuid(); > > - for (i = 0; i < options.num_host_key_files; i++) { > > - if (sensitive_data.host_keys[i]) { > > -+ char *fp; > > -+ > > -+ if (key_is_private(sensitive_data.host_keys[i])) > > -+ fp = > > sshkey_fingerprint(sensitive_data.host_keys[i], > > options.fingerprint_hash, SSH_FP_HEX); > > -+ else > > -+ fp = NULL; > > - tmp = key_demote(sensitive_data.host_keys[i]); > > - key_free(sensitive_data.host_keys[i]); > > - sensitive_data.host_keys[i] = tmp; > > - if (tmp->type == KEY_RSA1) > > - sensitive_data.ssh1_host_key = tmp; > > -+ if (fp != NULL) { > > -+ audit_destroy_sensitive_data(fp, pid, > > uid); > > -+ free(fp); > > -+ } > > - } > > - /* Certs do not need demotion */ > > - } > > -@@ -675,7 +725,7 @@ privsep_preauth(Authctxt *authctxt) > > - > > - if (use_privsep == PRIVSEP_ON) > > - box = ssh_sandbox_init(pmonitor); > > -- pid = fork(); > > -+ pmonitor->m_pid = pid = fork(); > > - if (pid == -1) { > > - fatal("fork of unprivileged child failed"); > > - } else if (pid != 0) { > > -@@ -759,6 +811,12 @@ privsep_postauth(Authctxt *authctxt) > > - else if (pmonitor->m_pid != 0) { > > - verbose("User child is on pid %ld", > (long)pmonitor->m_pid); > > > > - buffer_clear(&loginmsg); > > -+ if (*pmonitor->m_pkex != NULL ){ > > -+ > > newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]); > > -+ newkeys_destroy((*pmonitor->m_pkex)- > > > > > > newkeys[MODE_IN]); > > -+ audit_session_key_free_body(2, getpid(), > > getuid()); > > -+ packet_destroy_all(0, 0); > > -+ } > > - monitor_child_postauth(pmonitor); > > - > > - /* NEVERREACHED */ > > -@@ -1286,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so > > - if (received_sigterm) { > > - logit("Received signal %d; terminating.", > > - (int) received_sigterm); > > -+ destroy_sensitive_data(0); > > - close_listen_socks(); > > - if (options.pid_file != NULL) > > - unlink(options.pid_file); > > -@@ -2242,6 +2321,7 @@ main(int ac, char **av) > > - */ > > - if (use_privsep) { > > - mm_send_keystate(pmonitor); > > -+ packet_destroy_all(1, 1); > > - exit(0); > > - } > > - > > -@@ -2287,7 +2367,7 @@ main(int ac, char **av) > > - privsep_postauth(authctxt); > > - /* the monitor process [priv] will not return */ > > - if (!compat20) > > -- destroy_sensitive_data(); > > -+ destroy_sensitive_data(0); > > - } > > - > > - packet_set_timeout(options.client_alive_interval, > > -@@ -2301,6 +2381,9 @@ main(int ac, char **av) > > - do_authenticated(authctxt); > > - > > - /* The connection has been terminated. */ > > -+ packet_destroy_all(1, 1); > > -+ destroy_sensitive_data(1); > > -+ > > - packet_get_bytes(&ibytes, &obytes); > > - verbose("Transferred: sent %llu, received %llu bytes", > > - (unsigned long long)obytes, (unsigned long long)ibytes); > > -@@ -2461,6 +2544,10 @@ do_ssh1_kex(void) > > - if (cookie[i] != packet_get_char()) > > - packet_disconnect("IP Spoofing check bytes do not > > match."); > > - > > -+#ifdef SSH_AUDIT_EVENTS > > -+ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); > > -+#endif > > -+ > > - debug("Encryption type: %.200s", cipher_name(cipher_type)); > > - > > - /* Get the encrypted integer. */ > > -@@ -2520,7 +2607,7 @@ do_ssh1_kex(void) > > - } > > - > > - /* Destroy the private and public keys. No longer. */ > > -- destroy_sensitive_data(); > > -+ destroy_sensitive_data(1); > > - > > - if (use_privsep) > > - mm_ssh1_session_id(session_id); > > -@@ -2703,6 +2802,16 @@ do_ssh2_kex(void) > > - void > > - cleanup_exit(int i) > > - { > > -+ static int in_cleanup = 0; > > -+ int is_privsep_child; > > -+ > > -+ /* cleanup_exit can be called at the very least from the > privsep > > > > -+ wrappers used for auditing. Make sure we don't recurse > > -+ indefinitely. */ > > -+ if (in_cleanup) > > -+ _exit(i); > > -+ in_cleanup = 1; > > -+ > > - if (the_authctxt) { > > - do_cleanup(the_authctxt); > > - if (use_privsep && privsep_is_preauth && > > -@@ -2714,9 +2823,14 @@ cleanup_exit(int i) > > - pmonitor->m_pid, strerror(errno)); > > - } > > - } > > -+ is_privsep_child = use_privsep && pmonitor != NULL && > > pmonitor->m_pid == 0; > > -+ if (sensitive_data.host_keys != NULL) > > -+ destroy_sensitive_data(is_privsep_child); > > -+ packet_destroy_all(1, is_privsep_child); > > - #ifdef SSH_AUDIT_EVENTS > > - /* done after do_cleanup so it can cancel the PAM auth > 'thread' > > > > */ > > -- if (!use_privsep || mm_is_monitor()) > > -+ if ((the_authctxt == NULL || !the_authctxt->authenticated) && > > -+ (!use_privsep || mm_is_monitor())) > > - audit_event(SSH_CONNECTION_ABANDON); > > - #endif > > - _exit(i); > > -diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c > > ---- openssh-6.8p1/sshkey.c.audit 2015-03-17 06:49:20.000000000 > > +0100 > > -+++ openssh-6.8p1/sshkey.c 2015-03-20 13:41:15.111883751 +0100 > > -@@ -317,6 +319,33 @@ sshkey_type_is_valid_ca(int type) > > - } > > - > > - int > > -+sshkey_is_private(const struct sshkey *k) > > -+{ > > -+ switch (k->type) { > > -+ case KEY_RSA_CERT_V00: > > -+ case KEY_RSA_CERT: > > -+ case KEY_RSA1: > > -+ case KEY_RSA: > > -+ return k->rsa->d != NULL; > > -+ case KEY_DSA_CERT_V00: > > -+ case KEY_DSA_CERT: > > -+ case KEY_DSA: > > -+ return k->dsa->priv_key != NULL; > > -+#ifdef OPENSSL_HAS_ECC > > -+ case KEY_ECDSA_CERT: > > -+ case KEY_ECDSA: > > -+ return EC_KEY_get0_private_key(k->ecdsa) != NULL; > > -+#endif > > -+ case KEY_ED25519_CERT: > > -+ case KEY_ED25519: > > -+ return (k->ed25519_pk != NULL); > > -+ default: > > -+ /* fatal("key_is_private: bad key type %d", k->type); > */ > > > > -+ return 0; > > -+ } > > -+} > > -+ > > -+int > > - sshkey_is_cert(const struct sshkey *k) > > - { > > - if (k == NULL) > > -diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h > > ---- openssh-6.8p1/sshkey.h.audit 2015-03-17 06:49:20.000000000 > > +0100 > > -+++ openssh-6.8p1/sshkey.h 2015-03-20 13:41:15.098883772 +0100 > > -@@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey > > - int sshkey_generate(int type, u_int bits, struct sshkey > > **keyp); > > - int sshkey_from_private(const struct sshkey *, struct > > sshkey > > **); > > - int sshkey_type_from_name(const char *); > > -+int sshkey_is_private(const struct sshkey *); > > - int sshkey_is_cert(const struct sshkey *); > > - int sshkey_type_is_cert(int); > > - int sshkey_type_plain(int); > > -diff -up openssh-6.8p1/sandbox-seccomp-filter.c.audit > > openssh-6.8p1/sandbox-seccomp-filter.c > > ---- openssh-6.8p1/sandbox-seccomp-filter.c.audit 2015-03-20 > > 13:41:15.088883788 +0100 > > -+++ openssh-6.8p1/sandbox-seccomp-filter.c 2015-03-20 > > 13:41:15.097883774 +0100 > > -@@ -110,6 +110,12 @@ static const struct sock_filter preauth_ > > - #ifdef __NR_time /* not defined on EABI ARM */ > > - SC_ALLOW(time), > > - #endif > > -+#ifdef SSH_AUDIT_EVENTS > > -+ SC_ALLOW(getuid), > > -+#ifdef __NR_getuid32 /* not defined on x86_64 */ > > -+ SC_ALLOW(getuid32), > > -+#endif > > -+#endif > > - SC_ALLOW(read), > > - SC_ALLOW(write), > > - SC_ALLOW(close), > > diff --git a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > > b/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > > deleted file mode 100644 > > index 4285bd9..0000000 > > --- a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch > > +++ /dev/null > > @@ -1,66 +0,0 @@ > > -diff --git a/configure.ac b/configure.ac > > -index 4065d0e..d59ad44 100644 > > ---- a/configure.ac > > -+++ b/configure.ac > > -@@ -764,9 +764,12 @@ main() { if > (NSVersionOfRunTimeLibrary("System") > > > > > > > > > > > = (60 << 16)) > > - i*86-*) > > - seccomp_audit_arch=AUDIT_ARCH_I386 > > - ;; > > -- arm*-*) > > -+ aarch64*-*) > > -+ seccomp_audit_arch=AUDIT_ARCH_AARCH64 > > -+ ;; > > -+ arm*-*) > > - seccomp_audit_arch=AUDIT_ARCH_ARM > > -- ;; > > -+ ;; > > - esac > > - if test "x$seccomp_audit_arch" != "x" ; then > > - AC_MSG_RESULT(["$seccomp_audit_arch"]) > > -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c > > -index 095b04a..52f6810 100644 > > ---- a/sandbox-seccomp-filter.c > > -+++ b/sandbox-seccomp-filter.c > > -@@ -90,8 +90,20 @@ static const struct sock_filter preauth_insns[] = > { > > > > - /* Load the syscall number for checking. */ > > - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, > > - offsetof(struct seccomp_data, nr)), > > -- SC_DENY(open, EACCES), > > -- SC_DENY(stat, EACCES), > > -+ SC_DENY(openat, EACCES), > > -+#ifdef __NR_open > > -+ SC_DENY(open, EACCES), /* not on AArch64 */ > > -+#endif > > -+#ifdef __NR_fstat > > -+ SC_DENY(fstat, EACCES), /* x86_64, Aarch64 */ > > -+#endif > > -+#if defined(__NR_stat64) && defined(__NR_fstat64) > > -+ SC_DENY(stat64, EACCES), /* ix86, arm */ > > -+ SC_DENY(fstat64, EACCES), > > -+#endif > > -+#ifdef __NR_newfstatat > > -+ SC_DENY(newfstatat, EACCES), /* Aarch64 */ > > -+#endif > > - SC_ALLOW(getpid), > > - SC_ALLOW(gettimeofday), > > - SC_ALLOW(clock_gettime), > > -@@ -111,12 +123,19 @@ static const struct sock_filter preauth_insns[] > = > > > > { > > - SC_ALLOW(shutdown), > > - #endif > > - SC_ALLOW(brk), > > -+#ifdef __NR_poll /* not on AArch64 */ > > - SC_ALLOW(poll), > > -+#endif > > - #ifdef __NR__newselect > > - SC_ALLOW(_newselect), > > - #else > > -+#ifdef __NR_select /* not on AArch64 */ > > - SC_ALLOW(select), > > - #endif > > -+#ifdef __NR_pselect6 /* AArch64 */ > > -+ SC_ALLOW(pselect6), > > -+#endif > > -+#endif > > - SC_ALLOW(madvise), > > - #ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ > > - SC_ALLOW(mmap2), > >