diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index f36d83f..44c345b 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -34,7 +34,7 @@ diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h void log_init(char *, LogLevel, SyslogFacility, int); +void log_init_handler(char *, LogLevel, SyslogFacility, int, int); - void log_change_level(LogLevel); + int log_change_level(LogLevel); int log_is_on_stderr(void); void log_redirect_stderr_to(const char *); diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c @@ -123,30 +123,8 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c static int in_chroot = 0; +static int have_dev_log = 1; - /* Name and directory of socket for authentication agent forwarding. */ - static char *auth_sock_name = NULL; -@@ -365,8 +366,8 @@ do_exec_no_pty(Session *s, const char *c - is_child = 1; - - /* Child. Reinitialize the log since the pid has changed. */ -- log_init(__progname, options.log_level, -- options.log_facility, log_stderr); -+ log_init_handler(__progname, options.log_level, -+ options.log_facility, log_stderr, have_dev_log); - - /* - * Create a new session and process group since the 4.4BSD -@@ -523,8 +524,8 @@ do_exec_pty(Session *s, const char *comm - close(ptymaster); - - /* Child. Reinitialize the log because the pid has changed. */ -- log_init(__progname, options.log_level, -- options.log_facility, log_stderr); -+ log_init_handler(__progname, options.log_level, -+ options.log_facility, log_stderr, have_dev_log); - /* Close the master side of the pseudo tty. */ - close(ptyfd); - + /* File containing userauth info, if ExposeAuthInfo set */ + static char *auth_info_file = NULL; @@ -619,6 +620,7 @@ do_exec(Session *s, const char *command) int ret; const char *forced = NULL, *tty = NULL; diff --git a/openssh-6.6p1-GSSAPIEnablek5users.patch b/openssh-6.6p1-GSSAPIEnablek5users.patch index e64d320..9f91f14 100644 --- a/openssh-6.6p1-GSSAPIEnablek5users.patch +++ b/openssh-6.6p1-GSSAPIEnablek5users.patch @@ -22,22 +22,22 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.GSSAPIEnablek5users 2016-12-23 15:18:40.615216100 +0100 +++ openssh-7.4p1/servconf.c 2016-12-23 15:35:36.354401156 +0100 @@ -168,6 +168,7 @@ initialize_server_options(ServerOptions - options->fingerprint_hash = -1; - options->disable_forwarding = -1; + options->gss_strict_acceptor = -1; + options->gss_store_rekey = -1; options->use_kuserok = -1; + options->enable_k5users = -1; - } - - /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->challenge_response_authentication = -1; @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption - options->disable_forwarding = 0; + options->gss_store_rekey = 0; if (options->use_kuserok == -1) options->use_kuserok = 1; + if (options->enable_k5users == -1) + options->enable_k5users = 0; - - assemble_algorithms(options); - + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) @@ -418,7 +421,7 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, sHostKeyAlgorithms, @@ -80,28 +80,26 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c + M_CP_INTOPT(enable_k5users); M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); - + M_CP_INTOPT(log_level); @@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); - dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); + # endif dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); + #endif + #ifdef GSSAPI + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h --- openssh-7.4p1/servconf.h.GSSAPIEnablek5users 2016-12-23 15:18:40.616216100 +0100 +++ openssh-7.4p1/servconf.h 2016-12-23 15:18:40.629216102 +0100 -@@ -174,7 +174,8 @@ typedef struct { - - int num_permitted_opens; - -- int use_kuserok; -+ int use_kuserok; +@@ -174,6 +174,7 @@ typedef struct { + int kerberos_get_afs_token; /* If true, try to get AFS token if + * authenticated with Kerberos. */ + int use_kuserok; + int enable_k5users; - char *chroot_directory; - char *revoked_keys_file; - char *trusted_user_ca_keys; + int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_keyex; /* If true, permit GSSAPI key exchange */ + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5 --- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users 2016-12-23 15:18:40.630216103 +0100 +++ openssh-7.4p1/sshd_config.5 2016-12-23 15:36:21.607408435 +0100 diff --git a/openssh-6.6p1-ctr-cavstest.patch b/openssh-6.6p1-ctr-cavstest.patch index eb43c79..8aa6872 100644 --- a/openssh-6.6p1-ctr-cavstest.patch +++ b/openssh-6.6p1-ctr-cavstest.patch @@ -20,7 +20,7 @@ diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in ssh_api.o \ @@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o - $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) + $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) +ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o + $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) diff --git a/openssh-6.6p1-entropy.patch b/openssh-6.6p1-entropy.patch index db8ce54..f1fc6c9 100644 --- a/openssh-6.6p1-entropy.patch +++ b/openssh-6.6p1-entropy.patch @@ -16,7 +16,7 @@ diff -up openssh-7.4p1/openbsd-compat/Makefile.in.entropy openssh-7.4p1/openbsd- +++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 18:35:15.890769493 +0100 @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o @@ -123,26 +123,6 @@ diff -up openssh-7.4p1/ssh.1.entropy openssh-7.4p1/ssh.1 .Sh FILES .Bl -tag -width Ds -compact .It Pa ~/.rhosts -diff -up openssh-7.4p1/ssh-add.0.entropy openssh-7.4p1/ssh-add.0 ---- openssh-7.4p1/ssh-add.0.entropy 2016-12-19 06:21:21.000000000 +0100 -+++ openssh-7.4p1/ssh-add.0 2016-12-23 18:34:27.770753571 +0100 -@@ -88,6 +88,16 @@ ENVIRONMENT - Identifies the path of a UNIX-domain socket used to communicate - with the agent. - -+ SSH_USE_STRONG_RNG -+ The reseeding of the OpenSSL random generator is usually done -+ from /dev/urandom. If the SSH_USE_STRONG_RNG environment vari- -+ able is set to value other than 0 the OpenSSL random generator is -+ reseeded from /dev/random. The number of bytes read is defined -+ by the SSH_USE_STRONG_RNG value. Minimum is 14 bytes. This set- -+ ting is not recommended on the computers without the hardware -+ random generator because insufficient entropy causes the connec- -+ tion to be blocked until enough entropy is available. -+ - FILES - ~/.ssh/identity - Contains the protocol version 1 RSA authentication identity of diff -up openssh-7.4p1/ssh-add.1.entropy openssh-7.4p1/ssh-add.1 --- openssh-7.4p1/ssh-add.1.entropy 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/ssh-add.1 2016-12-23 18:34:27.770753571 +0100 diff --git a/openssh-6.6p1-keycat.patch b/openssh-6.6p1-keycat.patch index 2e8f977..b2826be 100644 --- a/openssh-6.6p1-keycat.patch +++ b/openssh-6.6p1-keycat.patch @@ -1,6 +1,6 @@ -diff -up openssh/auth2-pubkey.c.keycat openssh/auth2-pubkey.c ---- openssh/auth2-pubkey.c.keycat 2015-06-24 10:57:50.158849606 +0200 -+++ openssh/auth2-pubkey.c 2015-06-24 11:04:23.989868638 +0200 +diff -up openssh/misc.c.keycat openssh/misc.c +--- openssh/misc.c.keycat 2015-06-24 10:57:50.158849606 +0200 ++++ openssh/misc.c 2015-06-24 11:04:23.989868638 +0200 @@ -490,6 +490,14 @@ subprocess(const char *tag, struct passw _exit(1); } @@ -65,7 +65,7 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in $(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o -+ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) ++ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch index 3f10d60..47768aa 100644 --- a/openssh-6.6p1-kuserok.patch +++ b/openssh-6.6p1-kuserok.patch @@ -175,23 +175,23 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.kuserok 2016-12-23 14:36:07.630465944 +0100 +++ openssh-7.4p1/servconf.c 2016-12-23 15:11:52.278133344 +0100 -@@ -167,6 +167,7 @@ initialize_server_options(ServerOptions - options->version_addendum = NULL; - options->fingerprint_hash = -1; - options->disable_forwarding = -1; +@@ -116,6 +116,7 @@ initialize_server_options(ServerOptions + options->gss_cleanup_creds = -1; + options->gss_strict_acceptor = -1; + options->gss_store_rekey = -1; + options->use_kuserok = -1; - } - - /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -342,6 +343,8 @@ fill_default_server_options(ServerOption - options->fingerprint_hash = SSH_FP_HASH_DEFAULT; - if (options->disable_forwarding == -1) - options->disable_forwarding = 0; + options->password_authentication = -1; + options->kbd_interactive_authentication = -1; + options->challenge_response_authentication = -1; +@@ -278,6 +279,8 @@ fill_default_server_options(ServerOption + options->gss_strict_acceptor = 1; + if (options->gss_store_rekey == -1) + options->gss_store_rekey = 0; + if (options->use_kuserok == -1) + options->use_kuserok = 1; - - assemble_algorithms(options); - + if (options->password_authentication == -1) + options->password_authentication = 1; + if (options->kbd_interactive_authentication == -1) @@ -399,7 +402,7 @@ typedef enum { sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, @@ -233,26 +233,26 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c + M_CP_INTOPT(use_kuserok); M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); - + M_CP_INTOPT(log_level); @@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); - dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); - dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); + # ifdef USE_AFS + dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); + # endif + dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); + #endif + #ifdef GSSAPI + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h --- openssh-7.4p1/servconf.h.kuserok 2016-12-23 14:36:07.630465944 +0100 +++ openssh-7.4p1/servconf.h 2016-12-23 14:36:07.645465936 +0100 -@@ -174,6 +174,7 @@ typedef struct { - - int num_permitted_opens; - +@@ -118,6 +118,7 @@ typedef struct { + * file on logout. */ + int kerberos_get_afs_token; /* If true, try to get AFS token if + * authenticated with Kerberos. */ + int use_kuserok; - char *chroot_directory; - char *revoked_keys_file; - char *trusted_user_ca_keys; + int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_keyex; /* If true, permit GSSAPI key exchange */ + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 --- openssh-7.4p1/sshd_config.5.kuserok 2016-12-23 14:36:07.637465940 +0100 +++ openssh-7.4p1/sshd_config.5 2016-12-23 15:14:03.117162222 +0100 @@ -272,9 +272,9 @@ diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , +.Cm KerberosUseKuserok , + .Cm LogLevel , .Cm MaxAuthTries , .Cm MaxSessions , - .Cm PasswordAuthentication , diff -up openssh-7.4p1/sshd_config.kuserok openssh-7.4p1/sshd_config --- openssh-7.4p1/sshd_config.kuserok 2016-12-23 14:36:07.631465943 +0100 +++ openssh-7.4p1/sshd_config 2016-12-23 14:36:07.646465935 +0100 diff --git a/openssh-6.6p1-privsep-selinux.patch b/openssh-6.6p1-privsep-selinux.patch index 6933b39..bc2c15d 100644 --- a/openssh-6.6p1-privsep-selinux.patch +++ b/openssh-6.6p1-privsep-selinux.patch @@ -107,7 +107,7 @@ diff -up openssh-7.4p1/sshd.c.privsep-selinux openssh-7.4p1/sshd.c +#endif + /* Demote the child */ - if (getuid() == 0 || geteuid() == 0) { + if (privsep_chroot) { /* Change our root directory */ @@ -633,6 +637,9 @@ privsep_postauth(Authctxt *authctxt) { diff --git a/openssh-6.6p1-role-mls.patch b/openssh-6.6p1-role-mls.patch index f2bfa5a..ad2411f 100644 --- a/openssh-6.6p1-role-mls.patch +++ b/openssh-6.6p1-role-mls.patch @@ -2,7 +2,7 @@ diff -up openssh-7.4p1/auth2.c.role-mls openssh-7.4p1/auth2.c --- openssh-7.4p1/auth2.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth2.c 2016-12-23 12:19:58.587459379 +0100 @@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32 - Authctxt *authctxt = ctxt; + Authctxt *authctxt = ssh->authctxt; Authmethod *m = NULL; char *user, *service, *method, *style = NULL; +#ifdef WITH_SELINUX @@ -44,7 +44,7 @@ diff -up openssh-7.4p1/auth2-gss.c.role-mls openssh-7.4p1/auth2-gss.c --- openssh-7.4p1/auth2-gss.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth2-gss.c 2016-12-23 12:19:58.586459382 +0100 @@ -255,6 +255,7 @@ input_gssapi_mic(int type, u_int32_t ple - Authctxt *authctxt = ctxt; + Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; int authenticated = 0; + char *micuser; @@ -74,34 +74,35 @@ diff -up openssh-7.4p1/auth2-gss.c.role-mls openssh-7.4p1/auth2-gss.c + free(micuser); free(mic.value); - authctxt->postponed = 0; + if ((!use_privsep || mm_is_monitor()) && diff -up openssh-7.4p1/auth2-hostbased.c.role-mls openssh-7.4p1/auth2-hostbased.c --- openssh-7.4p1/auth2-hostbased.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 12:19:58.586459382 +0100 -@@ -121,7 +121,15 @@ userauth_hostbased(Authctxt *authctxt) - buffer_put_string(&b, session_id2, session_id2_len); +@@ -121,7 +121,16 @@ userauth_hostbased(Authctxt *authctxt) /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); + if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || +- (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#ifdef WITH_SELINUX -+ if (authctxt->role) { -+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); -+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); -+ buffer_put_char(&b, '/'); -+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); -+ } else ++ (authctxt->role ++ ? ( (r = sshbuf_put_u32(b, strlen(authctxt->user)+strlen(authctxt->role)+1)) != 0 || ++ (r = sshbuf_put(b, authctxt->user, strlen(authctxt->user))) != 0 || ++ (r = sshbuf_put_u8(b, '/') != 0) || ++ (r = sshbuf_put(b, authctxt->role, strlen(authctxt->role))) != 0) ++ : (r = sshbuf_put_cstring(b, authctxt->user)) != 0) || ++#else ++ (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || +#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, "hostbased"); - buffer_put_string(&b, pkalg, alen); + (r = sshbuf_put_cstring(b, service)) != 0 || + (r = sshbuf_put_cstring(b, "hostbased")) != 0 || + (r = sshbuf_put_string(b, pkalg, alen)) != 0 || diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c --- openssh-7.4p1/auth2-pubkey.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 12:19:58.587459379 +0100 @@ -151,9 +151,15 @@ userauth_pubkey(Authctxt *authctxt) + __func__, ssh_err(r)); } /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - xasprintf(&userstyle, "%s%s%s", authctxt->user, + xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user, authctxt->style ? ":" : "", @@ -113,9 +114,9 @@ diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c +#else + "", ""); +#endif - buffer_put_cstring(&b, userstyle); - free(userstyle); - buffer_put_cstring(&b, + if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || + (r = sshbuf_put_cstring(b, userstyle)) != 0 || + (r = sshbuf_put_cstring(b, ssh->compat & SSH_BUG_PKSERVICE ? diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h --- openssh-7.4p1/auth.h.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth.h 2016-12-23 12:19:43.478510375 +0100 @@ -126,9 +127,9 @@ diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h +#ifdef WITH_SELINUX + char *role; +#endif - void *kbdintctxt; - char *info; /* Extra info for next auth_log */ - #ifdef BSD_AUTH + + /* Method lists for multiple authentication */ + char **auth_methods; /* modified from server config */ diff -up openssh-7.4p1/auth-pam.c.role-mls openssh-7.4p1/auth-pam.c --- openssh-7.4p1/auth-pam.c.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/auth-pam.c 2016-12-23 12:19:43.477510378 +0100 @@ -320,8 +321,8 @@ diff -up openssh-7.4p1/monitor_wrap.h.role-mls openssh-7.4p1/monitor_wrap.h --- openssh-7.4p1/monitor_wrap.h.role-mls 2016-12-19 05:59:41.000000000 +0100 +++ openssh-7.4p1/monitor_wrap.h 2016-12-23 12:19:58.588459376 +0100 @@ -42,6 +42,9 @@ int mm_is_monitor(void); - DH *mm_choose_dh(int, int, int); - int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); + int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, + const char *); void mm_inform_authserv(char *, char *); +#ifdef WITH_SELINUX +void mm_inform_authrole(char *); @@ -334,7 +335,7 @@ diff -up openssh-7.4p1/openbsd-compat/Makefile.in.role-mls openssh-7.4p1/openbsd +++ openssh-7.4p1/openbsd-compat/Makefile.in 2016-12-23 12:24:06.042643938 +0100 @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf - COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o + COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o -PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o +PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o @@ -863,3 +864,16 @@ diff -up openssh-7.4p1/sshd.c.role-mls openssh-7.4p1/sshd.c #ifdef USE_PAM if (options.use_pam) { do_pam_setcred(1); +--- openssh/configure.ac.role-mls 2017-09-27 12:54:52.926425979 +0200 ++++ openssh/configure.ac 2017-09-27 12:57:06.854224956 +0200 +@@ -4158,10 +4158,7 @@ + LIBS="$LIBS -lselinux" + ], + AC_MSG_ERROR([SELinux support requires libselinux library])) +- SSHLIBS="$SSHLIBS $LIBSELINUX" +- SSHDLIBS="$SSHDLIBS $LIBSELINUX" + AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) +- LIBS="$save_LIBS" + fi ] + ) + AC_SUBST([SSHLIBS]) diff --git a/openssh-6.8p1-memory-problems.patch b/openssh-6.8p1-memory-problems.patch index e112033..b2da05e 100644 --- a/openssh-6.8p1-memory-problems.patch +++ b/openssh-6.8p1-memory-problems.patch @@ -21,4 +21,4 @@ diff -up openssh-7.4p1/servconf.c.memory openssh-7.4p1/servconf.c + dst->n[dst->num_n] = src->n[dst->num_n]; \ } \ } while(0) - + #define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \ diff --git a/openssh-7.0p1-gssKexAlgorithms.patch b/openssh-7.0p1-gssKexAlgorithms.patch index 30519af..6200eaa 100644 --- a/openssh-7.0p1-gssKexAlgorithms.patch +++ b/openssh-7.0p1-gssKexAlgorithms.patch @@ -245,9 +245,9 @@ diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c options->gss_strict_acceptor = -1; options->gss_store_rekey = -1; + options->gss_kex_algorithms = NULL; + options->use_kuserok = -1; + options->enable_k5users = -1; options->password_authentication = -1; - options->kbd_interactive_authentication = -1; - options->challenge_response_authentication = -1; @@ -288,6 +290,10 @@ fill_default_server_options(ServerOption options->gss_strict_acceptor = 1; if (options->gss_store_rekey == -1) @@ -256,9 +256,9 @@ diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c + if (options->gss_kex_algorithms == NULL) + options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); +#endif - if (options->password_authentication == -1) - options->password_authentication = 1; - if (options->kbd_interactive_authentication == -1) + if (options->use_kuserok == -1) + options->use_kuserok = 1; + if (options->enable_k5users == -1) @@ -427,7 +431,7 @@ typedef enum { sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, diff --git a/openssh-7.0p1-show-more-fingerprints.patch b/openssh-7.0p1-show-more-fingerprints.patch index d4637f5..aeb3daa 100644 --- a/openssh-7.0p1-show-more-fingerprints.patch +++ b/openssh-7.0p1-show-more-fingerprints.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c ---- openssh-7.4p1/clientloop.c.fingerprint 2016-12-23 15:38:50.520432387 +0100 -+++ openssh-7.4p1/clientloop.c 2016-12-23 15:38:50.564432394 +0100 -@@ -2279,7 +2279,7 @@ update_known_hosts(struct hostkeys_updat +diff -up openssh/clientloop.c.fingerprint openssh/clientloop.c +--- openssh/clientloop.c.fingerprint 2017-09-26 15:21:22.582477729 +0200 ++++ openssh/clientloop.c 2017-09-26 15:21:22.620477932 +0200 +@@ -1854,7 +1854,7 @@ update_known_hosts(struct hostkeys_updat if (ctx->keys_seen[i] != 2) continue; if ((fp = sshkey_fingerprint(ctx->keys[i], @@ -10,7 +10,7 @@ diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c fatal("%s: sshkey_fingerprint failed", __func__); do_log2(loglevel, "Learned new hostkey: %s %s", sshkey_type(ctx->keys[i]), fp); -@@ -2287,7 +2287,7 @@ update_known_hosts(struct hostkeys_updat +@@ -1862,7 +1862,7 @@ update_known_hosts(struct hostkeys_updat } for (i = 0; i < ctx->nold; i++) { if ((fp = sshkey_fingerprint(ctx->old_keys[i], @@ -19,7 +19,7 @@ diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c fatal("%s: sshkey_fingerprint failed", __func__); do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", sshkey_type(ctx->old_keys[i]), fp); -@@ -2330,7 +2330,7 @@ update_known_hosts(struct hostkeys_updat +@@ -1905,7 +1905,7 @@ update_known_hosts(struct hostkeys_updat (r = hostfile_replace_entries(options.user_hostfiles[0], ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, options.hash_known_hosts, 0, @@ -28,7 +28,7 @@ diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c error("%s: hostfile_replace_entries failed: %s", __func__, ssh_err(r)); } -@@ -2443,7 +2443,7 @@ client_input_hostkeys(void) +@@ -2038,7 +2038,7 @@ client_input_hostkeys(void) error("%s: parse key: %s", __func__, ssh_err(r)); goto out; } @@ -37,10 +37,10 @@ diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c SSH_FP_DEFAULT); debug3("%s: received %s key %s", __func__, sshkey_type(key), fp); -diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c ---- openssh-7.4p1/readconf.c.fingerprint 2016-12-23 15:38:50.559432393 +0100 -+++ openssh-7.4p1/readconf.c 2016-12-23 15:38:50.565432394 +0100 -@@ -1668,16 +1668,18 @@ parse_keytypes: +diff -up openssh/readconf.c.fingerprint openssh/readconf.c +--- openssh/readconf.c.fingerprint 2017-09-26 15:21:22.618477921 +0200 ++++ openssh/readconf.c 2017-09-26 15:21:22.621477937 +0200 +@@ -1681,16 +1681,18 @@ parse_keytypes: goto parse_string; case oFingerprintHash: @@ -69,7 +69,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c break; case oUpdateHostkeys: -@@ -1905,7 +1907,7 @@ initialize_options(Options * options) +@@ -1917,7 +1919,7 @@ initialize_options(Options * options) options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; options->revoked_host_keys = NULL; @@ -78,7 +78,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c options->update_hostkeys = -1; options->hostbased_key_types = NULL; options->pubkey_key_types = NULL; -@@ -2102,8 +2104,10 @@ fill_default_options(Options * options) +@@ -2096,8 +2098,10 @@ fill_default_options(Options * options) options->canonicalize_fallback_local = 1; if (options->canonicalize_hostname == -1) options->canonicalize_hostname = SSH_CANONICALISE_NO; @@ -91,7 +91,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c if (options->update_hostkeys == -1) options->update_hostkeys = 0; if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || -@@ -2489,6 +2493,17 @@ dump_cfg_strarray(OpCodes code, u_int co +@@ -2474,6 +2478,17 @@ dump_cfg_strarray(OpCodes code, u_int co } static void @@ -109,7 +109,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) { u_int i; -@@ -2564,7 +2579,6 @@ dump_client_config(Options *o, const cha +@@ -2549,7 +2564,6 @@ dump_client_config(Options *o, const cha dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); @@ -117,7 +117,7 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c dump_cfg_fmtint(oForwardAgent, o->forward_agent); dump_cfg_fmtint(oForwardX11, o->forward_x11); dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); -@@ -2634,6 +2648,7 @@ dump_client_config(Options *o, const cha +@@ -2618,6 +2632,7 @@ dump_client_config(Options *o, const cha dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); @@ -125,9 +125,9 @@ diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c /* Special cases */ -diff -up openssh-7.4p1/readconf.h.fingerprint openssh-7.4p1/readconf.h ---- openssh-7.4p1/readconf.h.fingerprint 2016-12-23 15:38:50.559432393 +0100 -+++ openssh-7.4p1/readconf.h 2016-12-23 15:38:50.565432394 +0100 +diff -up openssh/readconf.h.fingerprint openssh/readconf.h +--- openssh/readconf.h.fingerprint 2017-09-26 15:21:22.618477921 +0200 ++++ openssh/readconf.h 2017-09-26 15:21:22.621477937 +0200 @@ -21,6 +21,7 @@ #define MAX_SEND_ENV 256 #define SSH_MAX_HOSTS_FILES 32 @@ -136,7 +136,7 @@ diff -up openssh-7.4p1/readconf.h.fingerprint openssh-7.4p1/readconf.h #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) struct allowed_cname { -@@ -162,7 +163,8 @@ typedef struct { +@@ -157,7 +158,8 @@ typedef struct { char *revoked_host_keys; @@ -146,10 +146,10 @@ diff -up openssh-7.4p1/readconf.h.fingerprint openssh-7.4p1/readconf.h int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ -diff -up openssh-7.4p1/ssh_config.5.fingerprint openssh-7.4p1/ssh_config.5 ---- openssh-7.4p1/ssh_config.5.fingerprint 2016-12-23 15:38:50.565432394 +0100 -+++ openssh-7.4p1/ssh_config.5 2016-12-23 15:40:03.754444166 +0100 -@@ -652,12 +652,13 @@ or +diff -up openssh/ssh_config.5.fingerprint openssh/ssh_config.5 +--- openssh/ssh_config.5.fingerprint 2017-09-26 15:21:22.618477921 +0200 ++++ openssh/ssh_config.5 2017-09-26 15:21:22.621477937 +0200 +@@ -624,12 +624,13 @@ or .Cm no (the default). .It Cm FingerprintHash @@ -166,10 +166,10 @@ diff -up openssh-7.4p1/ssh_config.5.fingerprint openssh-7.4p1/ssh_config.5 .It Cm ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. -diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c ---- openssh-7.4p1/sshconnect2.c.fingerprint 2016-12-23 15:38:50.561432394 +0100 -+++ openssh-7.4p1/sshconnect2.c 2016-12-23 15:38:50.566432394 +0100 -@@ -677,7 +677,7 @@ input_userauth_pk_ok(int type, u_int32_t +diff -up openssh/sshconnect2.c.fingerprint openssh/sshconnect2.c +--- openssh/sshconnect2.c.fingerprint 2017-09-26 15:21:22.619477926 +0200 ++++ openssh/sshconnect2.c 2017-09-26 15:21:50.677628003 +0200 +@@ -679,7 +679,7 @@ input_userauth_pk_ok(int type, u_int32_t key->type, pktype); goto done; } @@ -178,7 +178,7 @@ diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c SSH_FP_DEFAULT)) == NULL) goto done; debug2("input_userauth_pk_ok: fp %s", fp); -@@ -1172,7 +1172,7 @@ sign_and_send_pubkey(Authctxt *authctxt, +@@ -1198,7 +1198,7 @@ sign_and_send_pubkey(Authctxt *authctxt, int matched, ret = -1, have_sig = 1; char *fp; @@ -187,7 +187,16 @@ diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c SSH_FP_DEFAULT)) == NULL) return 0; debug3("%s: %s %s", __func__, key_type(id->key), fp); -@@ -1864,7 +1864,7 @@ userauth_hostbased(Authctxt *authctxt) +@@ -1620,7 +1620,7 @@ userauth_pubkey(Authctxt *authctxt) + if (id->key != NULL) { + if (try_identity(id)) { + if ((fp = sshkey_fingerprint(id->key, +- options.fingerprint_hash, ++ options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", + __func__); +@@ -1914,7 +1914,7 @@ userauth_hostbased(Authctxt *authctxt) goto out; } @@ -196,10 +205,10 @@ diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c SSH_FP_DEFAULT)) == NULL) { error("%s: sshkey_fingerprint failed", __func__); goto out; -diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c ---- openssh-7.4p1/sshconnect.c.fingerprint 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshconnect.c 2016-12-23 15:38:50.566432394 +0100 -@@ -922,9 +922,9 @@ check_host_key(char *hostname, struct so +diff -up openssh/sshconnect.c.fingerprint openssh/sshconnect.c +--- openssh/sshconnect.c.fingerprint 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/sshconnect.c 2017-09-26 15:21:22.622477943 +0200 +@@ -861,9 +861,9 @@ check_host_key(char *hostname, struct so "of known hosts.", type, ip); } else if (options.visual_host_key) { fp = sshkey_fingerprint(host_key, @@ -211,7 +220,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); logit("Host key fingerprint is %s\n%s", fp, ra); -@@ -966,12 +966,6 @@ check_host_key(char *hostname, struct so +@@ -907,12 +907,6 @@ check_host_key(char *hostname, struct so else snprintf(msg1, sizeof(msg1), "."); /* The default */ @@ -224,7 +233,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c msg2[0] = '\0'; if (options.verify_host_key_dns) { if (matching_host_key_dns) -@@ -985,16 +979,28 @@ check_host_key(char *hostname, struct so +@@ -926,16 +920,28 @@ check_host_key(char *hostname, struct so } snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " @@ -262,7 +271,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c if (!confirm(msg)) goto fail; hostkey_trusted = 1; /* user explicitly confirmed */ -@@ -1244,7 +1250,7 @@ verify_host_key(char *host, struct socka +@@ -1192,7 +1198,7 @@ verify_host_key(char *host, struct socka struct sshkey *plain = NULL; if ((fp = sshkey_fingerprint(host_key, @@ -271,7 +280,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c error("%s: fingerprint host key: %s", __func__, ssh_err(r)); r = -1; goto out; -@@ -1252,7 +1258,7 @@ verify_host_key(char *host, struct socka +@@ -1200,7 +1206,7 @@ verify_host_key(char *host, struct socka if (sshkey_is_cert(host_key)) { if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, @@ -280,7 +289,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c error("%s: fingerprint CA key: %s", __func__, ssh_err(r)); r = -1; -@@ -1432,9 +1438,9 @@ show_other_keys(struct hostkeys *hostkey +@@ -1369,9 +1375,9 @@ show_other_keys(struct hostkeys *hostkey if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) continue; fp = sshkey_fingerprint(found->key, @@ -292,7 +301,7 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); logit("WARNING: %s key found for host %s\n" -@@ -1457,7 +1463,7 @@ warn_changed_key(Key *host_key) +@@ -1394,7 +1400,7 @@ warn_changed_key(struct sshkey *host_key { char *fp; @@ -301,9 +310,9 @@ diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c SSH_FP_DEFAULT); if (fp == NULL) fatal("%s: sshkey_fingerprint fail", __func__); -diff -up openssh-7.4p1/ssh-keysign.c.fingerprint openssh-7.4p1/ssh-keysign.c ---- openssh-7.4p1/ssh-keysign.c.fingerprint 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-keysign.c 2016-12-23 15:38:50.566432394 +0100 +diff -up openssh/ssh-keysign.c.fingerprint openssh/ssh-keysign.c +--- openssh/ssh-keysign.c.fingerprint 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/ssh-keysign.c 2017-09-26 15:21:22.622477943 +0200 @@ -285,7 +285,7 @@ main(int argc, char **argv) } } diff --git a/openssh-7.1p2-audit-race-condition.patch b/openssh-7.1p2-audit-race-condition.patch index 035f0ac..ec274eb 100644 --- a/openssh-7.1p2-audit-race-condition.patch +++ b/openssh-7.1p2-audit-race-condition.patch @@ -92,7 +92,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c + child_destory_sensitive_data(); + /* Do processing for the child (exec command etc). */ - do_child(s, command); + do_child(ssh, s, command); /* NOTREACHED */ @@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm /* Close the extra descriptor for the pseudo tty. */ @@ -112,7 +112,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c + fatal("pipe: %s", strerror(errno)); #endif if (s->ttyfd != -1) - ret = do_exec_pty(s, command); + ret = do_exec_pty(ssh, s, command); @@ -732,6 +745,20 @@ do_exec(Session *s, const char *command) */ buffer_clear(&loginmsg); @@ -134,7 +134,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c return ret; } -@@ -1538,6 +1565,33 @@ child_close_fds(void) +@@ -1538,6 +1565,34 @@ child_close_fds(void) endpwent(); } @@ -157,23 +157,25 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c + * which we can't do using one-way pipe. + */ + packet_destroy_all(0, 1); ++ /* XXX this will clean the rest but should not audit anymore */ ++ /* packet_clear_keys(); */ + +#ifdef SSH_AUDIT_EVENTS + /* Notify parent that we are done */ + close(pparent); +#endif -+ +} + /* * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group -@@ -1554,12 +1608,6 @@ do_child(Session *s, const char *command +@@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command struct passwd *pw = s->pw; int r = 0; - /* remove hostkey from the child's memory */ - destroy_sensitive_data(1); +- packet_clear_keys(); - /* 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); diff --git a/openssh-7.2p1-audit.patch b/openssh-7.2p1-audit.patch deleted file mode 100644 index 3888a23..0000000 --- a/openssh-7.2p1-audit.patch +++ /dev/null @@ -1,2168 +0,0 @@ -diff -up openssh-7.4p1/audit-bsm.c.audit openssh-7.4p1/audit-bsm.c ---- openssh-7.4p1/audit-bsm.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/audit-bsm.c 2016-12-23 18:54:54.433080419 +0100 -@@ -373,10 +373,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 -@@ -391,6 +404,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) - { -@@ -452,4 +471,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-7.4p1/audit.c.audit openssh-7.4p1/audit.c ---- openssh-7.4p1/audit.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/audit.c 2016-12-23 18:54:54.433080419 +0100 -@@ -26,6 +26,7 @@ - - #include - #include -+#include - - #ifdef SSH_AUDIT_EVENTS - -@@ -34,6 +35,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 -@@ -41,6 +47,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 -@@ -69,13 +76,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); - } - -@@ -109,6 +113,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. -@@ -138,6 +176,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. - * -@@ -172,13 +221,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, result %d", -+ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits, -+ 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-7.4p1/audit.h.audit openssh-7.4p1/audit.h ---- openssh-7.4p1/audit.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/audit.h 2016-12-23 18:54:54.433080419 +0100 -@@ -26,6 +26,7 @@ - # define _SSH_AUDIT_H - - #include "loginrec.h" -+#include "key.h" - - enum ssh_audit_event_type { - SSH_LOGIN_EXCEED_MAXTRIES, -@@ -43,13 +44,33 @@ enum ssh_audit_event_type { - SSH_CONNECTION_ABANDON, /* closed without completing auth */ - SSH_AUDIT_UNKNOWN - }; -+ -+enum ssh_audit_kex { -+ SSH_AUDIT_UNSUPPORTED_CIPHER, -+ SSH_AUDIT_UNSUPPORTED_MAC, -+ SSH_AUDIT_UNSUPPORTED_COMPRESSION -+}; - 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-7.4p1/audit-linux.c.audit openssh-7.4p1/audit-linux.c ---- openssh-7.4p1/audit-linux.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/audit-linux.c 2016-12-23 18:54:54.434080419 +0100 -@@ -33,25 +33,38 @@ - - #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" -+#include "channels.h" -+#include "session.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; - - if ((audit_fd = audit_open()) < 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,9 +78,97 @@ linux_audit_record_event(int uid, const - 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", ssh_remote_port(active_state)); -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, -+ buf, audit_username(), -1, NULL, ssh_remote_ipaddr(active_state), NULL, rv); -+ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) -+ goto out; -+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", -+ type, bits, fp, ssh_remote_port(active_state)); -+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, -+ buf, audit_username(), -1, NULL, ssh_remote_ipaddr(active_state), 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 -@@ -76,24 +177,51 @@ audit_connection_from(const char *host, - /* 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, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), -+ NULL, "ssh", 1, AUDIT_USER_LOGIN); -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, 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, session_get_remote_name_or_ip(active_state, 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, session_get_remote_name_or_ip(active_state, 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 -@@ -103,24 +231,180 @@ 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, -+ ssh_remote_ipaddr(ssh), "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, -+ ssh_remote_ipaddr(ssh), "ssh", 0, event); -+ linux_audit_user_logxxx(-1, audit_username(), NULL, -+ ssh_remote_ipaddr(ssh), "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, -+ ssh_remote_ipaddr(ssh), "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, -+ session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), -+ NULL, "ssh", 1, AUDIT_USER_END); -+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, -+ session_get_remote_name_or_ip(ssh, 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, -- ssh_remote_ipaddr(ssh), "sshd", 0); -+ linux_audit_user_logxxx(-1, audit_username(), NULL, -+ ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); - break; - default: - debug("%s: unhandled event %d", __func__, event); - break; - } - } -+ -+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], ssh_remote_port(active_state), (s = get_local_ipaddr(packet_get_connection_in())), -+ ssh_local_port(active_state)); -+ 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, ssh_remote_ipaddr(active_state), 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 struct sshcipher *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, -+ ssh_remote_port(active_state), (s = get_local_ipaddr(packet_get_connection_in())), ssh_local_port(active_state)); -+ 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, ssh_remote_ipaddr(active_state), 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, -+ ssh_remote_port(active_state), -+ (s = get_local_ipaddr(packet_get_connection_in())), -+ ssh_local_port(active_state)); -+ 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, ssh_remote_ipaddr(active_state), 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() ? NULL : ssh_remote_ipaddr(active_state), -+ 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-7.4p1/auditstub.c.audit openssh-7.4p1/auditstub.c ---- openssh-7.4p1/auditstub.c.audit 2016-12-23 18:54:54.434080419 +0100 -+++ openssh-7.4p1/auditstub.c 2016-12-23 18:54:54.434080419 +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 -+ */ -+ -+#include -+ -+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-7.4p1/auth2.c.audit openssh-7.4p1/auth2.c ---- openssh-7.4p1/auth2.c.audit 2016-12-23 18:54:54.422080416 +0100 -+++ openssh-7.4p1/auth2.c 2016-12-23 18:54:54.434080419 +0100 -@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 - } else { - /* Invalid user, fake password information */ - authctxt->pw = fakepw(); --#ifdef SSH_AUDIT_EVENTS -- PRIVSEP(audit_event(SSH_INVALID_USER)); --#endif - } - #ifdef USE_PAM - if (options.use_pam) -diff -up openssh-7.4p1/auth2-hostbased.c.audit openssh-7.4p1/auth2-hostbased.c ---- openssh-7.4p1/auth2-hostbased.c.audit 2016-12-23 18:54:54.422080416 +0100 -+++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 18:54:54.434080419 +0100 -@@ -148,7 +148,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; - authctxt->last_details = pubkey; -@@ -169,6 +169,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-7.4p1/auth2-pubkey.c.audit openssh-7.4p1/auth2-pubkey.c ---- openssh-7.4p1/auth2-pubkey.c.audit 2016-12-23 18:54:54.423080416 +0100 -+++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 18:54:54.435080419 +0100 -@@ -183,7 +183,7 @@ userauth_pubkey(Authctxt *authctxt) - /* test for correct signature */ - authenticated = 0; - if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && -- 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; - authctxt->last_details = pubkey; -@@ -252,6 +252,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; -+} -+ - /* - * Splits 's' into an argument vector. Handles quoted string and basic - * escape characters (\\, \", \'). Caller must free the argument vector -diff -up openssh-7.4p1/auth.c.audit openssh-7.4p1/auth.c ---- openssh-7.4p1/auth.c.audit 2016-12-23 18:54:54.373080404 +0100 -+++ openssh-7.4p1/auth.c 2016-12-23 18:54:54.435080419 +0100 -@@ -666,9 +666,6 @@ getpwnamallow(const char *user) - record_failed_login(user, - auth_get_canonical_hostname(ssh, 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-7.4p1/auth.h.audit openssh-7.4p1/auth.h ---- openssh-7.4p1/auth.h.audit 2016-12-23 18:54:54.423080416 +0100 -+++ openssh-7.4p1/auth.h 2016-12-23 18:54:54.435080419 +0100 -@@ -185,6 +185,7 @@ struct passwd * getpwnamallow(const char - - 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); -@@ -204,6 +205,7 @@ Key *get_hostkey_private_by_type(int, in - int get_hostkey_index(Key *, int, struct ssh *); - int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, - const u_char *, size_t, const char *, 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-7.4p1/cipher.c.audit openssh-7.4p1/cipher.c ---- openssh-7.4p1/cipher.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/cipher.c 2016-12-23 18:54:54.435080419 +0100 -@@ -66,26 +66,6 @@ struct sshcipher_ctx { - const struct sshcipher *cipher; - }; - --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-7.4p1/cipher.h.audit openssh-7.4p1/cipher.h ---- openssh-7.4p1/cipher.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/cipher.h 2016-12-23 18:54:54.436080419 +0100 -@@ -62,7 +62,25 @@ - #define CIPHER_ENCRYPT 1 - #define CIPHER_DECRYPT 0 - --struct sshcipher; -+struct sshcipher { /* from cipher.c */ -+ 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; - - u_int cipher_mask_ssh1(int); -diff -up openssh-7.4p1/kex.c.audit openssh-7.4p1/kex.c ---- openssh-7.4p1/kex.c.audit 2016-12-23 18:54:54.410080413 +0100 -+++ openssh-7.4p1/kex.c 2016-12-23 18:54:54.436080419 +0100 -@@ -54,6 +54,7 @@ - #include "ssherr.h" - #include "sshbuf.h" - #include "digest.h" -+#include "audit.h" - - #ifdef GSSAPI - #include "ssh-gss.h" -@@ -683,8 +684,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(SSH_AUDIT_UNSUPPORTED_CIPHER); -+#endif - return SSH_ERR_NO_CIPHER_ALG_MATCH; -+ } - if ((enc->cipher = cipher_by_name(name)) == NULL) { - free(name); - return SSH_ERR_INTERNAL_ERROR; -@@ -702,8 +707,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(SSH_AUDIT_UNSUPPORTED_MAC); -+#endif - return SSH_ERR_NO_MAC_ALG_MATCH; -+ } - if (mac_setup(mac, name) < 0) { - free(name); - return SSH_ERR_INTERNAL_ERROR; -@@ -720,8 +729,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(SSH_AUDIT_UNSUPPORTED_COMPRESSION); -+#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) { -@@ -890,6 +903,10 @@ kex_choose_conf(struct ssh *ssh) - dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); - dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); - dh_need = MAXIMUM(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; -@@ -1064,3 +1081,33 @@ 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->iv_len); -+ 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-7.4p1/kex.h.audit openssh-7.4p1/kex.h ---- openssh-7.4p1/kex.h.audit 2016-12-23 18:54:54.410080413 +0100 -+++ openssh-7.4p1/kex.h 2016-12-23 18:54:54.436080419 +0100 -@@ -213,6 +213,8 @@ int kexgss_client(struct ssh *); - int kexgss_server(struct ssh *); - #endif - -+void newkeys_destroy(struct newkeys *newkeys); -+ - int kex_dh_hash(int, 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-7.4p1/key.h.audit openssh-7.4p1/key.h ---- openssh-7.4p1/key.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/key.h 2016-12-23 18:54:54.436080419 +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_curve_name_to_nid sshkey_curve_name_to_nid - #define key_curve_nid_to_bits sshkey_curve_nid_to_bits -diff -up openssh-7.4p1/mac.c.audit openssh-7.4p1/mac.c ---- openssh-7.4p1/mac.c.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/mac.c 2016-12-23 18:54:54.436080419 +0100 -@@ -249,6 +249,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-7.4p1/mac.h.audit openssh-7.4p1/mac.h ---- openssh-7.4p1/mac.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/mac.h 2016-12-23 18:54:54.436080419 +0100 -@@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 - int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, - const u_char *, size_t); - void mac_clear(struct sshmac *); -+void mac_destroy(struct sshmac *); - - #endif /* SSHMAC_H */ -diff -up openssh-7.4p1/Makefile.in.audit openssh-7.4p1/Makefile.in ---- openssh-7.4p1/Makefile.in.audit 2016-12-23 18:54:54.375080404 +0100 -+++ openssh-7.4p1/Makefile.in 2016-12-23 18:54:54.436080419 +0100 -@@ -100,7 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - 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 \ -- platform-pledge.o platform-tracing.o -+ platform-pledge.o platform-tracing.o auditstub.o - - SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o mux.o -diff -up openssh-7.4p1/monitor.c.audit openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.audit 2016-12-23 18:54:54.423080416 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 18:54:54.437080420 +0100 -@@ -102,6 +102,7 @@ - #include "compat.h" - #include "ssh2.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 *); -@@ -222,6 +230,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}, -@@ -260,6 +272,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} - }; -@@ -1396,9 +1413,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); -@@ -1406,6 +1425,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) -@@ -1426,7 +1447,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"); - -@@ -1489,6 +1520,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); - } - -@@ -1591,6 +1628,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); -@@ -1633,11 +1672,45 @@ 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; -+#ifdef SSH_AUDIT_EVENTS -+ s->command_handle = audit_run_command(cmd); -+#endif -+ -+ 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); - } -@@ -1690,6 +1763,7 @@ monitor_apply_keystate(struct monitor *p - void - mm_get_keystate(struct monitor *pmonitor) - { -+ Buffer m; - debug3("%s: Waiting for new keys", __func__); - - if ((child_state = sshbuf_new()) == NULL) -@@ -1697,6 +1771,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) -+ ; -+ - } - - -@@ -1953,3 +2042,86 @@ 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); -+ -+ return 0; -+} -+#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.4p1/monitor.h.audit openssh-7.4p1/monitor.h ---- openssh-7.4p1/monitor.h.audit 2016-12-23 18:54:54.393080409 +0100 -+++ openssh-7.4p1/monitor.h 2016-12-23 18:54:54.437080420 +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 - - }; - -diff -up openssh-7.4p1/monitor_wrap.c.audit openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.audit 2016-12-23 18:54:54.376080405 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 18:54:54.437080420 +0100 -@@ -453,7 +453,7 @@ mm_key_allowed(enum mm_keytype type, con - */ - - 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; -@@ -467,6 +467,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); -@@ -484,6 +485,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) - { -@@ -861,10 +874,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); - -@@ -872,6 +886,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 */ -@@ -1007,3 +1041,70 @@ 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); -+ buffer_free(&m); -+} -+#endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-7.4p1/monitor_wrap.h.audit openssh-7.4p1/monitor_wrap.h ---- openssh-7.4p1/monitor_wrap.h.audit 2016-12-23 18:54:54.376080405 +0100 -+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 18:54:54.437080420 +0100 -@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, cons - int mm_user_key_allowed(struct passwd *, Key *, int); - int mm_hostbased_key_allowed(struct passwd *, const char *, - const 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); - - #ifdef GSSAPI - OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); -@@ -76,7 +77,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-7.4p1/packet.c.audit openssh-7.4p1/packet.c ---- openssh-7.4p1/packet.c.audit 2016-12-23 18:54:54.318080390 +0100 -+++ openssh-7.4p1/packet.c 2016-12-23 18:54:54.438080420 +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" -@@ -494,6 +495,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. -@@ -562,13 +570,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); -@@ -600,11 +601,21 @@ ssh_packet_close(struct ssh *ssh) - inflateEnd(stream); - } - } -- cipher_free(state->send_context); -- cipher_free(state->receive_context); -+ if (packet_state_has_keys(state)) { -+ cipher_free(state->send_context); -+ cipher_free(state->receive_context); -+ audit_session_key_free(MODE_MAX); -+ } - state->send_context = state->receive_context = NULL; - 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; - } -@@ -950,6 +961,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod - " (%llu bytes total)", __func__, - (unsigned long long)ps->blocks, dir, - (unsigned long long)ps->bytes); -+ audit_session_key_free(mode); - cipher_free(*ccp); - *ccp = NULL; - enc = &state->newkeys[mode]->enc; -@@ -2440,6 +2452,72 @@ 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_free(state->receive_context); -+ cipher_free(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)); -+ if (active_state != NULL) -+ packet_destroy_state(active_state->state); -+ if (audit_it) { -+#ifdef SSH_AUDIT_EVENTS -+ if (privsep) -+ audit_session_key_free(MODE_MAX); -+ else -+ audit_session_key_free_body(MODE_MAX, getpid(), getuid()); -+#endif -+ } -+} -+ - /* Reset after_authentication and reset compression in post-auth privsep */ - static int - ssh_packet_set_postauth(struct ssh *ssh) -diff -up openssh-7.4p1/packet.h.audit openssh-7.4p1/packet.h ---- openssh-7.4p1/packet.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/packet.h 2016-12-23 18:54:54.438080420 +0100 -@@ -208,4 +208,5 @@ extern struct ssh *active_state; - # undef EC_POINT - #endif - -+void packet_destroy_all(int, int); - #endif /* PACKET_H */ -diff -up openssh-7.4p1/session.c.audit openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.audit 2016-12-23 18:54:54.430080418 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 18:57:45.068115466 +0100 -@@ -142,7 +142,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. */ -@@ -576,6 +576,14 @@ do_exec_pty(Session *s, const char *comm - /* Parent. Close the slave side of the pseudo tty. */ - close(ttyfd); - -+#if !defined(HAVE_OSF_SIA) && defined(SSH_AUDIT_EVENTS) -+ /* do_login in the child did not affect state in this process, -+ compensate. From an architectural standpoint, this is extremely -+ ugly. */ -+ if (command != NULL) -+ audit_count_session_open(); -+#endif -+ - /* Enter interactive session. */ - s->ptymaster = ptymaster; - packet_set_interactive(1, -@@ -696,15 +704,19 @@ do_exec(Session *s, const char *command) - s->self); - - #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); -@@ -1543,7 +1555,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) { -@@ -1757,6 +1772,9 @@ session_unused(int id) - sessions[id].ttyfd = -1; - sessions[id].ptymaster = -1; - sessions[id].x11_chanids = NULL; -+#ifdef SSH_AUDIT_EVENTS -+ sessions[id].command_handle = -1; -+#endif - sessions[id].next_unused = sessions_first_unused; - sessions_first_unused = id; - } -@@ -1839,6 +1857,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("%s: unknown id %d", __func__, id); -+ session_dump(); -+ return NULL; -+} -+ -+Session * - session_by_tty(char *tty) - { - int i; -@@ -2351,6 +2382,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) - { -@@ -2365,6 +2422,10 @@ session_close(Session *s) - - 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); -@@ -2575,6 +2636,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) - { -@@ -2626,7 +2696,7 @@ 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); - } - - /* Return a name for the remote host that fits inside utmp_size */ -diff -up openssh-7.4p1/session.h.audit openssh-7.4p1/session.h ---- openssh-7.4p1/session.h.audit 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/session.h 2016-12-23 18:54:54.438080420 +0100 -@@ -60,6 +60,12 @@ struct Session { - char *name; - char *val; - } *env; -+ -+ /* exec */ -+#ifdef SSH_AUDIT_EVENTS -+ int command_handle; -+ char *command; -+#endif - }; - - void do_authenticated(Authctxt *); -@@ -72,8 +78,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-7.4p1/sshd.c.audit openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.audit 2016-12-23 18:54:54.403080411 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 18:56:18.992101105 +0100 -@@ -119,6 +119,7 @@ - #include "ssh-gss.h" - #endif - #include "monitor_wrap.h" -+#include "audit.h" - #include "ssh-sandbox.h" - #include "version.h" - #include "ssherr.h" -@@ -244,7 +245,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); - static void do_ssh2_kex(void); - -@@ -261,6 +262,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) - { -@@ -473,18 +483,45 @@ sshd_exchange_identification(struct ssh - } - } - --/* 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; -+#ifdef SSH_AUDIT_EVENTS -+ pid_t pid; -+ uid_t uid; - -+ pid = getpid(); -+ uid = getuid(); -+#endif - 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) { -+#ifdef SSH_AUDIT_EVENTS -+ if (privsep) -+ PRIVSEP(audit_destroy_sensitive_data(fp, -+ pid, uid)); -+ else -+ audit_destroy_sensitive_data(fp, -+ pid, uid); -+#endif -+ 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; - } -@@ -497,12 +534,30 @@ demote_sensitive_data(void) - { - Key *tmp; - int i; -+#ifdef SSH_AUDIT_EVENTS -+ pid_t pid; -+ uid_t uid; - -+ pid = getpid(); -+ uid = getuid(); -+#endif - 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 (fp != NULL) { -+#ifdef SSH_AUDIT_EVENTS -+ audit_destroy_sensitive_data(fp, pid, uid); -+#endif -+ free(fp); -+ } - } - /* Certs do not need demotion */ - } -@@ -585,7 +640,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) { -@@ -665,6 +720,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 */ -@@ -1154,6 +1215,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); -@@ -2092,6 +2150,7 @@ main(int ac, char **av) - */ - if (use_privsep) { - mm_send_keystate(pmonitor); -+ packet_destroy_all(1, 1); - exit(0); - } - -@@ -2148,6 +2207,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); -@@ -2321,6 +2383,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 && -@@ -2332,9 +2404,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-7.4p1/sshkey.c.audit openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.audit 2016-12-23 18:54:54.425080417 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 18:54:54.439080420 +0100 -@@ -303,6 +303,33 @@ sshkey_type_is_valid_ca(int type) - } - - int -+sshkey_is_private(const struct sshkey *k) -+{ -+ switch (k->type) { -+#ifdef WITH_OPENSSL -+ case KEY_RSA_CERT: -+ case KEY_RSA1: -+ case KEY_RSA: -+ return k->rsa->d != NULL; -+ 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 /* OPENSSL_HAS_ECC */ -+#endif /* WITH_OPENSSL */ -+ 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-7.4p1/sshkey.h.audit openssh-7.4p1/sshkey.h ---- openssh-7.4p1/sshkey.h.audit 2016-12-23 18:54:54.425080417 +0100 -+++ openssh-7.4p1/sshkey.h 2016-12-23 18:54:54.439080420 +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 --git a/openssh-7.2p1-fips.patch b/openssh-7.2p1-fips.patch index e1bafa6..54616f5 100644 --- a/openssh-7.2p1-fips.patch +++ b/openssh-7.2p1-fips.patch @@ -10,22 +10,29 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c #include #include #include -@@ -116,6 +118,20 @@ static const struct sshcipher ciphers[] - { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } +@@ -116,6 +118,27 @@ static const struct sshcipher ciphers[] + { NULL, 0, 0, 0, 0, 0, NULL } }; +static const struct sshcipher fips_ciphers[] = { -+ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, -+ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, -+ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, -+ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, -+ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, ++#ifdef WITH_OPENSSL ++ { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, ++ { "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc }, ++ { "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc }, ++ { "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc }, + { "rijndael-cbc@lysator.liu.se", -+ SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, -+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, -+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, -+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, -+ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } ++ 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc }, ++ { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr }, ++ { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr }, ++ { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr }, ++#else ++ { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL }, ++ { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL }, ++ { "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL }, ++#endif ++ { "none", 8, 0, 0, 0, CFLAG_NONE, NULL }, ++ ++ { NULL, 0, 0, 0, 0, 0, NULL } +}; + /*--*/ @@ -37,7 +44,7 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c - for (c = ciphers; c->name != NULL; c++) { + for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) { - if (c->number != SSH_CIPHER_SSH2) + if ((c->flags & CFLAG_INTERNAL) != 0) continue; if (auth_only && c->auth_len == 0) @@ -222,7 +238,7 @@ const struct sshcipher * @@ -49,24 +56,6 @@ diff -up openssh-7.5p1/cipher.c.fips openssh-7.5p1/cipher.c if (strcmp(c->name, name) == 0) return c; return NULL; -@@ -232,7 +248,7 @@ const struct sshcipher * - cipher_by_number(int id) - { - const struct sshcipher *c; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (c->number == id) - return c; - return NULL; -@@ -273,7 +289,7 @@ cipher_number(const char *name) - const struct sshcipher *c; - if (name == NULL) - return -1; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (strcasecmp(c->name, name) == 0) - return c->number; - return -1; diff -up openssh-7.5p1/cipher-ctr.c.fips openssh-7.5p1/cipher-ctr.c --- openssh-7.5p1/cipher-ctr.c.fips 2017-06-30 12:06:36.386713974 +0200 +++ openssh-7.5p1/cipher-ctr.c 2017-06-30 12:06:36.465713761 +0200 @@ -394,7 +383,7 @@ diff -up openssh-7.5p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.fips op + fp = sshkey_fingerprint(found, FIPS_mode() ? SSH_DIGEST_SHA1 : SSH_DIGEST_MD5, + SSH_FP_HEX); logit("Found matching %s key: %s", - key_type(found), fp); + sshkey_type(found), fp); free(fp); diff -up openssh-7.5p1/readconf.c.fips openssh-7.5p1/readconf.c --- openssh-7.5p1/readconf.c.fips 2017-06-30 12:06:36.468713753 +0200 @@ -492,16 +481,6 @@ diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ -@@ -609,6 +619,9 @@ main(int ac, char **av) - "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { - switch (opt) { - case '1': -+ if (FIPS_mode()) { -+ fatal("Protocol 1 not allowed in the FIPS mode."); -+ } - options.protocol = SSH_PROTO_1; - break; - case '2': @@ -964,7 +977,6 @@ main(int ac, char **av) host_arg = xstrdup(host); @@ -521,19 +500,6 @@ diff -up openssh-7.5p1/ssh.c.fips openssh-7.5p1/ssh.c if (options.user == NULL) options.user = xstrdup(pw->pw_name); -@@ -1263,6 +1279,12 @@ main(int ac, char **av) - - timeout_ms = options.connection_timeout * 1000; - -+ if (FIPS_mode()) { -+ options.protocol &= SSH_PROTO_2; -+ if (options.protocol == 0) -+ fatal("Protocol 2 disabled by configuration but required in the FIPS mode."); -+ } -+ - /* Open a connection to the remote host. */ - if (ssh_connect(host, addrs, &hostaddr, options.port, - options.address_family, options.connection_attempts, diff -up openssh-7.5p1/sshconnect2.c.fips openssh-7.5p1/sshconnect2.c --- openssh-7.5p1/sshconnect2.c.fips 2017-06-30 12:06:36.439713831 +0200 +++ openssh-7.5p1/sshconnect2.c 2017-06-30 12:06:36.469713750 +0200 @@ -707,9 +673,9 @@ diff -up openssh-7.5p1/sshkey.c.fips openssh-7.5p1/sshkey.c #include "crypto_api.h" @@ -58,6 +59,7 @@ + #define SSHKEY_INTERNAL #include "sshkey.h" #include "match.h" - #include "xmalloc.h" +#include "log.h" /* openssh private key file format */ @@ -736,6 +702,6 @@ diff -up openssh-7.5p1/ssh-keygen.c.fips openssh-7.5p1/ssh-keygen.c + if (type == KEY_ED25519) + fatal("ED25519 keys are not allowed in FIPS mode"); + } - if (type == KEY_DSA && *bitsp != 1024) - fatal("DSA keys must be 1024 bits"); - else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024) + switch (type) { + case KEY_DSA: + if (*bitsp != 1024) diff --git a/openssh-7.2p1-gsskex.patch b/openssh-7.2p1-gsskex.patch index 0b7c186..8c0523b 100644 --- a/openssh-7.2p1-gsskex.patch +++ b/openssh-7.2p1-gsskex.patch @@ -1,7 +1,7 @@ -diff -up openssh-7.4p1/auth2.c.gsskex openssh-7.4p1/auth2.c ---- openssh-7.4p1/auth2.c.gsskex 2016-12-23 13:38:53.685300997 +0100 -+++ openssh-7.4p1/auth2.c 2016-12-23 13:38:53.725301005 +0100 -@@ -70,6 +70,7 @@ extern Authmethod method_passwd; +diff -up openssh/auth2.c.gsskex openssh/auth2.c +--- openssh/auth2.c.gsskex 2017-09-27 13:54:53.539534068 +0200 ++++ openssh/auth2.c 2017-09-27 13:54:53.590534348 +0200 +@@ -72,6 +72,7 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI @@ -9,7 +9,7 @@ diff -up openssh-7.4p1/auth2.c.gsskex openssh-7.4p1/auth2.c extern Authmethod method_gssapi; #endif -@@ -77,6 +78,7 @@ Authmethod *authmethods[] = { +@@ -79,6 +80,7 @@ Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI @@ -17,9 +17,9 @@ diff -up openssh-7.4p1/auth2.c.gsskex openssh-7.4p1/auth2.c &method_gssapi, #endif &method_passwd, -diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c ---- openssh-7.4p1/auth2-gss.c.gsskex 2016-12-23 13:38:53.685300997 +0100 -+++ openssh-7.4p1/auth2-gss.c 2016-12-23 13:38:53.725301005 +0100 +diff -up openssh/auth2-gss.c.gsskex openssh/auth2-gss.c +--- openssh/auth2-gss.c.gsskex 2017-09-27 13:54:53.539534068 +0200 ++++ openssh/auth2-gss.c 2017-09-27 13:54:53.590534348 +0200 @@ -31,6 +31,7 @@ #include @@ -28,16 +28,17 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c #include "xmalloc.h" #include "key.h" -@@ -53,6 +54,40 @@ static int input_gssapi_mic(int type, u_ - static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); - static int input_gssapi_errtok(int, u_int32_t, void *); +@@ -53,6 +54,41 @@ static int input_gssapi_mic(int type, u_ + static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); + static int input_gssapi_errtok(int, u_int32_t, struct ssh *); +/* + * The 'gssapi_keyex' userauth mechanism. + */ +static int -+userauth_gsskeyex(Authctxt *authctxt) ++userauth_gsskeyex(struct ssh *ssh) +{ ++ Authctxt *authctxt = ssh->authctxt; + int authenticated = 0; + Buffer b; + gss_buffer_desc mic, gssbuf; @@ -69,7 +70,7 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -238,7 +273,8 @@ input_gssapi_exchange_complete(int type, +@@ -240,7 +275,8 @@ input_gssapi_exchange_complete(int type, packet_check_eom(); @@ -77,9 +78,9 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, + authctxt->pw)); - authctxt->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -281,7 +317,8 @@ input_gssapi_mic(int type, u_int32_t ple + if ((!use_privsep || mm_is_monitor()) && + (displayname = ssh_gssapi_displayname()) != NULL) +@@ -288,7 +324,8 @@ input_gssapi_mic(int type, u_int32_t ple gssbuf.length = buffer_len(&b); if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) @@ -89,7 +90,7 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c else logit("GSSAPI MIC check failed"); -@@ -299,6 +336,12 @@ input_gssapi_mic(int type, u_int32_t ple +@@ -310,6 +347,12 @@ input_gssapi_mic(int type, u_int32_t ple return 0; } @@ -102,10 +103,21 @@ diff -up openssh-7.4p1/auth2-gss.c.gsskex openssh-7.4p1/auth2-gss.c Authmethod method_gssapi = { "gssapi-with-mic", userauth_gssapi, -diff -up openssh-7.4p1/clientloop.c.gsskex openssh-7.4p1/clientloop.c ---- openssh-7.4p1/clientloop.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/clientloop.c 2016-12-23 13:38:53.725301005 +0100 -@@ -113,6 +113,10 @@ +diff -up openssh/auth.c.gsskex openssh/auth.c +--- openssh/auth.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/auth.c 2017-09-27 13:54:53.591534353 +0200 +@@ -395,6 +395,7 @@ auth_root_allowed(const char *method) + case PERMIT_NO_PASSWD: + if (strcmp(method, "publickey") == 0 || + strcmp(method, "hostbased") == 0 || ++ strcmp(method, "gssapi-keyex") == 0 || + strcmp(method, "gssapi-with-mic") == 0) + return 1; + break; +diff -up openssh/clientloop.c.gsskex openssh/clientloop.c +--- openssh/clientloop.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/clientloop.c 2017-09-27 13:54:53.591534353 +0200 +@@ -112,6 +112,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -116,13 +128,13 @@ diff -up openssh-7.4p1/clientloop.c.gsskex openssh-7.4p1/clientloop.c /* import options */ extern Options options; -@@ -1664,9 +1668,18 @@ client_loop(int have_pty, int escape_cha +@@ -1349,9 +1353,18 @@ client_loop(struct ssh *ssh, int have_pt break; /* Do channel operations unless rekeying in progress. */ -- if (!ssh_packet_is_rekeying(active_state)) -+ if (!ssh_packet_is_rekeying(active_state)) { - channel_after_select(readset, writeset); +- if (!ssh_packet_is_rekeying(ssh)) ++ if (!ssh_packet_is_rekeying(ssh)) { + channel_after_select(ssh, readset, writeset); +#ifdef GSSAPI + if (options.gss_renewal_rekey && @@ -136,10 +148,10 @@ diff -up openssh-7.4p1/clientloop.c.gsskex openssh-7.4p1/clientloop.c /* Buffer input from the connection. */ client_process_net_input(readset); -diff -up openssh-7.4p1/configure.ac.gsskex openssh-7.4p1/configure.ac ---- openssh-7.4p1/configure.ac.gsskex 2016-12-23 13:38:53.716301003 +0100 -+++ openssh-7.4p1/configure.ac 2016-12-23 13:38:53.726301005 +0100 -@@ -623,6 +623,30 @@ main() { if (NSVersionOfRunTimeLibrary(" +diff -up openssh/configure.ac.gsskex openssh/configure.ac +--- openssh/configure.ac.gsskex 2017-09-27 13:54:53.581534298 +0200 ++++ openssh/configure.ac 2017-09-27 13:54:53.592534359 +0200 +@@ -621,6 +621,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -170,9 +182,9 @@ diff -up openssh-7.4p1/configure.ac.gsskex openssh-7.4p1/configure.ac m4_pattern_allow([AU_IPv]) AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) -diff -up openssh-7.4p1/gss-genr.c.gsskex openssh-7.4p1/gss-genr.c ---- openssh-7.4p1/gss-genr.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/gss-genr.c 2016-12-23 13:38:53.726301005 +0100 +diff -up openssh/gss-genr.c.gsskex openssh/gss-genr.c +--- openssh/gss-genr.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/gss-genr.c 2017-09-27 13:54:53.592534359 +0200 @@ -40,12 +40,167 @@ #include "buffer.h" #include "log.h" @@ -510,9 +522,9 @@ diff -up openssh-7.4p1/gss-genr.c.gsskex openssh-7.4p1/gss-genr.c +} + #endif /* GSSAPI */ -diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c ---- openssh-7.4p1/gss-serv.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/gss-serv.c 2016-12-23 13:38:53.727301005 +0100 +diff -up openssh/gss-serv.c.gsskex openssh/gss-serv.c +--- openssh/gss-serv.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/gss-serv.c 2017-09-27 13:54:53.592534359 +0200 @@ -45,17 +45,19 @@ #include "session.h" #include "misc.h" @@ -565,7 +577,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c void ssh_gssapi_supported_oids(gss_OID_set *oidset) { -@@ -151,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o +@@ -151,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *o gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -576,7 +588,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -277,8 +304,48 @@ OM_uint32 +@@ -277,8 +303,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; @@ -598,8 +610,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c + ssh_gssapi_error(ctx); + return (ctx->major); + } - -- gss_buffer_desc ename; ++ + ctx->major = gss_compare_name(&ctx->minor, client->name, + new_name, &equal); + @@ -614,7 +625,8 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c + } + + debug("Marking rekeyed credentials for export"); -+ + +- gss_buffer_desc ename; + gss_release_name(&ctx->minor, &client->name); + gss_release_cred(&ctx->minor, &client->creds); + client->name = new_name; @@ -626,7 +638,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c client->mech = NULL; -@@ -293,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -293,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g if (client->mech == NULL) return GSS_S_FAILURE; @@ -640,7 +652,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -310,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -310,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g return (ctx->major); } @@ -649,7 +661,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -320,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g +@@ -320,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_g void ssh_gssapi_cleanup_creds(void) { @@ -675,7 +687,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c } } -@@ -357,7 +442,7 @@ ssh_gssapi_do_child(char ***envp, u_int +@@ -357,7 +441,7 @@ ssh_gssapi_do_child(char ***envp, u_int /* Privileged */ int @@ -684,7 +696,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c { OM_uint32 lmin; -@@ -367,9 +452,11 @@ ssh_gssapi_userok(char *user) +@@ -367,9 +451,11 @@ ssh_gssapi_userok(char *user) return 0; } if (gssapi_client.mech && gssapi_client.mech->userok) @@ -698,7 +710,7 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -383,14 +470,90 @@ ssh_gssapi_userok(char *user) +@@ -383,14 +469,90 @@ ssh_gssapi_userok(char *user) return (0); } @@ -794,10 +806,10 @@ diff -up openssh-7.4p1/gss-serv.c.gsskex openssh-7.4p1/gss-serv.c + return ok; } - #endif -diff -up openssh-7.4p1/gss-serv-krb5.c.gsskex openssh-7.4p1/gss-serv-krb5.c ---- openssh-7.4p1/gss-serv-krb5.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/gss-serv-krb5.c 2016-12-23 13:38:53.727301005 +0100 + /* Privileged */ +diff -up openssh/gss-serv-krb5.c.gsskex openssh/gss-serv-krb5.c +--- openssh/gss-serv-krb5.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/gss-serv-krb5.c 2017-09-27 13:54:53.593534364 +0200 @@ -121,7 +121,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl krb5_error_code problem; krb5_principal princ; @@ -925,9 +937,9 @@ diff -up openssh-7.4p1/gss-serv-krb5.c.gsskex openssh-7.4p1/gss-serv-krb5.c }; #endif /* KRB5 */ -diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c ---- openssh-7.4p1/kex.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kex.c 2016-12-23 13:39:56.064313151 +0100 +diff -up openssh/kex.c.gsskex openssh/kex.c +--- openssh/kex.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/kex.c 2017-09-27 13:54:53.593534364 +0200 @@ -54,6 +54,10 @@ #include "sshbuf.h" #include "digest.h" @@ -936,10 +948,10 @@ diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c +#include "ssh-gss.h" +#endif + - #if OPENSSL_VERSION_NUMBER >= 0x00907000L - # if defined(HAVE_EVP_SHA256) - # define evp_ssh_sha256 EVP_sha256 -@@ -111,6 +115,11 @@ static const struct kexalg kexalgs[] = { + /* prototype */ + static int kex_choose_conf(struct ssh *); + static int kex_input_newkeys(int, u_int32_t, struct ssh *); +@@ -103,6 +107,11 @@ static const struct kexalg kexalgs[] = { { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ @@ -951,7 +963,7 @@ diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c { NULL, -1, -1, -1}, }; -@@ -144,6 +153,12 @@ kex_alg_by_name(const char *name) +@@ -136,6 +145,12 @@ kex_alg_by_name(const char *name) for (k = kexalgs; k->name != NULL; k++) { if (strcmp(k->name, name) == 0) return k; @@ -964,9 +976,9 @@ diff -up openssh-7.4p1/kex.c.gsskex openssh-7.4p1/kex.c } return NULL; } -diff -up openssh-7.4p1/kexgssc.c.gsskex openssh-7.4p1/kexgssc.c ---- openssh-7.4p1/kexgssc.c.gsskex 2016-12-23 13:38:53.727301005 +0100 -+++ openssh-7.4p1/kexgssc.c 2016-12-23 13:38:53.727301005 +0100 +diff -up openssh/kexgssc.c.gsskex openssh/kexgssc.c +--- openssh/kexgssc.c.gsskex 2017-09-27 13:54:53.593534364 +0200 ++++ openssh/kexgssc.c 2017-09-27 13:54:53.593534364 +0200 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1306,9 +1318,9 @@ diff -up openssh-7.4p1/kexgssc.c.gsskex openssh-7.4p1/kexgssc.c +} + +#endif /* GSSAPI */ -diff -up openssh-7.4p1/kexgsss.c.gsskex openssh-7.4p1/kexgsss.c ---- openssh-7.4p1/kexgsss.c.gsskex 2016-12-23 13:38:53.728301005 +0100 -+++ openssh-7.4p1/kexgsss.c 2016-12-23 13:38:53.728301005 +0100 +diff -up openssh/kexgsss.c.gsskex openssh/kexgsss.c +--- openssh/kexgsss.c.gsskex 2017-09-27 13:54:53.593534364 +0200 ++++ openssh/kexgsss.c 2017-09-27 13:54:53.593534364 +0200 @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1607,9 +1619,9 @@ diff -up openssh-7.4p1/kexgsss.c.gsskex openssh-7.4p1/kexgsss.c + return 0; +} +#endif /* GSSAPI */ -diff -up openssh-7.4p1/kex.h.gsskex openssh-7.4p1/kex.h ---- openssh-7.4p1/kex.h.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kex.h 2016-12-23 13:38:53.728301005 +0100 +diff -up openssh/kex.h.gsskex openssh/kex.h +--- openssh/kex.h.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/kex.h 2017-09-27 13:54:53.593534364 +0200 @@ -99,6 +99,11 @@ enum kex_exchange { KEX_DH_GEX_SHA256, KEX_ECDH_SHA2, @@ -1646,11 +1658,11 @@ diff -up openssh-7.4p1/kex.h.gsskex openssh-7.4p1/kex.h int kex_dh_hash(int, const char *, const char *, const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, -diff -up openssh-7.4p1/Makefile.in.gsskex openssh-7.4p1/Makefile.in ---- openssh-7.4p1/Makefile.in.gsskex 2016-12-23 13:38:53.723301004 +0100 -+++ openssh-7.4p1/Makefile.in 2016-12-23 13:40:32.226320197 +0100 +diff -up openssh/Makefile.in.gsskex openssh/Makefile.in +--- openssh/Makefile.in.gsskex 2017-09-27 13:54:53.588534337 +0200 ++++ openssh/Makefile.in 2017-09-27 13:54:53.594534370 +0200 @@ -91,6 +91,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ + readpass.o ttymodes.o xmalloc.o addrmatch.o \ atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + kexgssc.o \ @@ -1666,9 +1678,9 @@ diff -up openssh-7.4p1/Makefile.in.gsskex openssh-7.4p1/Makefile.in loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ -diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.gsskex 2016-12-23 13:38:53.687300997 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 13:45:49.347381091 +0100 +diff -up openssh/monitor.c.gsskex openssh/monitor.c +--- openssh/monitor.c.gsskex 2017-09-27 13:54:53.541534079 +0200 ++++ openssh/monitor.c 2017-09-27 13:54:53.594534370 +0200 @@ -160,6 +160,8 @@ int mm_answer_gss_setup_ctx(int, Buffer int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); @@ -1697,7 +1709,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -307,6 +316,10 @@ monitor_child_preauth(Authctxt *_authctx +@@ -308,6 +317,10 @@ monitor_child_preauth(Authctxt *_authctx /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -1708,7 +1720,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -406,6 +419,10 @@ monitor_child_postauth(struct monitor *p +@@ -414,6 +427,10 @@ monitor_child_postauth(struct monitor *p monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -1719,7 +1731,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c if (!no_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1633,6 +1650,13 @@ monitor_apply_keystate(struct monitor *p +@@ -1656,6 +1673,13 @@ monitor_apply_keystate(struct monitor *p # endif #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -1733,7 +1745,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; -@@ -1712,7 +1736,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer +@@ -1744,7 +1768,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer OM_uint32 major; u_int len; @@ -1742,7 +1754,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c fatal("%s: GSSAPI authentication not enabled", __func__); goid.elements = buffer_get_string(m, &len); -@@ -1742,7 +1766,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -1774,7 +1798,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1751,7 +1763,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c fatal("%s: GSSAPI authentication not enabled", __func__); in.value = buffer_get_string(m, &len); -@@ -1762,6 +1786,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -1794,6 +1818,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1759,7 +1771,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c } return (0); } -@@ -1773,7 +1798,7 @@ mm_answer_gss_checkmic(int sock, Buffer +@@ -1805,7 +1830,7 @@ mm_answer_gss_checkmic(int sock, Buffer OM_uint32 ret; u_int len; @@ -1768,9 +1780,9 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c fatal("%s: GSSAPI authentication not enabled", __func__); gssbuf.value = buffer_get_string(m, &len); -@@ -1802,10 +1827,11 @@ mm_answer_gss_userok(int sock, Buffer *m - { +@@ -1835,10 +1860,11 @@ mm_answer_gss_userok(int sock, Buffer *m int authenticated; + const char *displayname; - if (!options.gss_authentication) + if (!options.gss_authentication && !options.gss_keyex) @@ -1782,7 +1794,7 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -1818,5 +1844,73 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -1854,5 +1880,73 @@ mm_answer_gss_userok(int sock, Buffer *m /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -1856,9 +1868,9 @@ diff -up openssh-7.4p1/monitor.c.gsskex openssh-7.4p1/monitor.c + #endif /* GSSAPI */ -diff -up openssh-7.4p1/monitor.h.gsskex openssh-7.4p1/monitor.h ---- openssh-7.4p1/monitor.h.gsskex 2016-12-23 13:38:53.687300997 +0100 -+++ openssh-7.4p1/monitor.h 2016-12-23 13:38:53.729301005 +0100 +diff -up openssh/monitor.h.gsskex openssh/monitor.h +--- openssh/monitor.h.gsskex 2017-09-27 13:54:53.541534079 +0200 ++++ openssh/monitor.h 2017-09-27 13:54:53.594534370 +0200 @@ -60,6 +60,8 @@ enum monitor_reqtype { #ifdef WITH_SELINUX MONITOR_REQ_AUTHROLE = 80, @@ -1868,10 +1880,10 @@ diff -up openssh-7.4p1/monitor.h.gsskex openssh-7.4p1/monitor.h MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, -diff -up openssh-7.4p1/monitor_wrap.c.gsskex openssh-7.4p1/monitor_wrap.c ---- openssh-7.4p1/monitor_wrap.c.gsskex 2016-12-23 13:38:53.687300997 +0100 -+++ openssh-7.4p1/monitor_wrap.c 2016-12-23 13:38:53.729301005 +0100 -@@ -943,7 +943,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss +diff -up openssh/monitor_wrap.c.gsskex openssh/monitor_wrap.c +--- openssh/monitor_wrap.c.gsskex 2017-09-27 13:54:53.542534084 +0200 ++++ openssh/monitor_wrap.c 2017-09-27 13:54:53.595534375 +0200 +@@ -950,7 +950,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } int @@ -1880,7 +1892,7 @@ diff -up openssh-7.4p1/monitor_wrap.c.gsskex openssh-7.4p1/monitor_wrap.c { Buffer m; int authenticated = 0; -@@ -960,5 +960,50 @@ mm_ssh_gssapi_userok(char *user) +@@ -967,5 +967,50 @@ mm_ssh_gssapi_userok(char *user) debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); return (authenticated); } @@ -1931,10 +1943,10 @@ diff -up openssh-7.4p1/monitor_wrap.c.gsskex openssh-7.4p1/monitor_wrap.c + #endif /* GSSAPI */ -diff -up openssh-7.4p1/monitor_wrap.h.gsskex openssh-7.4p1/monitor_wrap.h ---- openssh-7.4p1/monitor_wrap.h.gsskex 2016-12-23 13:38:53.687300997 +0100 -+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 13:38:53.729301005 +0100 -@@ -58,8 +58,10 @@ int mm_key_verify(Key *, u_char *, u_int +diff -up openssh/monitor_wrap.h.gsskex openssh/monitor_wrap.h +--- openssh/monitor_wrap.h.gsskex 2017-09-27 13:54:53.542534084 +0200 ++++ openssh/monitor_wrap.h 2017-09-27 13:54:53.595534375 +0200 +@@ -60,8 +60,10 @@ int mm_sshkey_verify(const struct sshkey OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -1946,9 +1958,9 @@ diff -up openssh-7.4p1/monitor_wrap.h.gsskex openssh-7.4p1/monitor_wrap.h #endif #ifdef USE_PAM -diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c ---- openssh-7.4p1/readconf.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/readconf.c 2016-12-23 13:38:53.730301005 +0100 +diff -up openssh/readconf.c.gsskex openssh/readconf.c +--- openssh/readconf.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/readconf.c 2017-09-27 13:54:53.596534381 +0200 @@ -160,6 +160,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, @@ -1958,7 +1970,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -205,10 +207,19 @@ static struct { +@@ -199,10 +201,19 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -1978,7 +1990,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c #endif #ifdef ENABLE_PKCS11 { "smartcarddevice", oPKCS11Provider }, -@@ -961,10 +972,30 @@ parse_time: +@@ -976,10 +987,30 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2009,7 +2021,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -1776,7 +1807,12 @@ initialize_options(Options * options) +@@ -1790,7 +1821,12 @@ initialize_options(Options * options) options->pubkey_authentication = -1; options->challenge_response_authentication = -1; options->gss_authentication = -1; @@ -2022,7 +2034,7 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -1920,8 +1956,14 @@ fill_default_options(Options * options) +@@ -1930,8 +1966,14 @@ fill_default_options(Options * options) options->challenge_response_authentication = 1; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2037,10 +2049,10 @@ diff -up openssh-7.4p1/readconf.c.gsskex openssh-7.4p1/readconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -diff -up openssh-7.4p1/readconf.h.gsskex openssh-7.4p1/readconf.h ---- openssh-7.4p1/readconf.h.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/readconf.h 2016-12-23 13:38:53.730301005 +0100 -@@ -45,7 +45,12 @@ typedef struct { +diff -up openssh/readconf.h.gsskex openssh/readconf.h +--- openssh/readconf.h.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/readconf.h 2017-09-27 13:54:53.596534381 +0200 +@@ -42,7 +42,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ int gss_authentication; /* Try GSS authentication */ @@ -2053,9 +2065,9 @@ diff -up openssh-7.4p1/readconf.h.gsskex openssh-7.4p1/readconf.h int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ -diff -up openssh-7.4p1/regress/cert-hostkey.sh.gsskex openssh-7.4p1/regress/cert-hostkey.sh ---- openssh-7.4p1/regress/cert-hostkey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/cert-hostkey.sh 2016-12-23 13:38:53.731301006 +0100 +diff -up openssh/regress/cert-hostkey.sh.gsskex openssh/regress/cert-hostkey.sh +--- openssh/regress/cert-hostkey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/regress/cert-hostkey.sh 2017-09-27 13:54:53.596534381 +0200 @@ -59,7 +59,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca @@ -2065,9 +2077,9 @@ diff -up openssh-7.4p1/regress/cert-hostkey.sh.gsskex openssh-7.4p1/regress/cert if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" -diff -up openssh-7.4p1/regress/cert-userkey.sh.gsskex openssh-7.4p1/regress/cert-userkey.sh ---- openssh-7.4p1/regress/cert-userkey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/cert-userkey.sh 2016-12-23 13:38:53.731301006 +0100 +diff -up openssh/regress/cert-userkey.sh.gsskex openssh/regress/cert-userkey.sh +--- openssh/regress/cert-userkey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/regress/cert-userkey.sh 2017-09-27 13:54:53.596534381 +0200 @@ -7,7 +7,7 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak @@ -2077,9 +2089,9 @@ diff -up openssh-7.4p1/regress/cert-userkey.sh.gsskex openssh-7.4p1/regress/cert if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" -diff -up openssh-7.4p1/regress/kextype.sh.gsskex openssh-7.4p1/regress/kextype.sh ---- openssh-7.4p1/regress/kextype.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/kextype.sh 2016-12-23 13:38:53.731301006 +0100 +diff -up openssh/regress/kextype.sh.gsskex openssh/regress/kextype.sh +--- openssh/regress/kextype.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/regress/kextype.sh 2017-09-27 13:54:53.596534381 +0200 @@ -14,6 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/ssh tries="1 2 3 4" @@ -2090,9 +2102,9 @@ diff -up openssh-7.4p1/regress/kextype.sh.gsskex openssh-7.4p1/regress/kextype.s verbose "kex $k" for i in $tries; do ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true -diff -up openssh-7.4p1/regress/rekey.sh.gsskex openssh-7.4p1/regress/rekey.sh ---- openssh-7.4p1/regress/rekey.sh.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/rekey.sh 2016-12-23 13:38:53.731301006 +0100 +diff -up openssh/regress/rekey.sh.gsskex openssh/regress/rekey.sh +--- openssh/regress/rekey.sh.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/regress/rekey.sh 2017-09-27 13:54:53.596534381 +0200 @@ -38,6 +38,9 @@ increase_datafile_size 300 opts="" @@ -2113,9 +2125,9 @@ diff -up openssh-7.4p1/regress/rekey.sh.gsskex openssh-7.4p1/regress/rekey.sh verbose "client rekey $c $kex" ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c done -diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.gsskex 2016-12-23 13:38:53.717301003 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 13:38:53.732301006 +0100 +diff -up openssh/servconf.c.gsskex openssh/servconf.c +--- openssh/servconf.c.gsskex 2017-09-27 13:54:53.581534298 +0200 ++++ openssh/servconf.c 2017-09-27 13:54:53.597534386 +0200 @@ -113,8 +113,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -2127,7 +2139,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -268,10 +270,14 @@ fill_default_server_options(ServerOption +@@ -269,10 +271,14 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2142,7 +2154,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -410,7 +416,7 @@ typedef enum { +@@ -413,7 +419,7 @@ typedef enum { sHostKeyAlgorithms, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -2151,7 +2163,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, -@@ -484,11 +490,17 @@ static struct { +@@ -488,11 +494,17 @@ static struct { { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, @@ -2169,7 +2181,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1211,6 +1223,10 @@ process_server_config_line(ServerOptions +@@ -1257,6 +1269,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2180,7 +2192,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1219,6 +1235,10 @@ process_server_config_line(ServerOptions +@@ -1265,6 +1281,10 @@ process_server_config_line(ServerOptions intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -2191,7 +2203,7 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -2257,6 +2277,9 @@ dump_config(ServerOptions *o) +@@ -2302,6 +2322,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2201,10 +2213,10 @@ diff -up openssh-7.4p1/servconf.c.gsskex openssh-7.4p1/servconf.c #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, -diff -up openssh-7.4p1/servconf.h.gsskex openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.gsskex 2016-12-23 13:38:53.717301003 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 13:38:53.732301006 +0100 -@@ -112,8 +112,10 @@ typedef struct { +diff -up openssh/servconf.h.gsskex openssh/servconf.h +--- openssh/servconf.h.gsskex 2017-09-27 13:54:53.582534304 +0200 ++++ openssh/servconf.h 2017-09-27 13:54:53.597534386 +0200 +@@ -119,8 +119,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -2215,10 +2227,10 @@ diff -up openssh-7.4p1/servconf.h.gsskex openssh-7.4p1/servconf.h int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh-7.4p1/ssh_config.5.gsskex openssh-7.4p1/ssh_config.5 ---- openssh-7.4p1/ssh_config.5.gsskex 2016-12-23 13:38:53.732301006 +0100 -+++ openssh-7.4p1/ssh_config.5 2016-12-23 13:48:00.502331870 +0100 -@@ -748,10 +748,40 @@ The default is +diff -up openssh/ssh_config.5.gsskex openssh/ssh_config.5 +--- openssh/ssh_config.5.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/ssh_config.5 2017-09-27 13:54:53.597534386 +0200 +@@ -720,10 +720,40 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -2259,10 +2271,10 @@ diff -up openssh-7.4p1/ssh_config.5.gsskex openssh-7.4p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 -diff -up openssh-7.4p1/ssh_config.gsskex openssh-7.4p1/ssh_config ---- openssh-7.4p1/ssh_config.gsskex 2016-12-23 13:38:53.708301001 +0100 -+++ openssh-7.4p1/ssh_config 2016-12-23 13:38:53.733301006 +0100 -@@ -26,6 +26,8 @@ +diff -up openssh/ssh_config.gsskex openssh/ssh_config +--- openssh/ssh_config.gsskex 2017-09-27 13:54:53.571534243 +0200 ++++ openssh/ssh_config 2017-09-27 13:54:53.597534386 +0200 +@@ -24,6 +24,8 @@ # HostbasedAuthentication no # GSSAPIAuthentication no # GSSAPIDelegateCredentials no @@ -2271,10 +2283,135 @@ diff -up openssh-7.4p1/ssh_config.gsskex openssh-7.4p1/ssh_config # BatchMode no # CheckHostIP yes # AddressFamily any -diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c ---- openssh-7.4p1/sshconnect2.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshconnect2.c 2016-12-23 13:38:53.733301006 +0100 -@@ -162,9 +162,34 @@ ssh_kex2(char *host, struct sockaddr *ho +diff -up openssh/sshconnect2.c.gsskex openssh/sshconnect2.c +--- openssh/sshconnect2.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/sshconnect2.c 2017-09-27 13:57:23.418358207 +0200 +@@ -82,6 +82,124 @@ extern char *client_version_string; + extern char *server_version_string; + extern Options options; + ++/* XXX from auth.h -- refactoring move these useful functions away of client context*/ ++ ++/* ++ * Returns the remote DNS hostname as a string. The returned string must not ++ * be freed. NB. this will usually trigger a DNS query the first time it is ++ * called. ++ * This function does additional checks on the hostname to mitigate some ++ * attacks on legacy rhosts-style authentication. ++ * XXX is RhostsRSAAuthentication vulnerable to these? ++ * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) ++ */ ++ ++static char * ++remote_hostname(struct ssh *ssh) ++{ ++ struct sockaddr_storage from; ++ socklen_t fromlen; ++ struct addrinfo hints, *ai, *aitop; ++ char name[NI_MAXHOST], ntop2[NI_MAXHOST]; ++ const char *ntop = ssh_remote_ipaddr(ssh); ++ ++ /* Get IP address of client. */ ++ fromlen = sizeof(from); ++ memset(&from, 0, sizeof(from)); ++ if (getpeername(ssh_packet_get_connection_in(ssh), ++ (struct sockaddr *)&from, &fromlen) < 0) { ++ debug("getpeername failed: %.100s", strerror(errno)); ++ return strdup(ntop); ++ } ++ ++ ipv64_normalise_mapped(&from, &fromlen); ++ if (from.ss_family == AF_INET6) ++ fromlen = sizeof(struct sockaddr_in6); ++ ++ debug3("Trying to reverse map address %.100s.", ntop); ++ /* Map the IP address to a host name. */ ++ if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), ++ NULL, 0, NI_NAMEREQD) != 0) { ++ /* Host name not found. Use ip address. */ ++ return strdup(ntop); ++ } ++ ++ /* ++ * if reverse lookup result looks like a numeric hostname, ++ * someone is trying to trick us by PTR record like following: ++ * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 ++ */ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_socktype = SOCK_DGRAM; /*dummy*/ ++ hints.ai_flags = AI_NUMERICHOST; ++ if (getaddrinfo(name, NULL, &hints, &ai) == 0) { ++ logit("Nasty PTR record \"%s\" is set up for %s, ignoring", ++ name, ntop); ++ freeaddrinfo(ai); ++ return strdup(ntop); ++ } ++ ++ /* Names are stored in lowercase. */ ++ lowercase(name); ++ ++ /* ++ * Map it back to an IP address and check that the given ++ * address actually is an address of this host. This is ++ * necessary because anyone with access to a name server can ++ * define arbitrary names for an IP address. Mapping from ++ * name to IP address can be trusted better (but can still be ++ * fooled if the intruder has access to the name server of ++ * the domain). ++ */ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_family = from.ss_family; ++ hints.ai_socktype = SOCK_STREAM; ++ if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { ++ logit("reverse mapping checking getaddrinfo for %.700s " ++ "[%s] failed.", name, ntop); ++ return strdup(ntop); ++ } ++ /* Look for the address from the list of addresses. */ ++ for (ai = aitop; ai; ai = ai->ai_next) { ++ if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, ++ sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && ++ (strcmp(ntop, ntop2) == 0)) ++ break; ++ } ++ freeaddrinfo(aitop); ++ /* If we reached the end of the list, the address was not there. */ ++ if (ai == NULL) { ++ /* Address not found for the host name. */ ++ logit("Address %.100s maps to %.600s, but this does not " ++ "map back to the address.", ntop, name); ++ return strdup(ntop); ++ } ++ return strdup(name); ++} ++ ++/* ++ * Return the canonical name of the host in the other side of the current ++ * connection. The host name is cached, so it is efficient to call this ++ * several times. ++ */ ++ ++const char * ++get_canonical_hostname(struct ssh *ssh, int use_dns) ++{ ++ static char *dnsname; ++ ++ if (!use_dns) ++ return ssh_remote_ipaddr(ssh); ++ else if (dnsname != NULL) ++ return dnsname; ++ else { ++ dnsname = remote_hostname(ssh); ++ return dnsname; ++ } ++} ++ ++ ++ + /* + * SSH2 key exchange + */ +@@ -162,9 +280,34 @@ ssh_kex2(char *host, struct sockaddr *ho struct kex *kex; int r; @@ -2309,7 +2446,7 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) fatal("%s: kex_names_cat", __func__); myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); -@@ -192,6 +217,17 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -192,6 +335,17 @@ ssh_kex2(char *host, struct sockaddr *ho order_hostkeyalgs(host, hostaddr, port)); } @@ -2327,7 +2464,7 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits(options.rekey_limit, options.rekey_interval); -@@ -212,11 +248,31 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -212,11 +366,31 @@ ssh_kex2(char *host, struct sockaddr *ho kex->kex[KEX_ECDH_SHA2] = kexecdh_client; # endif #endif @@ -2356,18 +2493,18 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c + } +#endif + - dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); + ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); /* remove ext-info from the KEX proposals for rekeying */ -@@ -311,6 +367,7 @@ int input_gssapi_token(int type, u_int32 - int input_gssapi_hash(int type, u_int32_t, void *); - int input_gssapi_error(int, u_int32_t, void *); - int input_gssapi_errtok(int, u_int32_t, void *); +@@ -311,6 +485,7 @@ int input_gssapi_token(int type, u_int32 + int input_gssapi_hash(int type, u_int32_t, struct ssh *); + int input_gssapi_error(int, u_int32_t, struct ssh *); + int input_gssapi_errtok(int, u_int32_t, struct ssh *); +int userauth_gsskeyex(Authctxt *authctxt); #endif void userauth(Authctxt *, char *); -@@ -327,6 +384,11 @@ static char *authmethods_get(void); +@@ -327,6 +502,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -2379,7 +2516,7 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c {"gssapi-with-mic", userauth_gssapi, NULL, -@@ -652,19 +714,31 @@ userauth_gssapi(Authctxt *authctxt) +@@ -654,19 +834,31 @@ userauth_gssapi(Authctxt *authctxt) static u_int mech = 0; OM_uint32 min; int ok = 0; @@ -2413,9 +2550,9 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c ok = 1; /* Mechanism works */ } else { mech++; -@@ -761,8 +835,8 @@ input_gssapi_response(int type, u_int32_ +@@ -763,8 +955,8 @@ input_gssapi_response(int type, u_int32_ { - Authctxt *authctxt = ctxt; + Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; - int oidlen; - char *oidv; @@ -2424,7 +2561,7 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); -@@ -875,6 +949,48 @@ input_gssapi_error(int type, u_int32_t p +@@ -877,6 +1069,48 @@ input_gssapi_error(int type, u_int32_t p free(lang); return 0; } @@ -2473,10 +2610,10 @@ diff -up openssh-7.4p1/sshconnect2.c.gsskex openssh-7.4p1/sshconnect2.c #endif /* GSSAPI */ int -diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c ---- openssh-7.2p1/sshd.c.gsskex 2016-02-19 10:01:04.860969328 +0100 -+++ openssh-7.2p1/sshd.c 2016-02-19 10:01:04.872969321 +0100 -@@ -547,7 +547,7 @@ privsep_preauth_child(void) +diff -up openssh/sshd.c.gsskex openssh/sshd.c +--- openssh/sshd.c.gsskex 2017-09-27 13:54:53.584534315 +0200 ++++ openssh/sshd.c 2017-09-27 13:54:53.600534403 +0200 +@@ -530,7 +530,7 @@ privsep_preauth_child(void) #ifdef GSSAPI /* Cache supported mechanism OIDs for later use */ @@ -2485,7 +2622,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c ssh_gssapi_prepare_supported_oids(); #endif -@@ -974,8 +974,9 @@ notify_hostkeys(struct ssh *ssh) +@@ -871,8 +871,9 @@ notify_hostkeys(struct ssh *ssh) } debug3("%s: sent %d hostkeys", __func__, nkeys); if (nkeys == 0) @@ -2497,7 +2634,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c sshbuf_free(buf); } -@@ -1739,7 +1740,8 @@ main(int ac, char **av) +@@ -1738,7 +1739,8 @@ main(int ac, char **av) key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); free(fp); } @@ -2507,7 +2644,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c logit("sshd: no hostkeys available -- exiting."); exit(1); } -@@ -2196,6 +2198,48 @@ do_ssh2_kex(void) +@@ -2203,6 +2205,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( list_hostkey_types()); @@ -2556,7 +2693,7 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c /* start key exchange */ if ((r = kex_setup(active_state, myproposal)) != 0) fatal("kex_setup: %s", ssh_err(r)); -@@ -2213,6 +2257,13 @@ do_ssh2_kex(void) +@@ -2220,6 +2264,13 @@ do_ssh2_kex(void) # endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; @@ -2570,10 +2707,10 @@ diff -up openssh-7.2p1/sshd.c.gsskex openssh-7.2p1/sshd.c kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff -up openssh-7.4p1/sshd_config.5.gsskex openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.gsskex 2016-12-23 13:38:53.734301006 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 13:48:57.825310358 +0100 -@@ -628,6 +628,11 @@ Specifies whether to automatically destr +diff -up openssh/sshd_config.5.gsskex openssh/sshd_config.5 +--- openssh/sshd_config.5.gsskex 2017-09-27 13:54:53.582534304 +0200 ++++ openssh/sshd_config.5 2017-09-27 13:54:53.600534403 +0200 +@@ -638,6 +638,11 @@ Specifies whether to automatically destr on logout. The default is .Cm yes . @@ -2585,7 +2722,7 @@ diff -up openssh-7.4p1/sshd_config.5.gsskex openssh-7.4p1/sshd_config.5 .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. -@@ -642,6 +647,11 @@ machine's default store. +@@ -652,6 +657,11 @@ machine's default store. This facility is provided to assist with operation on multi homed machines. The default is .Cm yes . @@ -2597,10 +2734,10 @@ diff -up openssh-7.4p1/sshd_config.5.gsskex openssh-7.4p1/sshd_config.5 .It Cm HostbasedAcceptedKeyTypes Specifies the key types that will be accepted for hostbased authentication as a comma-separated pattern list. -diff -up openssh-7.4p1/sshd_config.gsskex openssh-7.4p1/sshd_config ---- openssh-7.4p1/sshd_config.gsskex 2016-12-23 13:38:53.719301003 +0100 -+++ openssh-7.4p1/sshd_config 2016-12-23 13:38:53.734301006 +0100 -@@ -77,6 +77,8 @@ ChallengeResponseAuthentication no +diff -up openssh/sshd_config.gsskex openssh/sshd_config +--- openssh/sshd_config.gsskex 2017-09-27 13:54:53.585534320 +0200 ++++ openssh/sshd_config 2017-09-27 13:54:53.601534408 +0200 +@@ -86,6 +86,8 @@ ChallengeResponseAuthentication no # GSSAPI options GSSAPIAuthentication yes GSSAPICleanupCredentials no @@ -2609,11 +2746,11 @@ diff -up openssh-7.4p1/sshd_config.gsskex openssh-7.4p1/sshd_config # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will -diff -up openssh-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h ---- openssh-7.4p1/ssh-gss.h.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-gss.h 2016-12-23 13:38:53.734301006 +0100 +diff -up openssh/ssh-gss.h.gsskex openssh/ssh-gss.h +--- openssh/ssh-gss.h.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/ssh-gss.h 2017-09-27 13:54:53.601534408 +0200 @@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ + /* $OpenBSD: ssh-gss.h,v 1.12 2017/06/24 06:34:38 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -2676,7 +2813,7 @@ diff -up openssh-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -119,16 +136,32 @@ void ssh_gssapi_build_ctx(Gssctxt **); +@@ -119,17 +136,33 @@ void ssh_gssapi_build_ctx(Gssctxt **); void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); @@ -2701,6 +2838,7 @@ diff -up openssh-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h void ssh_gssapi_do_child(char ***, u_int *); void ssh_gssapi_cleanup_creds(void); void ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); +char *ssh_gssapi_server_mechanisms(void); +int ssh_gssapi_oid_table_ok(); @@ -2711,10 +2849,10 @@ diff -up openssh-7.4p1/ssh-gss.h.gsskex openssh-7.4p1/ssh-gss.h #endif /* GSSAPI */ #endif /* _SSH_GSS_H */ -diff -up openssh-7.4p1/sshkey.c.gsskex openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 13:38:53.735301006 +0100 -@@ -114,6 +114,7 @@ static const struct keytype keytypes[] = +diff -up openssh/sshkey.c.gsskex openssh/sshkey.c +--- openssh/sshkey.c.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/sshkey.c 2017-09-27 13:54:53.601534408 +0200 +@@ -112,6 +112,7 @@ static const struct keytype keytypes[] = # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -2722,10 +2860,10 @@ diff -up openssh-7.4p1/sshkey.c.gsskex openssh-7.4p1/sshkey.c { NULL, NULL, -1, -1, 0, 0 } }; -diff -up openssh-7.4p1/sshkey.h.gsskex openssh-7.4p1/sshkey.h ---- openssh-7.4p1/sshkey.h.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshkey.h 2016-12-23 13:38:53.735301006 +0100 -@@ -62,6 +62,7 @@ enum sshkey_types { +diff -up openssh/sshkey.h.gsskex openssh/sshkey.h +--- openssh/sshkey.h.gsskex 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/sshkey.h 2017-09-27 13:54:53.602534414 +0200 +@@ -61,6 +61,7 @@ enum sshkey_types { KEY_DSA_CERT, KEY_ECDSA_CERT, KEY_ED25519_CERT, @@ -2733,268 +2871,3 @@ diff -up openssh-7.4p1/sshkey.h.gsskex openssh-7.4p1/sshkey.h KEY_UNSPEC }; -diff -up openssh-7.4p1/auth.c.gsskex openssh-7.4p1/auth.c ---- openssh-7.4p1/auth.c.gsskex 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/auth.c 2016-12-23 13:38:53.735301006 +0100 -@@ -372,6 +372,7 @@ auth_root_allowed(const char *method) - case PERMIT_NO_PASSWD: - if (strcmp(method, "publickey") == 0 || - strcmp(method, "hostbased") == 0 || -+ strcmp(method, "gssapi-keyex") == 0 || - strcmp(method, "gssapi-with-mic") == 0) - return 1; - break; -@@ -795,99 +796,6 @@ fakepw(void) - } - - /* -- * Returns the remote DNS hostname as a string. The returned string must not -- * be freed. NB. this will usually trigger a DNS query the first time it is -- * called. -- * This function does additional checks on the hostname to mitigate some -- * attacks on legacy rhosts-style authentication. -- * XXX is RhostsRSAAuthentication vulnerable to these? -- * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) -- */ -- --static char * --remote_hostname(struct ssh *ssh) --{ -- struct sockaddr_storage from; -- socklen_t fromlen; -- struct addrinfo hints, *ai, *aitop; -- char name[NI_MAXHOST], ntop2[NI_MAXHOST]; -- const char *ntop = ssh_remote_ipaddr(ssh); -- -- /* Get IP address of client. */ -- fromlen = sizeof(from); -- memset(&from, 0, sizeof(from)); -- if (getpeername(ssh_packet_get_connection_in(ssh), -- (struct sockaddr *)&from, &fromlen) < 0) { -- debug("getpeername failed: %.100s", strerror(errno)); -- return strdup(ntop); -- } -- -- ipv64_normalise_mapped(&from, &fromlen); -- if (from.ss_family == AF_INET6) -- fromlen = sizeof(struct sockaddr_in6); -- -- debug3("Trying to reverse map address %.100s.", ntop); -- /* Map the IP address to a host name. */ -- if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), -- NULL, 0, NI_NAMEREQD) != 0) { -- /* Host name not found. Use ip address. */ -- return strdup(ntop); -- } -- -- /* -- * if reverse lookup result looks like a numeric hostname, -- * someone is trying to trick us by PTR record like following: -- * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 -- */ -- memset(&hints, 0, sizeof(hints)); -- hints.ai_socktype = SOCK_DGRAM; /*dummy*/ -- hints.ai_flags = AI_NUMERICHOST; -- if (getaddrinfo(name, NULL, &hints, &ai) == 0) { -- logit("Nasty PTR record \"%s\" is set up for %s, ignoring", -- name, ntop); -- freeaddrinfo(ai); -- return strdup(ntop); -- } -- -- /* Names are stored in lowercase. */ -- lowercase(name); -- -- /* -- * Map it back to an IP address and check that the given -- * address actually is an address of this host. This is -- * necessary because anyone with access to a name server can -- * define arbitrary names for an IP address. Mapping from -- * name to IP address can be trusted better (but can still be -- * fooled if the intruder has access to the name server of -- * the domain). -- */ -- memset(&hints, 0, sizeof(hints)); -- hints.ai_family = from.ss_family; -- hints.ai_socktype = SOCK_STREAM; -- if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { -- logit("reverse mapping checking getaddrinfo for %.700s " -- "[%s] failed.", name, ntop); -- return strdup(ntop); -- } -- /* Look for the address from the list of addresses. */ -- for (ai = aitop; ai; ai = ai->ai_next) { -- if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, -- sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && -- (strcmp(ntop, ntop2) == 0)) -- break; -- } -- freeaddrinfo(aitop); -- /* If we reached the end of the list, the address was not there. */ -- if (ai == NULL) { -- /* Address not found for the host name. */ -- logit("Address %.100s maps to %.600s, but this does not " -- "map back to the address.", ntop, name); -- return strdup(ntop); -- } -- return strdup(name); --} -- --/* - * Return the canonical name of the host in the other side of the current - * connection. The host name is cached, so it is efficient to call this - * several times. -diff -up openssh-7.4p1/openbsd-compat/port-linux.c.gsskex openssh-7.4p1/openbsd-compat/port-linux.c ---- openssh-7.4p1/openbsd-compat/port-linux.c.gsskex 2016-12-23 13:38:53.688300997 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux.c 2016-12-23 13:38:53.735301006 +0100 -@@ -30,6 +30,8 @@ - #include "log.h" - #include "xmalloc.h" - #include "port-linux.h" -+#include "canohost.h" -+#include "misc.h" - - #ifdef WITH_SELINUX - #include -@@ -279,4 +281,121 @@ oom_adjust_restore(void) - return; - } - #endif /* LINUX_OOM_ADJUST */ -+ -+/**************** XXX moved from auth.c ****************/ -+ -+/* -+ * Returns the remote DNS hostname as a string. The returned string must not -+ * be freed. NB. this will usually trigger a DNS query the first time it is -+ * called. -+ * This function does additional checks on the hostname to mitigate some -+ * attacks on legacy rhosts-style authentication. -+ * XXX is RhostsRSAAuthentication vulnerable to these? -+ * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) -+ */ -+ -+char * -+remote_hostname(struct ssh *ssh) -+{ -+ struct sockaddr_storage from; -+ socklen_t fromlen; -+ struct addrinfo hints, *ai, *aitop; -+ char name[NI_MAXHOST], ntop2[NI_MAXHOST]; -+ const char *ntop = ssh_remote_ipaddr(ssh); -+ -+ /* Get IP address of client. */ -+ fromlen = sizeof(from); -+ memset(&from, 0, sizeof(from)); -+ if (getpeername(ssh_packet_get_connection_in(ssh), -+ (struct sockaddr *)&from, &fromlen) < 0) { -+ debug("getpeername failed: %.100s", strerror(errno)); -+ return strdup(ntop); -+ } -+ -+ ipv64_normalise_mapped(&from, &fromlen); -+ if (from.ss_family == AF_INET6) -+ fromlen = sizeof(struct sockaddr_in6); -+ -+ debug3("Trying to reverse map address %.100s.", ntop); -+ /* Map the IP address to a host name. */ -+ if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), -+ NULL, 0, NI_NAMEREQD) != 0) { -+ /* Host name not found. Use ip address. */ -+ return strdup(ntop); -+ } -+ -+ /* -+ * if reverse lookup result looks like a numeric hostname, -+ * someone is trying to trick us by PTR record like following: -+ * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 -+ */ -+ memset(&hints, 0, sizeof(hints)); -+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/ -+ hints.ai_flags = AI_NUMERICHOST; -+ if (getaddrinfo(name, NULL, &hints, &ai) == 0) { -+ logit("Nasty PTR record \"%s\" is set up for %s, ignoring", -+ name, ntop); -+ freeaddrinfo(ai); -+ return strdup(ntop); -+ } -+ -+ /* Names are stored in lowercase. */ -+ lowercase(name); -+ -+ /* -+ * Map it back to an IP address and check that the given -+ * address actually is an address of this host. This is -+ * necessary because anyone with access to a name server can -+ * define arbitrary names for an IP address. Mapping from -+ * name to IP address can be trusted better (but can still be -+ * fooled if the intruder has access to the name server of -+ * the domain). -+ */ -+ memset(&hints, 0, sizeof(hints)); -+ hints.ai_family = from.ss_family; -+ hints.ai_socktype = SOCK_STREAM; -+ if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { -+ logit("reverse mapping checking getaddrinfo for %.700s " -+ "[%s] failed - POSSIBLE BREAK-IN ATTEMPT!", name, ntop); -+ return strdup(ntop); -+ } -+ /* Look for the address from the list of addresses. */ -+ for (ai = aitop; ai; ai = ai->ai_next) { -+ if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, -+ sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && -+ (strcmp(ntop, ntop2) == 0)) -+ break; -+ } -+ freeaddrinfo(aitop); -+ /* If we reached the end of the list, the address was not there. */ -+ if (ai == NULL) { -+ /* Address not found for the host name. */ -+ logit("Address %.100s maps to %.600s, but this does not " -+ "map back to the address - POSSIBLE BREAK-IN ATTEMPT!", -+ ntop, name); -+ return strdup(ntop); -+ } -+ return strdup(name); -+} -+ -+/* -+ * Return the canonical name of the host in the other side of the current -+ * connection. The host name is cached, so it is efficient to call this -+ * several times. -+ */ -+ -+const char * -+get_canonical_hostname(struct ssh *ssh, int use_dns) -+{ -+ static char *dnsname; -+ -+ if (!use_dns) -+ return ssh_remote_ipaddr(ssh); -+ else if (dnsname != NULL) -+ return dnsname; -+ else { -+ dnsname = remote_hostname(ssh); -+ return dnsname; -+ } -+} - #endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ -diff -up openssh-7.4p1/openbsd-compat/port-linux.h.gsskex openssh-7.4p1/openbsd-compat/port-linux.h ---- openssh-7.4p1/openbsd-compat/port-linux.h.gsskex 2016-12-23 13:38:53.712301002 +0100 -+++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 13:38:53.735301006 +0100 -@@ -16,6 +16,7 @@ - - #ifndef _PORT_LINUX_H - #define _PORT_LINUX_H -+#include "packet.h" - - #ifdef WITH_SELINUX - int ssh_selinux_enabled(void); -@@ -36,4 +37,8 @@ void oom_adjust_setup(void); - - void linux_seed(void); - -+const char *get_canonical_hostname(struct ssh *, int); -+char *remote_hostname(struct ssh *); -+ -+ - #endif /* ! _PORT_LINUX_H */ diff --git a/openssh-7.2p2-expose-pam.patch b/openssh-7.2p2-expose-pam.patch deleted file mode 100644 index 91428c3..0000000 --- a/openssh-7.2p2-expose-pam.patch +++ /dev/null @@ -1,517 +0,0 @@ -diff -up openssh-7.4p1/auth2.c.expose-pam openssh-7.4p1/auth2.c ---- openssh-7.4p1/auth2.c.expose-pam 2016-12-23 15:40:26.768447868 +0100 -+++ openssh-7.4p1/auth2.c 2016-12-23 15:40:26.818447876 +0100 -@@ -310,6 +310,7 @@ userauth_finish(Authctxt *authctxt, int - { - struct ssh *ssh = active_state; /* XXX */ - char *methods; -+ char *prev_auth_details; - int partial = 0; - - if (!authctxt->valid && authenticated) -@@ -340,6 +341,18 @@ userauth_finish(Authctxt *authctxt, int - if (authctxt->postponed) - return; - -+ if (authenticated || partial) { -+ prev_auth_details = authctxt->auth_details; -+ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", -+ prev_auth_details ? prev_auth_details : "", -+ prev_auth_details ? ", " : "", method, -+ authctxt->last_details ? ": " : "", -+ authctxt->last_details ? authctxt->last_details : ""); -+ free(prev_auth_details); -+ } -+ free(authctxt->last_details); -+ authctxt->last_details = NULL; -+ - #ifdef USE_PAM - if (options.use_pam && authenticated) { - if (!PRIVSEP(do_pam_account())) { -diff -up openssh-7.4p1/auth2-gss.c.expose-pam openssh-7.4p1/auth2-gss.c ---- openssh-7.4p1/auth2-gss.c.expose-pam 2016-12-23 15:40:26.769447868 +0100 -+++ openssh-7.4p1/auth2-gss.c 2016-12-23 15:40:26.818447876 +0100 -@@ -276,6 +276,9 @@ input_gssapi_exchange_complete(int type, - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, - authctxt->pw)); - -+ if (authenticated) -+ authctxt->last_details = ssh_gssapi_get_displayname(); -+ - authctxt->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); -@@ -322,6 +325,9 @@ input_gssapi_mic(int type, u_int32_t ple - else - logit("GSSAPI MIC check failed"); - -+ if (authenticated) -+ authctxt->last_details = ssh_gssapi_get_displayname(); -+ - buffer_free(&b); - if (micuser != authctxt->user) - free(micuser); -diff -up openssh-7.4p1/auth2-hostbased.c.expose-pam openssh-7.4p1/auth2-hostbased.c ---- openssh-7.4p1/auth2-hostbased.c.expose-pam 2016-12-23 15:40:26.731447862 +0100 -+++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 15:40:26.818447876 +0100 -@@ -60,7 +60,7 @@ userauth_hostbased(Authctxt *authctxt) - { - Buffer b; - Key *key = NULL; -- char *pkalg, *cuser, *chost, *service; -+ char *pkalg, *cuser, *chost, *service, *pubkey; - u_char *pkblob, *sig; - u_int alen, blen, slen; - int pktype; -@@ -140,15 +140,21 @@ userauth_hostbased(Authctxt *authctxt) - buffer_dump(&b); - #endif - -- pubkey_auth_info(authctxt, key, -- "client user \"%.100s\", client host \"%.100s\"", cuser, chost); -+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); -+ auth_info(authctxt, -+ "%s, client user \"%.100s\", client host \"%.100s\"", -+ pubkey, cuser, chost); - - /* 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), -- buffer_len(&b))) == 1) -+ buffer_len(&b))) == 1) { - authenticated = 1; -+ authctxt->last_details = pubkey; -+ } else { -+ free(pubkey); -+ } - - buffer_free(&b); - done: -diff -up openssh-7.4p1/auth2-pubkey.c.expose-pam openssh-7.4p1/auth2-pubkey.c ---- openssh-7.4p1/auth2-pubkey.c.expose-pam 2016-12-23 15:40:26.746447864 +0100 -+++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 15:40:26.819447876 +0100 -@@ -79,7 +79,7 @@ userauth_pubkey(Authctxt *authctxt) - { - Buffer b; - Key *key = NULL; -- char *pkalg, *userstyle, *fp = NULL; -+ char *pkalg, *userstyle, *pubkey, *fp = NULL; - u_char *pkblob, *sig; - u_int alen, blen, slen; - int have_sig, pktype; -@@ -177,7 +177,8 @@ userauth_pubkey(Authctxt *authctxt) - #ifdef DEBUG_PK - buffer_dump(&b); - #endif -- pubkey_auth_info(authctxt, key, NULL); -+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); -+ auth_info(authctxt, "%s", pubkey); - - /* test for correct signature */ - authenticated = 0; -@@ -185,9 +186,12 @@ userauth_pubkey(Authctxt *authctxt) - PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) { - authenticated = 1; -+ authctxt->last_details = pubkey; - /* Record the successful key to prevent reuse */ - auth2_record_userkey(authctxt, key); - key = NULL; /* Don't free below */ -+ } else { -+ free(pubkey); - } - buffer_free(&b); - free(sig); -@@ -228,7 +232,7 @@ done: - void - pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) - { -- char *fp, *extra; -+ char *extra, *pubkey; - va_list ap; - int i; - -@@ -238,27 +242,13 @@ pubkey_auth_info(Authctxt *authctxt, con - i = vasprintf(&extra, fmt, ap); - va_end(ap); - if (i < 0 || extra == NULL) -- fatal("%s: vasprintf failed", __func__); -+ fatal("%s: vasprintf failed", __func__); - } - -- if (key_is_cert(key)) { -- fp = sshkey_fingerprint(key->cert->signature_key, -- options.fingerprint_hash, SSH_FP_DEFAULT); -- auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", -- key_type(key), key->cert->key_id, -- (unsigned long long)key->cert->serial, -- key_type(key->cert->signature_key), -- fp == NULL ? "(null)" : fp, -- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); -- free(fp); -- } else { -- fp = sshkey_fingerprint(key, options.fingerprint_hash, -- SSH_FP_DEFAULT); -- auth_info(authctxt, "%s %s%s%s", key_type(key), -- fp == NULL ? "(null)" : fp, -- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); -- free(fp); -- } -+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); -+ auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ", -+ extra == NULL ? "" : extra); -+ free(pubkey); - free(extra); - } - -diff -up openssh-7.4p1/auth.h.expose-pam openssh-7.4p1/auth.h ---- openssh-7.4p1/auth.h.expose-pam 2016-12-23 15:40:26.782447870 +0100 -+++ openssh-7.4p1/auth.h 2016-12-23 15:40:26.819447876 +0100 -@@ -84,6 +84,9 @@ struct Authctxt { - - struct sshkey **prev_userkeys; - u_int nprev_userkeys; -+ -+ char *last_details; -+ char *auth_details; - }; - /* - * Every authentication method has to handle authentication requests for -diff -up openssh-7.4p1/auth-pam.c.expose-pam openssh-7.4p1/auth-pam.c ---- openssh-7.4p1/auth-pam.c.expose-pam 2016-12-23 15:40:26.731447862 +0100 -+++ openssh-7.4p1/auth-pam.c 2016-12-23 15:40:26.819447876 +0100 -@@ -688,6 +688,11 @@ sshpam_init_ctx(Authctxt *authctxt) - return (NULL); - } - -+ /* Notify PAM about any already successful auth methods */ -+ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMONLY && -+ authctxt->auth_details) -+ do_pam_putenv("SSH_USER_AUTH", authctxt->auth_details); -+ - ctxt = xcalloc(1, sizeof *ctxt); - - /* Start the authentication thread */ -diff -up openssh-7.4p1/gss-serv.c.expose-pam openssh-7.4p1/gss-serv.c ---- openssh-7.4p1/gss-serv.c.expose-pam 2016-12-23 15:40:26.808447874 +0100 -+++ openssh-7.4p1/gss-serv.c 2016-12-23 15:40:26.819447876 +0100 -@@ -441,6 +441,16 @@ ssh_gssapi_do_child(char ***envp, u_int - } - - /* Privileged */ -+char* -+ssh_gssapi_get_displayname(void) -+{ -+ if (gssapi_client.displayname.length != 0 && -+ gssapi_client.displayname.value != NULL) -+ return strdup((char *)gssapi_client.displayname.value); -+ return NULL; -+} -+ -+/* Privileged */ - int - ssh_gssapi_userok(char *user, struct passwd *pw) - { -diff -up openssh-7.4p1/monitor.c.expose-pam openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 15:41:16.473455863 +0100 -@@ -300,6 +300,7 @@ monitor_child_preauth(Authctxt *_authctx - struct ssh *ssh = active_state; /* XXX */ - struct mon_table *ent; - int authenticated = 0, partial = 0; -+ char *prev_auth_details; - - debug3("preauth child monitor started"); - -@@ -330,6 +331,18 @@ monitor_child_preauth(Authctxt *_authctx - auth_submethod = NULL; - authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); - -+ if (authenticated) { -+ prev_auth_details = authctxt->auth_details; -+ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", -+ prev_auth_details ? prev_auth_details : "", -+ prev_auth_details ? ", " : "", auth_method, -+ authctxt->last_details ? ": " : "", -+ authctxt->last_details ? authctxt->last_details : ""); -+ free(prev_auth_details); -+ } -+ free(authctxt->last_details); -+ authctxt->last_details = NULL; -+ - /* Special handling for multiple required authentications */ - if (options.num_auth_methods != 0) { - if (authenticated && -@@ -1417,6 +1430,10 @@ mm_answer_keyverify(int sock, Buffer *m) - debug3("%s: key %p signature %s", - __func__, key, (verified == 1) ? "verified" : "unverified"); - -+ if (verified == 1) -+ authctxt->last_details = sshkey_format_oneline(key, -+ options.fingerprint_hash); -+ - /* If auth was successful then record key to ensure it isn't reused */ - if (verified == 1 && key_blobtype == MM_USERKEY) - auth2_record_userkey(authctxt, key); -@@ -1860,6 +1877,9 @@ mm_answer_gss_userok(int sock, Buffer *m - - auth_method = "gssapi-with-mic"; - -+ if (authenticated) -+ authctxt->last_details = ssh_gssapi_get_displayname(); -+ - /* Monitor loop will terminate if authenticated */ - return (authenticated); - } -diff -up openssh-7.4p1/servconf.c.expose-pam openssh-7.4p1/servconf.c ---- openssh-7.4p1/servconf.c.expose-pam 2016-12-23 15:40:26.810447875 +0100 -+++ openssh-7.4p1/servconf.c 2016-12-23 15:44:04.691482920 +0100 -@@ -171,6 +171,7 @@ initialize_server_options(ServerOptions - options->disable_forwarding = -1; - options->use_kuserok = -1; - options->enable_k5users = -1; -+ options->expose_auth_methods = -1; - } - - /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -354,6 +355,8 @@ fill_default_server_options(ServerOption - options->use_kuserok = 1; - if (options->enable_k5users == -1) - options->enable_k5users = 0; -+ if (options->expose_auth_methods == -1) -+ options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER; - - assemble_algorithms(options); - -@@ -439,6 +442,7 @@ typedef enum { - sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, - sStreamLocalBindMask, sStreamLocalBindUnlink, - sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, -+ sExposeAuthenticationMethods, - sDeprecated, sIgnore, sUnsupported - } ServerOpCodes; - -@@ -595,6 +599,7 @@ static struct { - { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, - { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, - { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, -+ { "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL }, - { NULL, sBadOption, 0 } - }; - -@@ -984,6 +989,12 @@ static const struct multistate multistat - { "local", FORWARD_LOCAL }, - { NULL, -1 } - }; -+static const struct multistate multistate_exposeauthmeth[] = { -+ { "never", EXPOSE_AUTHMETH_NEVER }, -+ { "pam-only", EXPOSE_AUTHMETH_PAMONLY }, -+ { "pam-and-env", EXPOSE_AUTHMETH_PAMENV }, -+ { NULL, -1} -+}; - - int - process_server_config_line(ServerOptions *options, char *line, -@@ -1902,6 +1913,11 @@ process_server_config_line(ServerOptions - options->fingerprint_hash = value; - break; - -+ case sExposeAuthenticationMethods: -+ intptr = &options->expose_auth_methods; -+ multistate_ptr = multistate_exposeauthmeth; -+ goto parse_multistate; -+ - case sDeprecated: - case sIgnore: - case sUnsupported: -@@ -2060,6 +2076,7 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(enable_k5users); - M_CP_INTOPT(rekey_limit); - M_CP_INTOPT(rekey_interval); -+ M_CP_INTOPT(expose_auth_methods); - - /* - * The bind_mask is a mode_t that may be unsigned, so we can't use -@@ -2176,6 +2193,8 @@ fmt_intarg(ServerOpCodes code, int val) - return fmt_multistate_int(val, multistate_tcpfwd); - case sFingerprintHash: - return ssh_digest_alg_name(val); -+ case sExposeAuthenticationMethods: -+ return fmt_multistate_int(val, multistate_exposeauthmeth); - default: - switch (val) { - case 0: -@@ -2356,6 +2375,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); - dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); -+ dump_cfg_fmtint(sExposeAuthenticationMethods, o->expose_auth_methods); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-7.4p1/servconf.h.expose-pam openssh-7.4p1/servconf.h ---- openssh-7.4p1/servconf.h.expose-pam 2016-12-23 15:40:26.810447875 +0100 -+++ openssh-7.4p1/servconf.h 2016-12-23 15:40:26.821447876 +0100 -@@ -48,6 +48,11 @@ - #define FORWARD_LOCAL (1<<1) - #define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) - -+/* Expose AuthenticationMethods */ -+#define EXPOSE_AUTHMETH_NEVER 0 -+#define EXPOSE_AUTHMETH_PAMONLY 1 -+#define EXPOSE_AUTHMETH_PAMENV 2 -+ - #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ - #define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ - -@@ -195,6 +200,8 @@ typedef struct { - char *auth_methods[MAX_AUTH_METHODS]; - - int fingerprint_hash; -+ -+ int expose_auth_methods; /* EXPOSE_AUTHMETH_* above */ - } ServerOptions; - - /* Information about the incoming connection as used by Match */ -diff -up openssh-7.4p1/session.c.expose-pam openssh-7.4p1/session.c ---- openssh-7.4p1/session.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 -+++ openssh-7.4p1/session.c 2016-12-23 15:40:26.821447876 +0100 -@@ -997,6 +997,12 @@ copy_environment(char **source, char *** - } - *var_val++ = '\0'; - -+ if (options.expose_auth_methods < EXPOSE_AUTHMETH_PAMENV && -+ strcmp(var_name, "SSH_USER_AUTH") == 0) { -+ free(var_name); -+ continue; -+ } -+ - debug3("Copy environment: %s=%s", var_name, var_val); - child_set_env(env, envsize, var_name, var_val); - -@@ -1173,6 +1179,11 @@ do_setup_env(Session *s, const char *she - } - #endif /* USE_PAM */ - -+ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMENV && -+ s->authctxt->auth_details) -+ child_set_env(&env, &envsize, "SSH_USER_AUTH", -+ s->authctxt->auth_details); -+ - if (auth_sock_name != NULL) - child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, - auth_sock_name); -@@ -2561,6 +2572,9 @@ do_cleanup(Authctxt *authctxt) - if (authctxt == NULL) - return; - -+ free(authctxt->auth_details); -+ authctxt->auth_details = NULL; -+ - #ifdef USE_PAM - if (options.use_pam) { - sshpam_cleanup(); -diff -up openssh-7.4p1/ssh.1.expose-pam openssh-7.4p1/ssh.1 ---- openssh-7.4p1/ssh.1.expose-pam 2016-12-23 15:40:26.810447875 +0100 -+++ openssh-7.4p1/ssh.1 2016-12-23 15:40:26.822447877 +0100 -@@ -1421,6 +1421,10 @@ server IP address, and server port numbe - This variable contains the original command line if a forced command - is executed. - It can be used to extract the original arguments. -+.It Ev SSH_USER_AUTH -+This variable contains, for SSH2 only, a comma-separated list of authentication -+methods that were successfuly used to authenticate. When possible, these -+methods are extended with detailed information on the credential used. - .It Ev SSH_TTY - This is set to the name of the tty (path to the device) associated - with the current shell or command. -diff -up openssh-7.4p1/sshd_config.5.expose-pam openssh-7.4p1/sshd_config.5 ---- openssh-7.4p1/sshd_config.5.expose-pam 2016-12-23 15:40:26.822447877 +0100 -+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:45:22.411495421 +0100 -@@ -570,6 +570,21 @@ Disables all forwarding features, includ - TCP and StreamLocal. - This option overrides all other forwarding-related options and may - simplify restricted configurations. -+.It Cm ExposeAuthenticationMethods -+When using SSH2, this option controls the exposure of the list of -+successful authentication methods to PAM during the authentication -+and to the shell environment via the -+.Cm SSH_USER_AUTH -+variable. See the description of this variable for more details. -+Valid options are: -+.Cm never -+(Do not expose successful authentication methods), -+.Cm pam-only -+(Only expose them to PAM during authentication, not afterwards), -+.Cm pam-and-env -+(Expose them to PAM and keep them in the shell environment). -+The default is -+.Cm never . - .It Cm FingerprintHash - Specifies the hash algorithm used when logging key fingerprints. - Valid options are: -diff -up openssh-7.4p1/ssh-gss.h.expose-pam openssh-7.4p1/ssh-gss.h ---- openssh-7.4p1/ssh-gss.h.expose-pam 2016-12-23 15:40:26.811447875 +0100 -+++ openssh-7.4p1/ssh-gss.h 2016-12-23 15:40:26.823447877 +0100 -@@ -159,6 +159,7 @@ int ssh_gssapi_server_check_mech(Gssctxt - const char *); - OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); - int ssh_gssapi_userok(char *name, struct passwd *); -+char* ssh_gssapi_get_displayname(void); - OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); - void ssh_gssapi_do_child(char ***, u_int *); - void ssh_gssapi_cleanup_creds(void); -diff -up openssh-7.4p1/sshkey.c.expose-pam openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.expose-pam 2016-12-23 15:40:26.777447869 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 15:40:26.823447877 +0100 -@@ -57,6 +57,7 @@ - #define SSHKEY_INTERNAL - #include "sshkey.h" - #include "match.h" -+#include "xmalloc.h" - - /* openssh private key file format */ - #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" -@@ -1191,6 +1192,30 @@ sshkey_fingerprint(const struct sshkey * - return retval; - } - -+char * -+sshkey_format_oneline(const struct sshkey *key, int dgst_alg) -+{ -+ char *fp, *result; -+ -+ if (sshkey_is_cert(key)) { -+ fp = sshkey_fingerprint(key->cert->signature_key, dgst_alg, -+ SSH_FP_DEFAULT); -+ xasprintf(&result, "%s ID %s (serial %llu) CA %s %s", -+ sshkey_type(key), key->cert->key_id, -+ (unsigned long long)key->cert->serial, -+ sshkey_type(key->cert->signature_key), -+ fp == NULL ? "(null)" : fp); -+ free(fp); -+ } else { -+ fp = sshkey_fingerprint(key, dgst_alg, SSH_FP_DEFAULT); -+ xasprintf(&result, "%s %s", sshkey_type(key), -+ fp == NULL ? "(null)" : fp); -+ free(fp); -+ } -+ -+ return result; -+} -+ - #ifdef WITH_SSH1 - /* - * Reads a multiple-precision integer in decimal from the buffer, and advances -diff -up openssh-7.4p1/sshkey.h.expose-pam openssh-7.4p1/sshkey.h ---- openssh-7.4p1/sshkey.h.expose-pam 2016-12-23 15:40:26.777447869 +0100 -+++ openssh-7.4p1/sshkey.h 2016-12-23 15:40:26.823447877 +0100 -@@ -124,6 +124,7 @@ char *sshkey_fingerprint(const struct s - int, enum sshkey_fp_rep); - int sshkey_fingerprint_raw(const struct sshkey *k, - int, u_char **retp, size_t *lenp); -+char *sshkey_format_oneline(const struct sshkey *k, int dgst_alg); - const char *sshkey_type(const struct sshkey *); - const char *sshkey_cert_type(const struct sshkey *); - int sshkey_write(const struct sshkey *, FILE *); diff --git a/openssh-7.3p1-openssl-1.1.0.patch b/openssh-7.3p1-openssl-1.1.0.patch index baa0152..70284dd 100644 --- a/openssh-7.3p1-openssl-1.1.0.patch +++ b/openssh-7.3p1-openssl-1.1.0.patch @@ -1,103 +1,7 @@ -diff -up openssh-7.4p1/authfd.c.openssl openssh-7.4p1/authfd.c ---- openssh-7.4p1/authfd.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/authfd.c 2016-12-23 17:47:36.429817751 +0100 -@@ -207,15 +207,22 @@ deserialise_identity1(struct sshbuf *ids - int r, keybits; - u_int32_t bits; - char *comment = NULL; -+ BIGNUM *e = NULL, *n = NULL; - - if ((key = sshkey_new(KEY_RSA1)) == NULL) - return SSH_ERR_ALLOC_FAIL; -- if ((r = sshbuf_get_u32(ids, &bits)) != 0 || -- (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 || -- (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) -+ if ((e = BN_new()) == NULL || -+ (n = BN_new()) == NULL || -+ (r = sshbuf_get_u32(ids, &bits)) != 0 || -+ (r = sshbuf_get_bignum1(ids, e)) != 0 || -+ (r = sshbuf_get_bignum1(ids, n)) != 0 || -+ (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0 || -+ (RSA_set0_key(key->rsa, n, e, NULL) == 0)) { -+ BN_free(n); -+ BN_free(e); - goto out; -- keybits = BN_num_bits(key->rsa->n); -+ } -+ keybits = BN_num_bits(n); - /* XXX previously we just warned here. I think we should be strict */ - if (keybits < 0 || bits != (u_int)keybits) { - r = SSH_ERR_KEY_BITS_MISMATCH; -@@ -393,15 +400,17 @@ ssh_decrypt_challenge(int sock, struct s - struct sshbuf *msg; - int r; - u_char type; -+ const BIGNUM *e, *n; - - if (key->type != KEY_RSA1) - return SSH_ERR_INVALID_ARGUMENT; - if ((msg = sshbuf_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; -+ RSA_get0_key(key->rsa, &n, &e, NULL); - if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 || -- (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || -- (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 || -+ (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 || -+ (r = sshbuf_put_bignum1(msg, e)) != 0 || -+ (r = sshbuf_put_bignum1(msg, n)) != 0 || - (r = sshbuf_put_bignum1(msg, challenge)) != 0 || - (r = sshbuf_put(msg, session_id, 16)) != 0 || - (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */ -@@ -499,15 +508,19 @@ static int - ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment) - { - int r; -+ const BIGNUM *n, *e, *d, *q, *p, *iqmp; - -+ RSA_get0_key(key, &n, &e, &d); -+ RSA_get0_factors(key, &p, &q); -+ RSA_get0_crt_params(key, NULL, NULL, &iqmp); - /* To keep within the protocol: p < q for ssh. in SSL p > q */ -- if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 || -- (r = sshbuf_put_bignum1(b, key->n)) != 0 || -- (r = sshbuf_put_bignum1(b, key->e)) != 0 || -- (r = sshbuf_put_bignum1(b, key->d)) != 0 || -- (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 || -- (r = sshbuf_put_bignum1(b, key->q)) != 0 || -- (r = sshbuf_put_bignum1(b, key->p)) != 0 || -+ if ((r = sshbuf_put_u32(b, BN_num_bits(n))) != 0 || -+ (r = sshbuf_put_bignum1(b, n)) != 0 || -+ (r = sshbuf_put_bignum1(b, e)) != 0 || -+ (r = sshbuf_put_bignum1(b, d)) != 0 || -+ (r = sshbuf_put_bignum1(b, iqmp)) != 0 || -+ (r = sshbuf_put_bignum1(b, q)) != 0 || -+ (r = sshbuf_put_bignum1(b, p)) != 0 || - (r = sshbuf_put_cstring(b, comment)) != 0) - return r; - return 0; -@@ -622,11 +635,13 @@ ssh_remove_identity(int sock, struct ssh - - #ifdef WITH_SSH1 - if (key->type == KEY_RSA1) { -+ const BIGNUM *e, *n; -+ RSA_get0_key(key->rsa, &n, &e, NULL); - if ((r = sshbuf_put_u8(msg, - SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 || -- (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || -- (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0) -+ (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 || -+ (r = sshbuf_put_bignum1(msg, e)) != 0 || -+ (r = sshbuf_put_bignum1(msg, n)) != 0) - goto out; - } else - #endif -diff -up openssh-7.4p1/auth-pam.c.openssl openssh-7.4p1/auth-pam.c ---- openssh-7.4p1/auth-pam.c.openssl 2016-12-23 17:47:36.400817739 +0100 -+++ openssh-7.4p1/auth-pam.c 2016-12-23 17:47:36.430817752 +0100 -@@ -129,6 +129,10 @@ extern u_int utmp_len; +diff -up openssh/auth-pam.c.openssl openssh/auth-pam.c +--- openssh/auth-pam.c.openssl 2017-09-26 13:19:31.662248869 +0200 ++++ openssh/auth-pam.c 2017-09-26 13:19:31.793249672 +0200 +@@ -128,6 +128,10 @@ extern u_int utmp_len; typedef pthread_t sp_pthread_t; #else typedef pid_t sp_pthread_t; @@ -108,169 +12,10 @@ diff -up openssh-7.4p1/auth-pam.c.openssl openssh-7.4p1/auth-pam.c #endif struct pam_ctxt { -diff -up openssh-7.4p1/cipher-3des1.c.openssl openssh-7.4p1/cipher-3des1.c ---- openssh-7.4p1/cipher-3des1.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/cipher-3des1.c 2016-12-23 17:47:36.430817752 +0100 -@@ -44,7 +44,7 @@ - */ - struct ssh1_3des_ctx - { -- EVP_CIPHER_CTX k1, k2, k3; -+ EVP_CIPHER_CTX *k1, *k2, *k3; - }; - - const EVP_CIPHER * evp_ssh1_3des(void); -@@ -65,7 +65,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons - if (key == NULL) - return 1; - if (enc == -1) -- enc = ctx->encrypt; -+ enc = EVP_CIPHER_CTX_encrypting(ctx); - k1 = k2 = k3 = (u_char *) key; - k2 += 8; - if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { -@@ -74,12 +74,19 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, cons - else - k1 += 16; - } -- EVP_CIPHER_CTX_init(&c->k1); -- EVP_CIPHER_CTX_init(&c->k2); -- EVP_CIPHER_CTX_init(&c->k3); -- if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || -- EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || -- EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { -+ c->k1 = EVP_CIPHER_CTX_new(); -+ c->k2 = EVP_CIPHER_CTX_new(); -+ c->k3 = EVP_CIPHER_CTX_new(); -+ if (c->k1 == NULL || c->k2 == NULL || c->k3 == NULL) { -+ EVP_CIPHER_CTX_free(c->k1); -+ EVP_CIPHER_CTX_free(c->k2); -+ EVP_CIPHER_CTX_free(c->k3); -+ free(c); -+ return 0; -+ } -+ if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || -+ EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || -+ EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { - explicit_bzero(c, sizeof(*c)); - free(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); -@@ -95,9 +102,9 @@ ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_cha - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) - return 0; -- if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || -- EVP_Cipher(&c->k2, dest, dest, len) == 0 || -- EVP_Cipher(&c->k3, dest, dest, len) == 0) -+ if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 || -+ EVP_Cipher(c->k2, dest, dest, len) == 0 || -+ EVP_Cipher(c->k3, dest, dest, len) == 0) - return 0; - return 1; - } -@@ -108,9 +115,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) - struct ssh1_3des_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { -- EVP_CIPHER_CTX_cleanup(&c->k1); -- EVP_CIPHER_CTX_cleanup(&c->k2); -- EVP_CIPHER_CTX_cleanup(&c->k3); -+ EVP_CIPHER_CTX_free(c->k1); -+ EVP_CIPHER_CTX_free(c->k2); -+ EVP_CIPHER_CTX_free(c->k3); - explicit_bzero(c, sizeof(*c)); - free(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); -@@ -128,13 +135,13 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do - if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) - return SSH_ERR_INTERNAL_ERROR; - if (doset) { -- memcpy(c->k1.iv, iv, 8); -- memcpy(c->k2.iv, iv + 8, 8); -- memcpy(c->k3.iv, iv + 16, 8); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8); - } else { -- memcpy(iv, c->k1.iv, 8); -- memcpy(iv + 8, c->k2.iv, 8); -- memcpy(iv + 16, c->k3.iv, 8); -+ memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8); -+ memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8); -+ memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8); - } - return 0; - } -@@ -142,17 +149,14 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int do - const EVP_CIPHER * - evp_ssh1_3des(void) - { -- static EVP_CIPHER ssh1_3des; -+ EVP_CIPHER *ssh1_3des; - -- memset(&ssh1_3des, 0, sizeof(ssh1_3des)); -- ssh1_3des.nid = NID_undef; -- ssh1_3des.block_size = 8; -- ssh1_3des.iv_len = 0; -- ssh1_3des.key_len = 16; -- ssh1_3des.init = ssh1_3des_init; -- ssh1_3des.cleanup = ssh1_3des_cleanup; -- ssh1_3des.do_cipher = ssh1_3des_cbc; -- ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; -- return &ssh1_3des; -+ ssh1_3des = EVP_CIPHER_meth_new(NID_undef, 8, 16); -+ EVP_CIPHER_meth_set_iv_length(ssh1_3des, 0); -+ EVP_CIPHER_meth_set_init(ssh1_3des, ssh1_3des_init); -+ EVP_CIPHER_meth_set_cleanup(ssh1_3des, ssh1_3des_cleanup); -+ EVP_CIPHER_meth_set_do_cipher(ssh1_3des, ssh1_3des_cbc); -+ EVP_CIPHER_meth_set_flags(ssh1_3des, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH); -+ return ssh1_3des; - } - #endif /* WITH_SSH1 */ -diff -up openssh-7.4p1/cipher-bf1.c.openssl openssh-7.4p1/cipher-bf1.c ---- openssh-7.4p1/cipher-bf1.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/cipher-bf1.c 2016-12-23 17:47:36.430817752 +0100 -@@ -89,17 +89,28 @@ bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_ch - const EVP_CIPHER * - evp_ssh1_bf(void) - { -- static EVP_CIPHER ssh1_bf; -+ EVP_CIPHER *ssh1_bf; - -- memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER)); -- orig_bf = ssh1_bf.do_cipher; -- ssh1_bf.nid = NID_undef; -+ orig_bf = EVP_CIPHER_meth_get_do_cipher(EVP_bf_cbc()); -+ /* block_size, length, flags from openssl/crypto/engine/eng_cryptodev.c:638 */ -+ ssh1_bf = EVP_CIPHER_meth_new(NID_undef, 8, 32); -+ EVP_CIPHER_meth_set_iv_length(ssh1_bf, 8); -+ EVP_CIPHER_meth_set_flags(ssh1_bf, EVP_CIPH_CBC_MODE); - #ifdef SSH_OLD_EVP -- ssh1_bf.init = bf_ssh1_init; -+ EVP_CIPHER_meth_set_init(ssh1_bf, ssh1_bf_init); -+#else -+ EVP_CIPHER_meth_set_init(ssh1_bf, -+ EVP_CIPHER_meth_get_init(EVP_bf_cbc())); - #endif -- ssh1_bf.do_cipher = bf_ssh1_cipher; -- ssh1_bf.key_len = 32; -- return (&ssh1_bf); -+ /* copy methods and parameters from old EVP_BF_cbc() -+ * meth_dup does not allow to change type and key_len */ -+ EVP_CIPHER_meth_set_cleanup(ssh1_bf, -+ EVP_CIPHER_meth_get_cleanup(EVP_bf_cbc())); -+ EVP_CIPHER_meth_set_ctrl(ssh1_bf, -+ EVP_CIPHER_meth_get_ctrl(EVP_bf_cbc())); -+ /* ASN1 params??? */ -+ EVP_CIPHER_meth_set_do_cipher(ssh1_bf, bf_ssh1_cipher); -+ return ssh1_bf; - } - #endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */ - -diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c ---- openssh-7.4p1/cipher.c.openssl 2016-12-23 17:47:36.418817747 +0100 -+++ openssh-7.4p1/cipher.c 2016-12-23 17:47:36.430817752 +0100 -@@ -368,7 +368,7 @@ cipher_init(struct sshcipher_ctx **ccp, +diff -up openssh/cipher.c.openssl openssh/cipher.c +--- openssh/cipher.c.openssl 2017-09-26 13:19:31.782249605 +0200 ++++ openssh/cipher.c 2017-09-26 13:27:37.424040367 +0200 +@@ -283,7 +283,7 @@ cipher_init(struct sshcipher_ctx **ccp, ret = SSH_ERR_ALLOC_FAIL; goto out; } @@ -279,7 +24,7 @@ diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c (do_encrypt == CIPHER_ENCRYPT)) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; -@@ -386,10 +386,6 @@ cipher_init(struct sshcipher_ctx **ccp, +@@ -301,10 +301,6 @@ cipher_init(struct sshcipher_ctx **ccp, goto out; } } @@ -287,28 +32,26 @@ diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - - if (cipher->discard_len > 0) { - if ((junk = malloc(cipher->discard_len)) == NULL || -@@ -621,7 +617,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c - len, iv)) - return SSH_ERR_LIBCRYPTO_ERROR; - } else -- memcpy(iv, cc->evp->iv, len); -+ memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len); - break; + ret = 0; + #endif /* WITH_OPENSSL */ + out: +@@ -490,7 +486,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c + len, iv)) + return SSH_ERR_LIBCRYPTO_ERROR; + } else +- memcpy(iv, cc->evp->iv, len); ++ memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len); #endif - #ifdef WITH_SSH1 -@@ -667,7 +663,7 @@ cipher_set_keyiv(struct sshcipher_ctx *c - EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) - return SSH_ERR_LIBCRYPTO_ERROR; - } else -- memcpy(cc->evp->iv, iv, evplen); -+ memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen); - break; + return 0; + } +@@ -524,14 +520,14 @@ cipher_set_keyiv(struct sshcipher_ctx *c + EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) + return SSH_ERR_LIBCRYPTO_ERROR; + } else +- memcpy(cc->evp->iv, iv, evplen); ++ memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen); #endif - #ifdef WITH_SSH1 -@@ -681,8 +677,8 @@ cipher_set_keyiv(struct sshcipher_ctx *c + return 0; } #ifdef WITH_OPENSSL @@ -319,9 +62,9 @@ diff -up openssh-7.4p1/cipher.c.openssl openssh-7.4p1/cipher.c #endif int -diff -up openssh-7.4p1/ctr-cavstest.c.openssl openssh-7.4p1/ctr-cavstest.c ---- openssh-7.4p1/ctr-cavstest.c.openssl 2016-12-23 17:47:36.344817716 +0100 -+++ openssh-7.4p1/ctr-cavstest.c 2016-12-23 17:47:36.430817752 +0100 +diff -up openssh/ctr-cavstest.c.openssl openssh/ctr-cavstest.c +--- openssh/ctr-cavstest.c.openssl 2017-09-26 13:19:31.707249145 +0200 ++++ openssh/ctr-cavstest.c 2017-09-26 13:19:31.794249679 +0200 @@ -144,7 +144,7 @@ int main (int argc, char *argv[]) usage(); } @@ -331,9 +74,9 @@ diff -up openssh-7.4p1/ctr-cavstest.c.openssl openssh-7.4p1/ctr-cavstest.c c = cipher_by_name(algo); if (c == NULL) { -diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c ---- openssh-7.4p1/dh.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/dh.c 2016-12-23 17:47:36.430817752 +0100 +diff -up openssh/dh.c.openssl openssh/dh.c +--- openssh/dh.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/dh.c 2017-09-26 13:19:31.794249679 +0200 @@ -212,14 +212,15 @@ choose_dh(int min, int wantbits, int max /* diffie-hellman-groupN-sha1 */ @@ -409,7 +152,7 @@ diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c return SSH_ERR_LIBCRYPTO_ERROR; } return 0; -@@ -284,15 +290,22 @@ DH * +@@ -284,15 +289,22 @@ DH * dh_new_group_asc(const char *gen, const char *modulus) { DH *dh; @@ -439,7 +182,7 @@ diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c } /* -@@ -307,8 +320,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu +@@ -307,8 +319,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu if ((dh = DH_new()) == NULL) return NULL; @@ -449,9 +192,9 @@ diff -up openssh-7.4p1/dh.c.openssl openssh-7.4p1/dh.c return (dh); } -diff -up openssh-7.4p1/dh.h.openssl openssh-7.4p1/dh.h ---- openssh-7.4p1/dh.h.openssl 2016-12-23 17:47:36.418817747 +0100 -+++ openssh-7.4p1/dh.h 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/dh.h.openssl openssh/dh.h +--- openssh/dh.h.openssl 2017-09-26 13:19:31.783249611 +0200 ++++ openssh/dh.h 2017-09-26 13:19:31.794249679 +0200 @@ -42,7 +42,7 @@ DH *dh_new_group18(void); DH *dh_new_group_fallback(int); @@ -461,9 +204,9 @@ diff -up openssh-7.4p1/dh.h.openssl openssh-7.4p1/dh.h u_int dh_estimate(int); -diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c ---- openssh-7.4p1/digest-openssl.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/digest-openssl.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/digest-openssl.c.openssl openssh/digest-openssl.c +--- openssh/digest-openssl.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/digest-openssl.c 2017-09-26 13:19:31.795249685 +0200 @@ -43,7 +43,7 @@ struct ssh_digest_ctx { @@ -473,7 +216,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c }; struct ssh_digest { -@@ -107,7 +107,7 @@ ssh_digest_bytes(int alg) +@@ -106,7 +106,7 @@ ssh_digest_bytes(int alg) size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx) { @@ -482,7 +225,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c } struct ssh_digest_ctx * -@@ -119,8 +119,9 @@ ssh_digest_start(int alg) +@@ -118,8 +118,9 @@ ssh_digest_start(int alg) if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) return NULL; ret->alg = alg; @@ -494,7 +237,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c free(ret); return NULL; } -@@ -133,7 +134,7 @@ ssh_digest_copy_state(struct ssh_digest_ +@@ -132,7 +133,7 @@ ssh_digest_copy_state(struct ssh_digest_ if (from->alg != to->alg) return SSH_ERR_INVALID_ARGUMENT; /* we have bcopy-style order while openssl has memcpy-style */ @@ -503,7 +246,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c return SSH_ERR_LIBCRYPTO_ERROR; return 0; } -@@ -141,7 +142,7 @@ ssh_digest_copy_state(struct ssh_digest_ +@@ -140,7 +141,7 @@ ssh_digest_copy_state(struct ssh_digest_ int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) { @@ -512,7 +255,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c return SSH_ERR_LIBCRYPTO_ERROR; return 0; } -@@ -162,7 +163,7 @@ ssh_digest_final(struct ssh_digest_ctx * +@@ -161,7 +162,7 @@ ssh_digest_final(struct ssh_digest_ctx * return SSH_ERR_INVALID_ARGUMENT; if (dlen < digest->digest_len) /* No truncation allowed */ return SSH_ERR_INVALID_ARGUMENT; @@ -521,7 +264,7 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c return SSH_ERR_LIBCRYPTO_ERROR; if (l != digest->digest_len) /* sanity */ return SSH_ERR_INTERNAL_ERROR; -@@ -173,7 +174,7 @@ void +@@ -172,7 +173,7 @@ void ssh_digest_free(struct ssh_digest_ctx *ctx) { if (ctx != NULL) { @@ -530,9 +273,9 @@ diff -up openssh-7.4p1/digest-openssl.c.openssl openssh-7.4p1/digest-openssl.c explicit_bzero(ctx, sizeof(*ctx)); free(ctx); } -diff -up openssh-7.4p1/entropy.c.openssl openssh-7.4p1/entropy.c ---- openssh-7.4p1/entropy.c.openssl 2016-12-23 17:47:36.419817747 +0100 -+++ openssh-7.4p1/entropy.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/entropy.c.openssl openssh/entropy.c +--- openssh/entropy.c.openssl 2017-09-26 13:19:31.783249611 +0200 ++++ openssh/entropy.c 2017-09-26 13:19:31.795249685 +0200 @@ -218,7 +218,9 @@ seed_rng(void) "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); @@ -543,9 +286,9 @@ diff -up openssh-7.4p1/entropy.c.openssl openssh-7.4p1/entropy.c #ifndef OPENSSL_PRNG_ONLY if (RAND_status() == 1) { -diff -up openssh-7.4p1/gss-genr.c.openssl openssh-7.4p1/gss-genr.c ---- openssh-7.4p1/gss-genr.c.openssl 2016-12-23 17:47:36.392817736 +0100 -+++ openssh-7.4p1/gss-genr.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/gss-genr.c.openssl openssh/gss-genr.c +--- openssh/gss-genr.c.openssl 2017-09-26 13:19:31.773249550 +0200 ++++ openssh/gss-genr.c 2017-09-26 13:19:31.796249691 +0200 @@ -99,7 +99,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup u_char digest[EVP_MAX_MD_SIZE]; char deroid[2]; @@ -589,10 +332,10 @@ diff -up openssh-7.4p1/gss-genr.c.openssl openssh-7.4p1/gss-genr.c gss_enc2oid[oidpos].oid = NULL; gss_enc2oid[oidpos].encoded = NULL; -diff -up openssh-7.4p1/includes.h.openssl openssh-7.4p1/includes.h ---- openssh-7.4p1/includes.h.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/includes.h 2016-12-23 17:47:36.431817752 +0100 -@@ -163,6 +163,7 @@ +diff -up openssh/includes.h.openssl openssh/includes.h +--- openssh/includes.h.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/includes.h 2017-09-26 13:19:31.796249691 +0200 +@@ -166,6 +166,7 @@ #ifdef WITH_OPENSSL #include /* For OPENSSL_VERSION_NUMBER */ @@ -600,9 +343,9 @@ diff -up openssh-7.4p1/includes.h.openssl openssh-7.4p1/includes.h #endif #include "defines.h" -diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c ---- openssh-7.4p1/kexdhc.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kexdhc.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/kexdhc.c.openssl openssh/kexdhc.c +--- openssh/kexdhc.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/kexdhc.c 2017-09-26 13:19:31.797249697 +0200 @@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh) { struct kex *kex = ssh->kex; @@ -643,7 +386,7 @@ diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c return r; } -@@ -110,6 +117,7 @@ input_kex_dh(int type, u_int32_t seq, vo +@@ -109,6 +116,7 @@ input_kex_dh(int type, u_int32_t seq, st u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t klen = 0, slen, sbloblen, hashlen; int kout, r; @@ -651,7 +394,7 @@ diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c if (kex->verify_host_key == NULL) { r = SSH_ERR_INVALID_ARGUMENT; -@@ -169,6 +177,7 @@ input_kex_dh(int type, u_int32_t seq, vo +@@ -168,6 +176,7 @@ input_kex_dh(int type, u_int32_t seq, st #endif /* calc and verify H */ @@ -659,7 +402,7 @@ diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c hashlen = sizeof(hash); if ((r = kex_dh_hash( kex->hash_alg, -@@ -177,7 +186,7 @@ input_kex_dh(int type, u_int32_t seq, vo +@@ -176,7 +185,7 @@ input_kex_dh(int type, u_int32_t seq, st sshbuf_ptr(kex->my), sshbuf_len(kex->my), sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, @@ -668,9 +411,9 @@ diff -up openssh-7.4p1/kexdhc.c.openssl openssh-7.4p1/kexdhc.c dh_server_pub, shared_secret, hash, &hashlen)) != 0) -diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c ---- openssh-7.4p1/kexdhs.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/kexdhs.c 2016-12-23 17:47:36.431817752 +0100 +diff -up openssh/kexdhs.c.openssl openssh/kexdhs.c +--- openssh/kexdhs.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/kexdhs.c 2017-09-26 13:19:31.797249697 +0200 @@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh) ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); r = 0; @@ -682,7 +425,7 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c return r; } -@@ -102,6 +106,7 @@ input_kex_dh_init(int type, u_int32_t se +@@ -101,6 +105,7 @@ input_kex_dh_init(int type, u_int32_t se size_t sbloblen, slen; size_t klen = 0, hashlen; int kout, r; @@ -690,7 +433,7 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { -@@ -164,6 +169,7 @@ input_kex_dh_init(int type, u_int32_t se +@@ -163,6 +168,7 @@ input_kex_dh_init(int type, u_int32_t se goto out; /* calc H */ hashlen = sizeof(hash); @@ -698,7 +441,7 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c if ((r = kex_dh_hash( kex->hash_alg, kex->client_version_string, -@@ -172,7 +178,7 @@ input_kex_dh_init(int type, u_int32_t se +@@ -171,7 +177,7 @@ input_kex_dh_init(int type, u_int32_t se sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, dh_client_pub, @@ -707,7 +450,7 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c shared_secret, hash, &hashlen)) != 0) goto out; -@@ -198,7 +204,7 @@ input_kex_dh_init(int type, u_int32_t se +@@ -197,7 +203,7 @@ input_kex_dh_init(int type, u_int32_t se /* send server hostkey, DH pubkey 'f' and singed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || @@ -716,10 +459,10 @@ diff -up openssh-7.4p1/kexdhs.c.openssl openssh-7.4p1/kexdhs.c (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; -diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c ---- openssh-7.4p1/kexgexc.c.openssl 2016-12-23 17:47:36.419817747 +0100 -+++ openssh-7.4p1/kexgexc.c 2016-12-23 17:47:36.431817752 +0100 -@@ -96,6 +96,7 @@ input_kex_dh_gex_group(int type, u_int32 +diff -up openssh/kexgexc.c.openssl openssh/kexgexc.c +--- openssh/kexgexc.c.openssl 2017-09-26 13:19:31.783249611 +0200 ++++ openssh/kexgexc.c 2017-09-26 13:19:31.797249697 +0200 +@@ -95,6 +95,7 @@ input_kex_dh_gex_group(int type, u_int32 struct kex *kex = ssh->kex; BIGNUM *p = NULL, *g = NULL; int r, bits; @@ -727,7 +470,7 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); -@@ -120,26 +121,30 @@ input_kex_dh_gex_group(int type, u_int32 +@@ -119,26 +120,30 @@ input_kex_dh_gex_group(int type, u_int32 p = g = NULL; /* belong to kex->dh now */ /* generate and send 'e', client DH public key */ @@ -766,7 +509,7 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c return r; } -@@ -154,6 +159,7 @@ input_kex_dh_gex_reply(int type, u_int32 +@@ -152,6 +157,7 @@ input_kex_dh_gex_reply(int type, u_int32 u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t klen = 0, slen, sbloblen, hashlen; int kout, r; @@ -774,7 +517,7 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); if (kex->verify_host_key == NULL) { -@@ -220,6 +226,8 @@ input_kex_dh_gex_reply(int type, u_int32 +@@ -214,6 +220,8 @@ input_kex_dh_gex_reply(int type, u_int32 kex->min = kex->max = -1; /* calc and verify H */ @@ -783,7 +526,7 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c hashlen = sizeof(hash); if ((r = kexgex_hash( kex->hash_alg, -@@ -229,8 +237,8 @@ input_kex_dh_gex_reply(int type, u_int32 +@@ -223,8 +231,8 @@ input_kex_dh_gex_reply(int type, u_int32 sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, kex->min, kex->nbits, kex->max, @@ -794,10 +537,10 @@ diff -up openssh-7.4p1/kexgexc.c.openssl openssh-7.4p1/kexgexc.c dh_server_pub, shared_secret, hash, &hashlen)) != 0) -diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c ---- openssh-7.4p1/kexgexs.c.openssl 2016-12-23 17:47:36.419817747 +0100 -+++ openssh-7.4p1/kexgexs.c 2016-12-23 17:47:36.432817753 +0100 -@@ -73,6 +73,7 @@ input_kex_dh_gex_request(int type, u_int +diff -up openssh/kexgexs.c.openssl openssh/kexgexs.c +--- openssh/kexgexs.c.openssl 2017-09-26 13:19:31.783249611 +0200 ++++ openssh/kexgexs.c 2017-09-26 13:19:31.797249697 +0200 +@@ -72,6 +72,7 @@ input_kex_dh_gex_request(int type, u_int struct kex *kex = ssh->kex; int r; u_int min = 0, max = 0, nbits = 0; @@ -805,7 +548,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); if ((r = sshpkt_get_u32(ssh, &min)) != 0 || -@@ -102,9 +103,10 @@ input_kex_dh_gex_request(int type, u_int +@@ -101,9 +102,10 @@ input_kex_dh_gex_request(int type, u_int goto out; } debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); @@ -818,7 +561,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c (r = sshpkt_send(ssh)) != 0) goto out; -@@ -116,6 +118,10 @@ input_kex_dh_gex_request(int type, u_int +@@ -115,6 +117,10 @@ input_kex_dh_gex_request(int type, u_int ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); r = 0; out: @@ -829,7 +572,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c return r; } -@@ -131,6 +137,7 @@ input_kex_dh_gex_init(int type, u_int32_ +@@ -129,6 +135,7 @@ input_kex_dh_gex_init(int type, u_int32_ size_t sbloblen, slen; size_t klen = 0, hashlen; int kout, r; @@ -837,7 +580,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) { -@@ -193,6 +200,8 @@ input_kex_dh_gex_init(int type, u_int32_ +@@ -191,6 +198,8 @@ input_kex_dh_gex_init(int type, u_int32_ goto out; /* calc H */ hashlen = sizeof(hash); @@ -846,7 +589,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c if ((r = kexgex_hash( kex->hash_alg, kex->client_version_string, -@@ -201,9 +210,9 @@ input_kex_dh_gex_init(int type, u_int32_ +@@ -199,9 +208,9 @@ input_kex_dh_gex_init(int type, u_int32_ sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, kex->min, kex->nbits, kex->max, @@ -858,7 +601,7 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c shared_secret, hash, &hashlen)) != 0) goto out; -@@ -229,7 +238,7 @@ input_kex_dh_gex_init(int type, u_int32_ +@@ -227,7 +236,7 @@ input_kex_dh_gex_init(int type, u_int32_ /* send server hostkey, DH pubkey 'f' and singed H */ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || @@ -867,10 +610,10 @@ diff -up openssh-7.4p1/kexgexs.c.openssl openssh-7.4p1/kexgexs.c (r = sshpkt_put_string(ssh, signature, slen)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; -diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c ---- openssh-7.4p1/kexgssc.c.openssl 2016-12-23 17:47:36.349817718 +0100 -+++ openssh-7.4p1/kexgssc.c 2016-12-23 17:47:36.432817753 +0100 -@@ -58,6 +58,7 @@ kexgss_client(struct ssh *ssh) { +diff -up openssh/kexgssc.c.openssl openssh/kexgssc.c +--- openssh/kexgssc.c.openssl 2017-09-26 13:19:31.771249537 +0200 ++++ openssh/kexgssc.c 2017-09-26 13:19:31.797249697 +0200 +@@ -59,6 +59,7 @@ kexgss_client(struct ssh *ssh) { BIGNUM *shared_secret = NULL; BIGNUM *p = NULL; BIGNUM *g = NULL; @@ -878,7 +621,7 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c u_char *kbuf; u_char *serverhostkey = NULL; u_char *empty = ""; -@@ -121,6 +122,7 @@ kexgss_client(struct ssh *ssh) { +@@ -126,6 +127,7 @@ kexgss_client(struct ssh *ssh) { /* Step 1 - e is dh->pub_key */ dh_gen_key(dh, ssh->kex->we_need * 8); @@ -886,7 +629,7 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c /* This is f, we initialise it now to make life easier */ dh_server_pub = BN_new(); -@@ -168,7 +170,7 @@ kexgss_client(struct ssh *ssh) { +@@ -173,7 +175,7 @@ kexgss_client(struct ssh *ssh) { packet_start(SSH2_MSG_KEXGSS_INIT); packet_put_string(send_tok.value, send_tok.length); @@ -895,7 +638,7 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c first = 0; } else { packet_start(SSH2_MSG_KEXGSS_CONTINUE); -@@ -275,13 +277,14 @@ kexgss_client(struct ssh *ssh) { +@@ -282,13 +284,14 @@ kexgss_client(struct ssh *ssh) { buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), (serverhostkey ? serverhostkey : empty), slen, @@ -911,7 +654,7 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c kexgex_hash( ssh->kex->hash_alg, ssh->kex->client_version_string, -@@ -290,8 +293,8 @@ kexgss_client(struct ssh *ssh) { +@@ -297,8 +300,8 @@ kexgss_client(struct ssh *ssh) { buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), (serverhostkey ? serverhostkey : empty), slen, min, nbits, max, @@ -922,10 +665,10 @@ diff -up openssh-7.4p1/kexgssc.c.openssl openssh-7.4p1/kexgssc.c dh_server_pub, shared_secret, hash, &hashlen -diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c ---- openssh-7.4p1/kexgsss.c.openssl 2016-12-23 17:47:36.349817718 +0100 -+++ openssh-7.4p1/kexgsss.c 2016-12-23 17:47:36.432817753 +0100 -@@ -77,6 +77,7 @@ kexgss_server(struct ssh *ssh) +diff -up openssh/kexgsss.c.openssl openssh/kexgsss.c +--- openssh/kexgsss.c.openssl 2017-09-26 13:19:31.771249537 +0200 ++++ openssh/kexgsss.c 2017-09-26 13:19:31.798249703 +0200 +@@ -78,6 +78,7 @@ kexgss_server(struct ssh *ssh) char *mechs; u_char hash[SSH_DIGEST_MAX_LENGTH]; size_t hashlen; @@ -933,7 +676,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c /* Initialise GSSAPI */ -@@ -122,9 +123,10 @@ kexgss_server(struct ssh *ssh) +@@ -127,9 +128,10 @@ kexgss_server(struct ssh *ssh) if (dh == NULL) packet_disconnect("Protocol error: no matching group found"); @@ -946,7 +689,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c packet_send(); packet_write_wait(); -@@ -216,6 +218,7 @@ kexgss_server(struct ssh *ssh) +@@ -221,6 +223,7 @@ kexgss_server(struct ssh *ssh) memset(kbuf, 0, klen); free(kbuf); @@ -954,7 +697,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c hashlen = sizeof(hash); switch (ssh->kex->kex_type) { case KEX_GSS_GRP1_SHA1: -@@ -225,7 +228,7 @@ kexgss_server(struct ssh *ssh) +@@ -232,7 +235,7 @@ kexgss_server(struct ssh *ssh) buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), NULL, 0, /* Change this if we start sending host keys */ @@ -963,7 +706,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c hash, &hashlen ); break; -@@ -237,9 +240,9 @@ kexgss_server(struct ssh *ssh) +@@ -244,9 +247,9 @@ kexgss_server(struct ssh *ssh) buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), NULL, 0, cmin, nbits, cmax, @@ -975,7 +718,7 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c shared_secret, hash, &hashlen ); -@@ -263,7 +266,7 @@ kexgss_server(struct ssh *ssh) +@@ -270,7 +273,7 @@ kexgss_server(struct ssh *ssh) fatal("Couldn't get MIC"); packet_start(SSH2_MSG_KEXGSS_COMPLETE); @@ -984,9 +727,9 @@ diff -up openssh-7.4p1/kexgsss.c.openssl openssh-7.4p1/kexgsss.c packet_put_string(msg_tok.value,msg_tok.length); if (send_tok.length != 0) { -diff -up openssh-7.4p1/libcrypto-compat.c.openssl openssh-7.4p1/libcrypto-compat.c ---- openssh-7.4p1/libcrypto-compat.c.openssl 2016-12-23 17:47:36.432817753 +0100 -+++ openssh-7.4p1/libcrypto-compat.c 2016-12-23 17:47:36.432817753 +0100 +diff -up openssh/libcrypto-compat.c.openssl openssh/libcrypto-compat.c +--- openssh/libcrypto-compat.c.openssl 2017-09-26 13:19:31.798249703 +0200 ++++ openssh/libcrypto-compat.c 2017-09-26 13:19:31.798249703 +0200 @@ -0,0 +1,546 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. @@ -1534,9 +1277,9 @@ diff -up openssh-7.4p1/libcrypto-compat.c.openssl openssh-7.4p1/libcrypto-compat +} + +#endif /* OPENSSL_VERSION_NUMBER */ -diff -up openssh-7.4p1/libcrypto-compat.h.openssl openssh-7.4p1/libcrypto-compat.h ---- openssh-7.4p1/libcrypto-compat.h.openssl 2016-12-23 17:47:36.432817753 +0100 -+++ openssh-7.4p1/libcrypto-compat.h 2016-12-23 17:47:36.432817753 +0100 +diff -up openssh/libcrypto-compat.h.openssl openssh/libcrypto-compat.h +--- openssh/libcrypto-compat.h.openssl 2017-09-26 13:19:31.798249703 +0200 ++++ openssh/libcrypto-compat.h 2017-09-26 13:19:31.798249703 +0200 @@ -0,0 +1,98 @@ +#ifndef LIBCRYPTO_COMPAT_H +#define LIBCRYPTO_COMPAT_H @@ -1636,22 +1379,22 @@ diff -up openssh-7.4p1/libcrypto-compat.h.openssl openssh-7.4p1/libcrypto-compat + +#endif /* LIBCRYPTO_COMPAT_H */ + -diff -up openssh-7.4p1/Makefile.in.openssl openssh-7.4p1/Makefile.in ---- openssh-7.4p1/Makefile.in.openssl 2016-12-23 17:47:36.420817748 +0100 -+++ openssh-7.4p1/Makefile.in 2016-12-23 17:47:36.432817753 +0100 -@@ -100,7 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ +diff -up openssh/Makefile.in.openssl openssh/Makefile.in +--- openssh/Makefile.in.openssl 2017-09-26 13:19:31.784249617 +0200 ++++ openssh/Makefile.in 2017-09-26 13:19:31.798249703 +0200 +@@ -101,7 +101,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ -- platform-pledge.o platform-tracing.o auditstub.o -+ platform-pledge.o platform-tracing.o auditstub.o libcrypto-compat.o + platform-pledge.o platform-tracing.o platform-misc.o \ +- auditstub.o ++ auditstub.o libcrypto-compat.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o mux.o -diff -up openssh-7.4p1/monitor.c.openssl openssh-7.4p1/monitor.c ---- openssh-7.4p1/monitor.c.openssl 2016-12-23 17:47:36.426817750 +0100 -+++ openssh-7.4p1/monitor.c 2016-12-23 17:47:36.433817753 +0100 -@@ -636,9 +636,12 @@ mm_answer_moduli(int sock, Buffer *m) + sshconnect.o sshconnect2.o mux.o +diff -up openssh/monitor.c.openssl openssh/monitor.c +--- openssh/monitor.c.openssl 2017-09-26 13:19:31.789249648 +0200 ++++ openssh/monitor.c 2017-09-26 13:19:31.799249709 +0200 +@@ -631,9 +631,12 @@ mm_answer_moduli(int sock, Buffer *m) return (0); } else { /* Send first bignum */ @@ -1666,9 +1409,9 @@ diff -up openssh-7.4p1/monitor.c.openssl openssh-7.4p1/monitor.c DH_free(dh); } -diff -up openssh-7.4p1/openbsd-compat/openssl-compat.c.openssl openssh-7.4p1/openbsd-compat/openssl-compat.c ---- openssh-7.4p1/openbsd-compat/openssl-compat.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/openbsd-compat/openssl-compat.c 2016-12-23 17:47:36.433817753 +0100 +diff -up openssh/openbsd-compat/openssl-compat.c.openssl openssh/openbsd-compat/openssl-compat.c +--- openssh/openbsd-compat/openssl-compat.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/openbsd-compat/openssl-compat.c 2017-09-26 13:19:31.799249709 +0200 @@ -70,12 +70,19 @@ ssh_compatible_openssl(long headerver, l void ssh_OpenSSL_add_all_algorithms(void) @@ -1689,9 +1432,9 @@ diff -up openssh-7.4p1/openbsd-compat/openssl-compat.c.openssl openssh-7.4p1/ope } #endif -diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/configure.ac.openssl openssh-7.4p1/pam_ssh_agent_auth-0.10.3/configure.ac ---- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/configure.ac.openssl 2014-03-31 19:35:17.000000000 +0200 -+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/configure.ac 2016-12-23 17:47:36.433817753 +0100 +diff -up openssh/pam_ssh_agent_auth-0.10.3/configure.ac.openssl openssh/pam_ssh_agent_auth-0.10.3/configure.ac +--- openssh/pam_ssh_agent_auth-0.10.3/configure.ac.openssl 2016-11-13 04:24:32.000000000 +0100 ++++ openssh/pam_ssh_agent_auth-0.10.3/configure.ac 2017-09-26 13:19:31.799249709 +0200 @@ -1829,6 +1829,7 @@ AC_RUN_IFELSE( [AC_LANG_SOURCE([[ #include @@ -1700,9 +1443,9 @@ diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/configure.ac.openssl openssh-7. int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); } ]])], [ -diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p1/regress/unittests/sshkey/test_file.c ---- openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/unittests/sshkey/test_file.c 2016-12-23 17:47:36.433817753 +0100 +diff -up openssh/regress/unittests/sshkey/test_file.c.openssl openssh/regress/unittests/sshkey/test_file.c +--- openssh/regress/unittests/sshkey/test_file.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/regress/unittests/sshkey/test_file.c 2017-09-26 13:19:31.799249709 +0200 @@ -46,6 +46,7 @@ sshkey_file_tests(void) struct sshbuf *buf, *pw; BIGNUM *a, *b, *c; @@ -1711,17 +1454,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p TEST_START("load passphrase"); pw = load_text_file("pw"); -@@ -58,7 +59,8 @@ sshkey_file_tests(void) - sshbuf_free(buf); - ASSERT_PTR_NE(k1, NULL); - a = load_bignum("rsa1_1.param.n"); -- ASSERT_BIGNUM_EQ(k1->rsa->n, a); -+ RSA_get0_key(k1->rsa, &n, NULL, NULL); -+ ASSERT_BIGNUM_EQ(n, a); - BN_free(a); - TEST_DONE(); - -@@ -109,9 +111,11 @@ sshkey_file_tests(void) +@@ -60,9 +61,11 @@ sshkey_file_tests(void) a = load_bignum("rsa_1.param.n"); b = load_bignum("rsa_1.param.p"); c = load_bignum("rsa_1.param.q"); @@ -1736,7 +1469,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p BN_free(a); BN_free(b); BN_free(c); -@@ -200,9 +204,11 @@ sshkey_file_tests(void) +@@ -151,9 +154,11 @@ sshkey_file_tests(void) a = load_bignum("dsa_1.param.g"); b = load_bignum("dsa_1.param.priv"); c = load_bignum("dsa_1.param.pub"); @@ -1751,20 +1484,10 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_file.c.openssl openssh-7.4p BN_free(a); BN_free(b); BN_free(c); -diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c ---- openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c 2016-12-23 17:47:36.433817753 +0100 +diff -up openssh/regress/unittests/sshkey/test_sshkey.c.openssl openssh/regress/unittests/sshkey/test_sshkey.c +--- openssh/regress/unittests/sshkey/test_sshkey.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/regress/unittests/sshkey/test_sshkey.c 2017-09-26 13:19:31.800249715 +0200 @@ -197,9 +197,6 @@ sshkey_tests(void) - k1 = sshkey_new(KEY_RSA1); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->rsa, NULL); -- ASSERT_PTR_NE(k1->rsa->n, NULL); -- ASSERT_PTR_NE(k1->rsa->e, NULL); -- ASSERT_PTR_EQ(k1->rsa->p, NULL); - sshkey_free(k1); - TEST_DONE(); - -@@ -207,9 +204,6 @@ sshkey_tests(void) k1 = sshkey_new(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); @@ -1774,7 +1497,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. sshkey_free(k1); TEST_DONE(); -@@ -217,8 +211,6 @@ sshkey_tests(void) +@@ -207,8 +204,6 @@ sshkey_tests(void) k1 = sshkey_new(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); @@ -1783,7 +1506,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. sshkey_free(k1); TEST_DONE(); -@@ -244,9 +236,6 @@ sshkey_tests(void) +@@ -234,9 +229,6 @@ sshkey_tests(void) k1 = sshkey_new_private(KEY_RSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->rsa, NULL); @@ -1793,7 +1516,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); -@@ -255,8 +244,6 @@ sshkey_tests(void) +@@ -245,8 +237,6 @@ sshkey_tests(void) k1 = sshkey_new_private(KEY_DSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->dsa, NULL); @@ -1802,7 +1525,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. ASSERT_INT_EQ(sshkey_add_private(k1), 0); sshkey_free(k1); TEST_DONE(); -@@ -295,18 +282,13 @@ sshkey_tests(void) +@@ -285,18 +275,13 @@ sshkey_tests(void) ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); ASSERT_PTR_NE(kr, NULL); ASSERT_PTR_NE(kr->rsa, NULL); @@ -1822,7 +1545,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. TEST_DONE(); #ifdef OPENSSL_HAS_ECC -@@ -333,9 +315,6 @@ sshkey_tests(void) +@@ -323,9 +308,6 @@ sshkey_tests(void) ASSERT_PTR_NE(kr, k1); ASSERT_INT_EQ(k1->type, KEY_RSA); ASSERT_PTR_NE(k1->rsa, NULL); @@ -1832,7 +1555,7 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. TEST_DONE(); TEST_START("equal KEY_RSA/demoted KEY_RSA"); -@@ -349,8 +328,6 @@ sshkey_tests(void) +@@ -339,8 +321,6 @@ sshkey_tests(void) ASSERT_PTR_NE(kd, k1); ASSERT_INT_EQ(k1->type, KEY_DSA); ASSERT_PTR_NE(k1->dsa, NULL); @@ -1841,399 +1564,10 @@ diff -up openssh-7.4p1/regress/unittests/sshkey/test_sshkey.c.openssl openssh-7. TEST_DONE(); TEST_START("equal KEY_DSA/demoted KEY_DSA"); -diff -up openssh-7.4p1/rsa.c.openssl openssh-7.4p1/rsa.c ---- openssh-7.4p1/rsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/rsa.c 2016-12-23 17:47:36.434817754 +0100 -@@ -76,11 +76,14 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM * - { - u_char *inbuf = NULL, *outbuf = NULL; - int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; -+ const BIGNUM *e, *n; - -- if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) -+ RSA_get0_key(key, &n, &e, NULL); -+ -+ if (BN_num_bits(e) < 2 || !BN_is_odd(e)) - return SSH_ERR_INVALID_ARGUMENT; - -- olen = BN_num_bytes(key->n); -+ olen = BN_num_bytes(n); - if ((outbuf = malloc(olen)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; -@@ -122,8 +125,11 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM - { - u_char *inbuf = NULL, *outbuf = NULL; - int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; -+ const BIGNUM *n; -+ -+ RSA_get0_key(key, &n, NULL, NULL); - -- olen = BN_num_bytes(key->n); -+ olen = BN_num_bytes(n); - if ((outbuf = malloc(olen)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; -@@ -157,31 +163,42 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM - return r; - } - --/* calculate p-1 and q-1 */ -+/* calculate d mod p-1 and d mod q-1 */ - int --rsa_generate_additional_parameters(RSA *rsa) -+rsa_generate_additional_parameters(RSA *rsa, BIGNUM *iqmp) - { - BIGNUM *aux = NULL; - BN_CTX *ctx = NULL; - int r; -+ const BIGNUM *p, *q, *d; -+ BIGNUM *dmp1 = NULL, *dmq1 = NULL; -+ -+ RSA_get0_factors(rsa, &p, &q); -+ RSA_get0_key(rsa, NULL, NULL, &d); - -- if ((ctx = BN_CTX_new()) == NULL) -- return SSH_ERR_ALLOC_FAIL; -- if ((aux = BN_new()) == NULL) { -+ if ((ctx = BN_CTX_new()) == NULL || -+ (aux = BN_new()) == NULL || -+ (dmp1 = BN_new()) == NULL || -+ (dmq1 = BN_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - -- if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || -- (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || -- (BN_sub(aux, rsa->p, BN_value_one()) == 0) || -- (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { -+ if ((BN_sub(aux, q, BN_value_one()) == 0) || -+ (BN_mod(dmq1, d, aux, ctx) == 0) || -+ (BN_sub(aux, p, BN_value_one()) == 0) || -+ (BN_mod(dmp1, d, aux, ctx) == 0) || -+ (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0)) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -+ dmp1 = NULL; -+ dmq1 = NULL; - r = 0; - out: - BN_clear_free(aux); -+ BN_clear_free(dmp1); -+ BN_clear_free(dmq1); - BN_CTX_free(ctx); - return r; - } -diff -up openssh-7.4p1/rsa.h.openssl openssh-7.4p1/rsa.h ---- openssh-7.4p1/rsa.h.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/rsa.h 2016-12-23 17:47:36.434817754 +0100 -@@ -21,6 +21,6 @@ - - int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); - int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *); --int rsa_generate_additional_parameters(RSA *); -+int rsa_generate_additional_parameters(RSA *, BIGNUM *); - - #endif /* RSA_H */ -diff -up openssh-7.4p1/ssh-agent.c.openssl openssh-7.4p1/ssh-agent.c ---- openssh-7.4p1/ssh-agent.c.openssl 2016-12-23 17:47:36.428817751 +0100 -+++ openssh-7.4p1/ssh-agent.c 2016-12-23 17:47:36.434817754 +0100 -@@ -258,12 +258,12 @@ process_request_identities(SocketEntry * - TAILQ_FOREACH(id, &tab->idlist, next) { - if (id->key->type == KEY_RSA1) { - #ifdef WITH_SSH1 -+ const BIGNUM *r_n, *r_e; -+ RSA_get0_key(id->key->rsa, &r_n, &r_e, NULL); - if ((r = sshbuf_put_u32(msg, -- BN_num_bits(id->key->rsa->n))) != 0 || -- (r = sshbuf_put_bignum1(msg, -- id->key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum1(msg, -- id->key->rsa->n)) != 0) -+ BN_num_bits(r_n))) != 0 || -+ (r = sshbuf_put_bignum1(msg, r_e)) != 0 || -+ (r = sshbuf_put_bignum1(msg, r_n)) != 0) - fatal("%s: buffer error: %s", - __func__, ssh_err(r)); - #endif -@@ -302,6 +302,7 @@ process_authentication_challenge1(Socket - struct sshbuf *msg; - struct ssh_digest_ctx *md; - struct sshkey *key; -+ BIGNUM *r_n = NULL, *r_e = NULL; - - if ((msg = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); -@@ -310,11 +311,16 @@ process_authentication_challenge1(Socket - if ((challenge = BN_new()) == NULL) - fatal("%s: BN_new failed", __func__); - -- if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ -- (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 || -- (r = sshbuf_get_bignum1(e->request, challenge))) -+ if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL || -+ (r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ -+ (r = sshbuf_get_bignum1(e->request, r_e)) != 0 || -+ (r = sshbuf_get_bignum1(e->request, r_n)) != 0 || -+ (r = sshbuf_get_bignum1(e->request, challenge)) || -+ RSA_set0_key(key->rsa, r_n, r_e, NULL) == 0) { -+ BN_free(r_n); -+ BN_free(r_e); - fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ } - - /* Only protocol 1.1 is supported */ - if (sshbuf_len(e->request) == 0) -@@ -450,6 +456,7 @@ process_remove_identity(SocketEntry *e, - u_char *blob; - #ifdef WITH_SSH1 - u_int bits; -+ BIGNUM *r_n = NULL, *r_e = NULL; - #endif /* WITH_SSH1 */ - - switch (version) { -@@ -459,10 +466,15 @@ process_remove_identity(SocketEntry *e, - error("%s: sshkey_new failed", __func__); - return; - } -- if ((r = sshbuf_get_u32(e->request, &bits)) != 0 || -- (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0) -+ if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL || -+ (r = sshbuf_get_u32(e->request, &bits)) != 0 || -+ (r = sshbuf_get_bignum1(e->request, r_e)) != 0 || -+ (r = sshbuf_get_bignum1(e->request, r_n)) != 0 || -+ RSA_set0_key(key->rsa, r_n, r_e, NULL) == 0) { -+ BN_free(r_n); -+ BN_free(r_e); - fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ } - - if (bits != sshkey_size(key)) - logit("Warning: identity keysize mismatch: " -@@ -565,23 +577,46 @@ agent_decode_rsa1(struct sshbuf *m, stru - { - struct sshkey *k = NULL; - int r = SSH_ERR_INTERNAL_ERROR; -+ BIGNUM *n = NULL, *e = NULL, *d = NULL, -+ *iqmp = NULL, *q = NULL, *p = NULL; - - *kp = NULL; - if ((k = sshkey_new_private(KEY_RSA1)) == NULL) - return SSH_ERR_ALLOC_FAIL; - -- if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ -- (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 || -- (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 || -- (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 || -+ if ((n = BN_new()) == NULL || (e = BN_new()) == NULL || -+ (d = BN_new()) == NULL || (iqmp = BN_new()) == NULL || -+ (q = BN_new()) == NULL || (p = BN_new()) == NULL || -+ (r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ -+ (r = sshbuf_get_bignum1(m, n)) != 0 || -+ (r = sshbuf_get_bignum1(m, e)) != 0 || -+ (r = sshbuf_get_bignum1(m, d)) != 0 || -+ (r = sshbuf_get_bignum1(m, iqmp)) != 0 || - /* SSH1 and SSL have p and q swapped */ -- (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */ -- (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ -+ (r = sshbuf_get_bignum1(m, q)) != 0 || /* p */ -+ (r = sshbuf_get_bignum1(m, p)) != 0 || /* q */ -+ RSA_set0_key(k->rsa, n, e, d) == 0) { -+ BN_free(n); -+ BN_free(e); -+ BN_free(d); -+ BN_free(p); -+ BN_free(q); -+ BN_free(iqmp); -+ goto out; -+ } -+ if (RSA_set0_factors(k->rsa, p, q) == 0) { -+ BN_free(p); -+ BN_free(q); -+ BN_free(iqmp); - goto out; -+ } -+ if (RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) { -+ BN_free(iqmp); -+ goto out; -+ } - - /* Generate additional parameters */ -- if ((r = rsa_generate_additional_parameters(k->rsa)) != 0) -+ if ((r = rsa_generate_additional_parameters(k->rsa, NULL)) != 0) - goto out; - /* enable blinding */ - if (RSA_blinding_on(k->rsa, NULL) != 1) { -diff -up openssh-7.4p1/sshconnect1.c.openssl openssh-7.4p1/sshconnect1.c ---- openssh-7.4p1/sshconnect1.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/sshconnect1.c 2016-12-23 17:47:36.434817754 +0100 -@@ -70,6 +70,7 @@ try_agent_authentication(void) - u_char response[16]; - size_t i; - BIGNUM *challenge; -+ const BIGNUM *n; - struct ssh_identitylist *idlist = NULL; - - /* Get connection to the agent. */ -@@ -96,8 +97,9 @@ try_agent_authentication(void) - idlist->comments[i]); - - /* Tell the server that we are willing to authenticate using this key. */ -+ RSA_get0_key(idlist->keys[i]->rsa, &n, NULL, NULL); - packet_start(SSH_CMSG_AUTH_RSA); -- packet_put_bignum(idlist->keys[i]->rsa->n); -+ packet_put_bignum((BIGNUM *)n); - packet_send(); - packet_write_wait(); - -@@ -220,6 +222,7 @@ static int - try_rsa_authentication(int idx) - { - BIGNUM *challenge; -+ const BIGNUM *n; - Key *public, *private; - char buf[300], *passphrase = NULL, *comment, *authfile; - int i, perm_ok = 1, type, quit; -@@ -231,8 +234,9 @@ try_rsa_authentication(int idx) - debug("Trying RSA authentication with key '%.100s'", comment); - - /* Tell the server that we are willing to authenticate using this key. */ -+ RSA_get0_key(public->rsa, &n, NULL, NULL); - packet_start(SSH_CMSG_AUTH_RSA); -- packet_put_bignum(public->rsa->n); -+ packet_put_bignum((BIGNUM *)n); - packet_send(); - packet_write_wait(); - -@@ -348,15 +352,17 @@ try_rhosts_rsa_authentication(const char - { - int type; - BIGNUM *challenge; -+ const BIGNUM *n, *e; - - debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); - - /* Tell the server that we are willing to authenticate using this key. */ -+ RSA_get0_key(host_key->rsa, &n, &e, NULL); - packet_start(SSH_CMSG_AUTH_RHOSTS_RSA); - packet_put_cstring(local_user); -- packet_put_int(BN_num_bits(host_key->rsa->n)); -- packet_put_bignum(host_key->rsa->e); -- packet_put_bignum(host_key->rsa->n); -+ packet_put_int(BN_num_bits(n)); -+ packet_put_bignum((BIGNUM *)e); -+ packet_put_bignum((BIGNUM *)n); - packet_send(); - packet_write_wait(); - -@@ -502,6 +508,8 @@ ssh_kex(char *host, struct sockaddr *hos - { - int i; - BIGNUM *key; -+ BIGNUM *server_n = NULL, *server_e = NULL, -+ *host_n = NULL, *host_e = NULL; - Key *host_key, *server_key; - int bits, rbits; - int ssh_cipher_default = SSH_CIPHER_3DES; -@@ -522,10 +530,14 @@ ssh_kex(char *host, struct sockaddr *hos - if ((server_key = key_new(KEY_RSA1)) == NULL) - fatal("%s: key_new(KEY_RSA1) failed", __func__); - bits = packet_get_int(); -- packet_get_bignum(server_key->rsa->e); -- packet_get_bignum(server_key->rsa->n); -+ if ((server_e = BN_new()) == NULL || -+ (server_n = BN_new()) == NULL) -+ fatal("BN_new() failed"); -+ packet_get_bignum(server_e); -+ packet_get_bignum(server_n); -+ RSA_set0_key(server_key->rsa, server_n, server_e, NULL); - -- rbits = BN_num_bits(server_key->rsa->n); -+ rbits = BN_num_bits(server_n); - if (bits != rbits) { - logit("Warning: Server lies about size of server public key: " - "actual size is %d bits vs. announced %d.", rbits, bits); -@@ -534,10 +546,14 @@ ssh_kex(char *host, struct sockaddr *hos - if ((host_key = key_new(KEY_RSA1)) == NULL) - fatal("%s: key_new(KEY_RSA1) failed", __func__); - bits = packet_get_int(); -- packet_get_bignum(host_key->rsa->e); -- packet_get_bignum(host_key->rsa->n); -+ if ((host_e = BN_new()) == NULL || -+ (host_n = BN_new()) == NULL) -+ fatal("BN_new() failed"); -+ packet_get_bignum(host_e); -+ packet_get_bignum(host_n); -+ RSA_set0_key(host_key->rsa, host_n, host_e, NULL); - -- rbits = BN_num_bits(host_key->rsa->n); -+ rbits = BN_num_bits(host_n); - if (bits != rbits) { - logit("Warning: Server lies about size of server host key: " - "actual size is %d bits vs. announced %d.", rbits, bits); -@@ -553,14 +569,14 @@ ssh_kex(char *host, struct sockaddr *hos - packet_check_eom(); - - debug("Received server public key (%d bits) and host key (%d bits).", -- BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n)); -+ BN_num_bits(server_n), BN_num_bits(host_n)); - - if (verify_host_key(host, hostaddr, host_key) == -1) - fatal("Host key verification failed."); - - client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; - -- derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id); -+ derive_ssh1_session_id(host_n, server_n, cookie, session_id); - - /* - * Generate an encryption key for the session. The key is a 256 bit -@@ -595,14 +611,14 @@ ssh_kex(char *host, struct sockaddr *hos - * Encrypt the integer using the public key and host key of the - * server (key with smaller modulus first). - */ -- if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) { -+ if (BN_cmp(server_n, host_n) < 0) { - /* Public key has smaller modulus. */ -- if (BN_num_bits(host_key->rsa->n) < -- BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { -+ if (BN_num_bits(host_n) < -+ BN_num_bits(server_n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " - "SSH_KEY_BITS_RESERVED %d", -- BN_num_bits(host_key->rsa->n), -- BN_num_bits(server_key->rsa->n), -+ BN_num_bits(host_n), -+ BN_num_bits(server_n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_public_encrypt(key, key, server_key->rsa) != 0 || -@@ -610,12 +626,12 @@ ssh_kex(char *host, struct sockaddr *hos - fatal("%s: rsa_public_encrypt failed", __func__); - } else { - /* Host key has smaller modulus (or they are equal). */ -- if (BN_num_bits(server_key->rsa->n) < -- BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { -+ if (BN_num_bits(server_n) < -+ BN_num_bits(host_n) + SSH_KEY_BITS_RESERVED) { - fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " - "SSH_KEY_BITS_RESERVED %d", -- BN_num_bits(server_key->rsa->n), -- BN_num_bits(host_key->rsa->n), -+ BN_num_bits(server_n), -+ BN_num_bits(host_n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_public_encrypt(key, key, host_key->rsa) != 0 || -diff -up openssh-7.4p1/sshconnect2.c.openssl openssh-7.4p1/sshconnect2.c ---- openssh-7.4p1/sshconnect2.c.openssl 2016-12-23 17:47:36.423817749 +0100 -+++ openssh-7.4p1/sshconnect2.c 2016-12-23 17:47:36.434817754 +0100 -@@ -299,6 +299,7 @@ ssh_kex2(char *host, struct sockaddr *ho +diff -up openssh/sshconnect2.c.openssl openssh/sshconnect2.c +--- openssh/sshconnect2.c.openssl 2017-09-26 13:19:31.786249629 +0200 ++++ openssh/sshconnect2.c 2017-09-26 13:19:31.800249715 +0200 +@@ -306,6 +306,7 @@ ssh_kex2(char *host, struct sockaddr *ho packet_send(); packet_write_wait(); #endif @@ -2241,10 +1575,10 @@ diff -up openssh-7.4p1/sshconnect2.c.openssl openssh-7.4p1/sshconnect2.c } /* -diff -up openssh-7.4p1/sshconnect.c.openssl openssh-7.4p1/sshconnect.c ---- openssh-7.4p1/sshconnect.c.openssl 2016-12-23 17:47:36.397817738 +0100 -+++ openssh-7.4p1/sshconnect.c 2016-12-23 17:47:36.435817754 +0100 -@@ -1369,6 +1369,7 @@ ssh_login(Sensitive *sensitive, const ch +diff -up openssh/sshconnect.c.openssl openssh/sshconnect.c +--- openssh/sshconnect.c.openssl 2017-09-26 13:19:31.759249464 +0200 ++++ openssh/sshconnect.c 2017-09-26 13:19:31.800249715 +0200 +@@ -1316,6 +1316,7 @@ ssh_login(Sensitive *sensitive, const ch char *server_user, *local_user; local_user = xstrdup(pw->pw_name); @@ -2252,10 +1586,10 @@ diff -up openssh-7.4p1/sshconnect.c.openssl openssh-7.4p1/sshconnect.c server_user = options.user ? options.user : local_user; /* Convert the user-supplied hostname into all lowercase. */ -diff -up openssh-7.4p1/ssh.c.openssl openssh-7.4p1/ssh.c ---- openssh-7.4p1/ssh.c.openssl 2016-12-23 17:47:36.422817748 +0100 -+++ openssh-7.4p1/ssh.c 2016-12-23 17:47:36.435817754 +0100 -@@ -532,7 +532,9 @@ main(int ac, char **av) +diff -up openssh/ssh.c.openssl openssh/ssh.c +--- openssh/ssh.c.openssl 2017-09-26 13:19:31.786249629 +0200 ++++ openssh/ssh.c 2017-09-26 13:19:31.800249715 +0200 +@@ -530,7 +530,9 @@ main(int ac, char **av) sanitise_stdfd(); __progname = ssh_get_progname(av[0]); @@ -2265,7 +1599,7 @@ diff -up openssh-7.4p1/ssh.c.openssl openssh-7.4p1/ssh.c if (access("/etc/system-fips", F_OK) == 0) if (! FIPSCHECK_verify(NULL, NULL)){ if (FIPS_mode()) -@@ -1247,6 +1249,7 @@ main(int ac, char **av) +@@ -1263,6 +1265,7 @@ main(int ac, char **av) free(cp); } free(conn_hash_hex); @@ -2273,10 +1607,10 @@ diff -up openssh-7.4p1/ssh.c.openssl openssh-7.4p1/ssh.c if (config_test) { dump_client_config(&options, host); -diff -up openssh-7.4p1/sshd.c.openssl openssh-7.4p1/sshd.c ---- openssh-7.4p1/sshd.c.openssl 2016-12-23 17:47:36.428817751 +0100 -+++ openssh-7.4p1/sshd.c 2016-12-23 17:47:36.435817754 +0100 -@@ -1483,7 +1483,7 @@ main(int ac, char **av) +diff -up openssh/sshd.c.openssl openssh/sshd.c +--- openssh/sshd.c.openssl 2017-09-26 13:19:31.792249666 +0200 ++++ openssh/sshd.c 2017-09-26 13:19:31.801249721 +0200 +@@ -1485,7 +1485,7 @@ main(int ac, char **av) #endif __progname = ssh_get_progname(av[0]); @@ -2285,9 +1619,9 @@ diff -up openssh-7.4p1/sshd.c.openssl openssh-7.4p1/sshd.c if (access("/etc/system-fips", F_OK) == 0) if (! FIPSCHECK_verify(NULL, NULL)) { openlog(__progname, LOG_PID, LOG_AUTHPRIV); -diff -up openssh-7.4p1/ssh-dss.c.openssl openssh-7.4p1/ssh-dss.c ---- openssh-7.4p1/ssh-dss.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-dss.c 2016-12-23 17:47:36.435817754 +0100 +diff -up openssh/ssh-dss.c.openssl openssh/ssh-dss.c +--- openssh/ssh-dss.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-dss.c 2017-09-26 13:19:31.801249721 +0200 @@ -55,6 +55,7 @@ ssh_dss_sign(const struct sshkey *key, u size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); struct sshbuf *b = NULL; @@ -2361,9 +1695,9 @@ diff -up openssh-7.4p1/ssh-dss.c.openssl openssh-7.4p1/ssh-dss.c sshbuf_free(b); free(ktype); if (sigblob != NULL) { -diff -up openssh-7.4p1/ssh-ecdsa.c.openssl openssh-7.4p1/ssh-ecdsa.c ---- openssh-7.4p1/ssh-ecdsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-ecdsa.c 2016-12-23 17:47:36.436817754 +0100 +diff -up openssh/ssh-ecdsa.c.openssl openssh/ssh-ecdsa.c +--- openssh/ssh-ecdsa.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-ecdsa.c 2017-09-26 13:19:31.801249721 +0200 @@ -54,6 +54,7 @@ ssh_ecdsa_sign(const struct sshkey *key, size_t len, dlen; struct sshbuf *b = NULL, *bb = NULL; @@ -2431,11 +1765,11 @@ diff -up openssh-7.4p1/ssh-ecdsa.c.openssl openssh-7.4p1/ssh-ecdsa.c free(ktype); return ret; } -diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c ---- openssh-7.4p1/sshkey.c.openssl 2016-12-23 17:47:36.424817749 +0100 -+++ openssh-7.4p1/sshkey.c 2016-12-23 17:47:56.652826110 +0100 -@@ -275,10 +275,10 @@ sshkey_size(const struct sshkey *k) - case KEY_RSA1: +diff -up openssh/sshkey.c.openssl openssh/sshkey.c +--- openssh/sshkey.c.openssl 2017-09-26 13:19:31.786249629 +0200 ++++ openssh/sshkey.c 2017-09-26 13:19:31.802249728 +0200 +@@ -267,10 +267,10 @@ sshkey_size(const struct sshkey *k) + #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: - return BN_num_bits(k->rsa->n); @@ -2447,10 +1781,10 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c case KEY_ECDSA: case KEY_ECDSA_CERT: return sshkey_curve_nid_to_bits(k->ecdsa_nid); -@@ -311,11 +311,17 @@ sshkey_is_private(const struct sshkey *k +@@ -302,11 +302,17 @@ sshkey_is_private(const struct sshkey *k + switch (k->type) { #ifdef WITH_OPENSSL case KEY_RSA_CERT: - case KEY_RSA1: - case KEY_RSA: - return k->rsa->d != NULL; + case KEY_RSA: { @@ -2469,8 +1803,8 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c #ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: -@@ -505,11 +511,7 @@ sshkey_new(int type) - case KEY_RSA1: +@@ -496,11 +501,7 @@ sshkey_new(int type) + #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: - if ((rsa = RSA_new()) == NULL || @@ -2482,7 +1816,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c free(k); return NULL; } -@@ -517,13 +519,7 @@ sshkey_new(int type) +@@ -508,13 +509,7 @@ sshkey_new(int type) break; case KEY_DSA: case KEY_DSA_CERT: @@ -2497,8 +1831,8 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c free(k); return NULL; } -@@ -563,21 +559,10 @@ sshkey_add_private(struct sshkey *k) - case KEY_RSA1: +@@ -553,21 +548,10 @@ sshkey_add_private(struct sshkey *k) + #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: -#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) @@ -2519,9 +1853,9 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c case KEY_ECDSA: case KEY_ECDSA_CERT: /* Cannot do anything until we know the group */ -@@ -696,17 +681,31 @@ sshkey_equal_public(const struct sshkey +@@ -684,17 +668,31 @@ sshkey_equal_public(const struct sshkey + switch (a->type) { #ifdef WITH_OPENSSL - case KEY_RSA1: case KEY_RSA_CERT: - case KEY_RSA: - return a->rsa != NULL && b->rsa != NULL && @@ -2561,7 +1895,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: -@@ -781,15 +780,21 @@ to_blob_buf(const struct sshkey *key, st +@@ -769,15 +767,21 @@ to_blob_buf(const struct sshkey *key, st return ret; break; #ifdef WITH_OPENSSL @@ -2592,7 +1926,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -802,13 +807,18 @@ to_blob_buf(const struct sshkey *key, st +@@ -790,13 +794,18 @@ to_blob_buf(const struct sshkey *key, st return ret; break; # endif @@ -2618,93 +1952,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; #endif /* WITH_OPENSSL */ case KEY_ED25519: -@@ -914,8 +924,13 @@ sshkey_fingerprint_raw(const struct sshk - - if (k->type == KEY_RSA1) { - #ifdef WITH_OPENSSL -- int nlen = BN_num_bytes(k->rsa->n); -- int elen = BN_num_bytes(k->rsa->e); -+ const BIGNUM *n, *e; -+ int nlen, elen; -+ -+ RSA_get0_key(k->rsa, &n, &e, NULL); -+ -+ nlen = BN_num_bytes(n); -+ elen = BN_num_bytes(e); - - if (nlen < 0 || elen < 0 || nlen >= INT_MAX - elen) { - r = SSH_ERR_INVALID_FORMAT; -@@ -926,8 +941,8 @@ sshkey_fingerprint_raw(const struct sshk - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- BN_bn2bin(k->rsa->n, blob); -- BN_bn2bin(k->rsa->e, blob + nlen); -+ BN_bn2bin(n, blob); -+ BN_bn2bin(e, blob + nlen); - #endif /* WITH_OPENSSL */ - } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0) - goto out; -@@ -1290,6 +1305,7 @@ sshkey_read(struct sshkey *ret, char **c - struct sshbuf *blob; - #ifdef WITH_SSH1 - u_long bits; -+ BIGNUM *e = NULL, *n = NULL; - #endif /* WITH_SSH1 */ - - if (ret == NULL) -@@ -1303,12 +1319,21 @@ sshkey_read(struct sshkey *ret, char **c - bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) - return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ - /* Get public exponent, public modulus. */ -- if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0) -+ if ((e = BN_new()) == NULL || (n = BN_new()) == NULL) { -+ BN_free(e); -+ return SSH_ERR_ALLOC_FAIL; -+ } -+ if ((r = read_decimal_bignum(&ep, e)) < 0) - return r; -- if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0) -+ if ((r = read_decimal_bignum(&ep, n)) < 0) - return r; -+ if (RSA_set0_key(ret->rsa, n, e, NULL) == 0) { -+ BN_free(e); -+ BN_free(n); -+ return -1; -+ } - /* validate the claimed number of bits */ -- if (BN_num_bits(ret->rsa->n) != (int)bits) -+ if (BN_num_bits(n) != (int)bits) - return SSH_ERR_KEY_BITS_MISMATCH; - *cpp = ep; - retval = 0; -@@ -1473,19 +1498,20 @@ sshkey_format_rsa1(const struct sshkey * - #ifdef WITH_SSH1 - u_int bits = 0; - char *dec_e = NULL, *dec_n = NULL; -+ const BIGNUM *e, *n; - -- if (key->rsa == NULL || key->rsa->e == NULL || -- key->rsa->n == NULL) { -+ RSA_get0_key(key->rsa, &n, &e, NULL); -+ if (key->rsa == NULL || e == NULL || n == NULL) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -- if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL || -- (dec_n = BN_bn2dec(key->rsa->n)) == NULL) { -+ if ((dec_e = BN_bn2dec(e)) == NULL || -+ (dec_n = BN_bn2dec(n)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - /* size of modulus 'n' */ -- if ((bits = BN_num_bits(key->rsa->n)) <= 0) { -+ if ((bits = BN_num_bits(n)) <= 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -@@ -1819,15 +1845,32 @@ sshkey_from_private(const struct sshkey +@@ -1672,15 +1681,32 @@ sshkey_from_private(const struct sshkey switch (k->type) { #ifdef WITH_OPENSSL case KEY_DSA: @@ -2746,10 +1994,10 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c } break; # ifdef OPENSSL_HAS_ECC -@@ -1850,13 +1893,22 @@ sshkey_from_private(const struct sshkey +@@ -1702,13 +1728,22 @@ sshkey_from_private(const struct sshkey + break; # endif /* OPENSSL_HAS_ECC */ case KEY_RSA: - case KEY_RSA1: - case KEY_RSA_CERT: - if ((n = sshkey_new(k->type)) == NULL) - return SSH_ERR_ALLOC_FAIL; @@ -2776,7 +2024,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c } break; #endif /* WITH_OPENSSL */ -@@ -2054,10 +2106,20 @@ sshkey_from_blob_internal(struct sshbuf +@@ -1907,12 +1942,22 @@ sshkey_from_blob_internal(struct sshbuf ret = SSH_ERR_ALLOC_FAIL; goto out; } @@ -2799,9 +2047,12 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + goto out; + } } - #ifdef DEBUG_PK - RSA_print_fp(stderr, key->rsa, 8); -@@ -2075,12 +2137,34 @@ sshkey_from_blob_internal(struct sshbuf +- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { ++ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + ret = SSH_ERR_KEY_LENGTH; + goto out; + } +@@ -1932,12 +1977,34 @@ sshkey_from_blob_internal(struct sshbuf ret = SSH_ERR_ALLOC_FAIL; goto out; } @@ -2842,10 +2093,10 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c } #ifdef DEBUG_PK DSA_print_fp(stderr, key->dsa, 8); -@@ -2320,26 +2404,53 @@ sshkey_demote(const struct sshkey *k, st +@@ -2171,26 +2238,53 @@ sshkey_demote(const struct sshkey *k, st + if ((ret = sshkey_cert_copy(k, pk)) != 0) goto fail; /* FALLTHROUGH */ - case KEY_RSA1: - case KEY_RSA: - if ((pk->rsa = RSA_new()) == NULL || - (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || @@ -2910,7 +2161,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c } break; case KEY_ECDSA_CERT: -@@ -2460,12 +2571,17 @@ sshkey_certify(struct sshkey *k, struct +@@ -2312,12 +2406,17 @@ sshkey_certify_custom(struct sshkey *k, /* XXX this substantially duplicates to_blob(); refactor */ switch (k->type) { #ifdef WITH_OPENSSL @@ -2934,7 +2185,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: -@@ -2477,10 +2593,15 @@ sshkey_certify(struct sshkey *k, struct +@@ -2329,10 +2428,15 @@ sshkey_certify_custom(struct sshkey *k, goto out; break; # endif /* OPENSSL_HAS_ECC */ @@ -2954,7 +2205,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; #endif /* WITH_OPENSSL */ case KEY_ED25519_CERT: -@@ -2637,43 +2758,65 @@ sshkey_private_serialize(const struct ss +@@ -2505,43 +2609,65 @@ sshkey_private_serialize(const struct ss goto out; switch (key->type) { #ifdef WITH_OPENSSL @@ -3044,7 +2295,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2749,18 +2892,51 @@ sshkey_private_deserialize(struct sshbuf +@@ -2617,18 +2743,51 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3107,7 +2358,7 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c break; # ifdef OPENSSL_HAS_ECC case KEY_ECDSA: -@@ -2819,24 +2995,84 @@ sshkey_private_deserialize(struct sshbuf +@@ -2687,29 +2846,89 @@ sshkey_private_deserialize(struct sshbuf r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -3117,8 +2368,9 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c - (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || - (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || - (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || -- (r = rsa_generate_additional_parameters(k->rsa)) != 0) +- (r = ssh_rsa_generate_additional_parameters(k)) != 0) - goto out; +- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + { + BIGNUM *n, *e, *d, *iqmp, *p, *q; + @@ -3154,11 +2406,15 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + BN_free(q); + goto out; + } -+ if ((r = rsa_generate_additional_parameters(k->rsa, iqmp)) != 0) { ++ if ((r = ssh_rsa_generate_additional_parameters(k, iqmp)) != 0) { + BN_free(iqmp); + goto out; + } + } ++ if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + r = SSH_ERR_KEY_LENGTH; + goto out; + } break; - case KEY_RSA_CERT: - if ((r = sshkey_froms(buf, &k)) != 0 || @@ -3167,8 +2423,9 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c - (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || - (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || - (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || -- (r = rsa_generate_additional_parameters(k->rsa)) != 0) +- (r = ssh_rsa_generate_additional_parameters(k)) != 0) - goto out; +- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + case KEY_RSA_CERT: { + BIGNUM *d, *iqmp, *p, *q; + @@ -3200,164 +2457,28 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c + BN_free(q); + goto out; + } -+ if (rsa_generate_additional_parameters(k->rsa, iqmp) != 0) { ++ if (ssh_rsa_generate_additional_parameters(k, iqmp) != 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + free(iqmp); + goto out; + } + } - break; - #endif /* WITH_OPENSSL */ - case KEY_ED25519: -@@ -3471,6 +3704,7 @@ sshkey_private_rsa1_to_blob(struct sshke - struct sshcipher_ctx *ciphercontext = NULL; - const struct sshcipher *cipher; - u_char *cp; -+ const BIGNUM *n, *e, *d, *q, *p, *iqmp; - - /* - * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting -@@ -3497,10 +3731,13 @@ sshkey_private_rsa1_to_blob(struct sshke - * format would just give known plaintext). - * Note: q and p are stored in reverse order to SSL. - */ -- if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 || -- (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 || -- (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 || -- (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0) -+ RSA_get0_key(key->rsa, &n, &e, &d); -+ RSA_get0_factors(key->rsa, &p, &q); -+ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); -+ if ((r = sshbuf_put_bignum1(buffer, d)) != 0 || -+ (r = sshbuf_put_bignum1(buffer, iqmp)) != 0 || -+ (r = sshbuf_put_bignum1(buffer, q)) != 0 || -+ (r = sshbuf_put_bignum1(buffer, p)) != 0) - goto out; - - /* Pad the part to be encrypted to a size that is a multiple of 8. */ -@@ -3525,9 +3762,9 @@ sshkey_private_rsa1_to_blob(struct sshke - goto out; - - /* Store public key. This will be in plain text. */ -- if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 || -- (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 || -- (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 || -+ if ((r = sshbuf_put_u32(encrypted, BN_num_bits(n))) != 0 || -+ (r = sshbuf_put_bignum1(encrypted, n)) != 0 || -+ (r = sshbuf_put_bignum1(encrypted, e)) != 0 || - (r = sshbuf_put_cstring(encrypted, comment)) != 0) - goto out; - -@@ -3654,6 +3891,7 @@ sshkey_parse_public_rsa1_fileblob(struct - int r; - struct sshkey *pub = NULL; - struct sshbuf *copy = NULL; -+ BIGNUM *n = NULL, *e = NULL; - - if (keyp != NULL) - *keyp = NULL; -@@ -3683,10 +3921,16 @@ sshkey_parse_public_rsa1_fileblob(struct - goto out; - - /* Read the public key from the buffer. */ -- if ((pub = sshkey_new(KEY_RSA1)) == NULL || -- (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 || -- (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0) -+ if ((n = BN_new()) == NULL || -+ (e = BN_new()) == NULL || -+ (pub = sshkey_new(KEY_RSA1)) == NULL || -+ (r = sshbuf_get_bignum1(copy, n)) != 0 || -+ (r = sshbuf_get_bignum1(copy, e)) != 0 || -+ RSA_set0_key(pub->rsa, n, e, NULL) == 0) { -+ BN_free(n); -+ BN_free(e); - goto out; -+ } - - /* Finally, the comment */ - if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0) -@@ -3718,6 +3962,8 @@ sshkey_parse_private_rsa1(struct sshbuf - struct sshcipher_ctx *ciphercontext = NULL; - const struct sshcipher *cipher; - struct sshkey *prv = NULL; -+ BIGNUM *n = NULL, *e = NULL, *d = NULL, *q = NULL, *p = NULL, -+ *iqmp = NULL; - - if (keyp != NULL) - *keyp = NULL; -@@ -3753,11 +3999,17 @@ sshkey_parse_private_rsa1(struct sshbuf - goto out; - - /* Read the public key and comment from the buffer. */ -- if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ -- (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 || -- (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 || -- (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0) -+ if ((n = BN_new()) == NULL || -+ (e = BN_new()) == NULL || -+ (r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ -+ (r = sshbuf_get_bignum1(copy, n)) != 0 || -+ (r = sshbuf_get_bignum1(copy, e)) != 0 || -+ (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0 || -+ RSA_set0_key(prv->rsa, n, e, NULL) == 0) { -+ BN_free(n); -+ BN_free(e); - goto out; -+ } - - /* Check that it is a supported cipher. */ - cipher = cipher_by_number(cipher_type); -@@ -3786,15 +4038,33 @@ sshkey_parse_private_rsa1(struct sshbuf - } - - /* Read the rest of the private key. */ -- if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 || -- (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 || -- (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 || -- (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0) -+ if ((d = BN_new()) == NULL || -+ (p = BN_new()) == NULL || -+ (q = BN_new()) == NULL || -+ (iqmp = BN_new()) == NULL || -+ (r = sshbuf_get_bignum1(decrypted, d)) != 0 || -+ (r = sshbuf_get_bignum1(decrypted, iqmp)) != 0 || -+ (r = sshbuf_get_bignum1(decrypted, q)) != 0 || -+ (r = sshbuf_get_bignum1(decrypted, p)) != 0 || -+ (RSA_set0_key(prv->rsa, NULL, NULL, d) == 0)) { -+ BN_free(d); -+ BN_free(p); -+ BN_free(q); -+ BN_free(iqmp); -+ goto out; -+ } -+ if (RSA_set0_factors(prv->rsa, p, q) == 0) { -+ BN_free(p); -+ BN_free(q); -+ BN_free(iqmp); - goto out; -+ } - - /* calculate p-1 and q-1 */ -- if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) -+ if ((r = rsa_generate_additional_parameters(prv->rsa, iqmp)) != 0) { -+ BN_free(iqmp); - goto out; -+ } - - /* enable blinding */ - if (RSA_blinding_on(prv->rsa, NULL) != 1) { -@@ -3874,7 +4146,9 @@ sshkey_parse_private_pem_fileblob(struct - case EVP_R_BAD_DECRYPT: - r = SSH_ERR_KEY_WRONG_PASSPHRASE; - goto out; ++ if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + r = SSH_ERR_KEY_LENGTH; + goto out; + } +@@ -3427,7 +3646,9 @@ translate_libcrypto_error(unsigned long + switch (pem_reason) { + case EVP_R_BAD_DECRYPT: + return SSH_ERR_KEY_WRONG_PASSPHRASE; +#ifdef EVP_R_BN_DECODE_ERROR - case EVP_R_BN_DECODE_ERROR: + case EVP_R_BN_DECODE_ERROR: +#endif - case EVP_R_DECODE_ERROR: + case EVP_R_DECODE_ERROR: #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR - case EVP_R_PRIVATE_KEY_DECODE_ERROR: -@@ -3892,7 +4166,7 @@ sshkey_parse_private_pem_fileblob(struct - r = SSH_ERR_LIBCRYPTO_ERROR; + case EVP_R_PRIVATE_KEY_DECODE_ERROR: +@@ -3492,7 +3713,7 @@ sshkey_parse_private_pem_fileblob(struct + r = convert_libcrypto_error(); goto out; } - if (pk->type == EVP_PKEY_RSA && @@ -3365,16 +2486,21 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c (type == KEY_UNSPEC || type == KEY_RSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -@@ -3861,7 +4124,7 @@ sshkey_parse_private_pem_fileblob(struct +@@ -3507,11 +3728,11 @@ sshkey_parse_private_pem_fileblob(struct r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } +- if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { ++ if (RSA_bits(prv->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + r = SSH_ERR_KEY_LENGTH; + goto out; + } - } else if (pk->type == EVP_PKEY_DSA && + } else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA && (type == KEY_UNSPEC || type == KEY_DSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -@@ -3873,7 +4136,7 @@ sshkey_parse_private_pem_fileblob(struct +@@ -3523,7 +3744,7 @@ sshkey_parse_private_pem_fileblob(struct DSA_print_fp(stderr, prv->dsa, 8); #endif #ifdef OPENSSL_HAS_ECC @@ -3383,10 +2509,10 @@ diff -up openssh-7.4p1/sshkey.c.openssl openssh-7.4p1/sshkey.c (type == KEY_UNSPEC || type == KEY_ECDSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; -diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c ---- openssh-7.4p1/ssh-keygen.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-keygen.c 2016-12-23 17:47:36.437817755 +0100 -@@ -480,40 +480,67 @@ do_convert_private_ssh2_from_blob(u_char +diff -up openssh/ssh-keygen.c.openssl openssh/ssh-keygen.c +--- openssh/ssh-keygen.c.openssl 2017-09-26 13:19:31.787249636 +0200 ++++ openssh/ssh-keygen.c 2017-09-26 13:19:31.802249728 +0200 +@@ -501,40 +501,67 @@ do_convert_private_ssh2_from_blob(u_char free(type); switch (key->type) { @@ -3467,7 +2593,7 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c + if (RSA_set0_key(key->rsa, bn_n, bn_e, bn_d) == 0 || + RSA_set0_factors(key->rsa, bn_p, bn_q) == 0) + fatal("Failed to set RSA parameters"); -+ if ((r = rsa_generate_additional_parameters(key->rsa, bn_iqmp)) != 0) ++ if ((r = ssh_rsa_generate_additional_parameters(key, bn_iqmp)) != 0) + fatal("generate RSA parameters failed: %s", ssh_err(r)); } - if (!BN_set_word(key->rsa->e, e)) { @@ -3480,12 +2606,12 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c - buffer_get_bignum_bits(b, key->rsa->iqmp); - buffer_get_bignum_bits(b, key->rsa->q); - buffer_get_bignum_bits(b, key->rsa->p); -- if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) +- if ((r = ssh_rsa_generate_additional_parameters(key)) != 0) - fatal("generate RSA parameters failed: %s", ssh_err(r)); break; } rlen = sshbuf_len(b); -@@ -621,7 +648,7 @@ do_convert_from_pkcs8(struct sshkey **k, +@@ -642,7 +669,7 @@ do_convert_from_pkcs8(struct sshkey **k, identity_file); } fclose(fp); @@ -3494,7 +2620,7 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c case EVP_PKEY_RSA: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); -@@ -645,7 +672,7 @@ do_convert_from_pkcs8(struct sshkey **k, +@@ -666,7 +693,7 @@ do_convert_from_pkcs8(struct sshkey **k, #endif default: fatal("%s: unsupported pubkey type %d", __func__, @@ -3503,7 +2629,7 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c } EVP_PKEY_free(pubkey); return; -@@ -1683,6 +1710,7 @@ do_ca_sign(struct passwd *pw, int argc, +@@ -1798,6 +1825,7 @@ do_ca_sign(struct passwd *pw, int argc, #ifdef ENABLE_PKCS11 pkcs11_terminate(); #endif @@ -3511,44 +2637,21 @@ diff -up openssh-7.4p1/ssh-keygen.c.openssl openssh-7.4p1/ssh-keygen.c exit(0); } -diff -up openssh-7.4p1/ssh-keyscan.c.openssl openssh-7.4p1/ssh-keyscan.c ---- openssh-7.4p1/ssh-keyscan.c.openssl 2016-12-23 17:47:36.325817708 +0100 -+++ openssh-7.4p1/ssh-keyscan.c 2016-12-23 17:47:36.437817755 +0100 -@@ -195,6 +195,7 @@ keygrab_ssh1(con *c) - static struct sshbuf *msg; - int r; - u_char type; -+ BIGNUM *n = NULL, *e = NULL; - - if (rsa == NULL) { - if ((rsa = sshkey_new(KEY_RSA1)) == NULL) { -@@ -213,16 +214,20 @@ keygrab_ssh1(con *c) - sshbuf_reset(msg); - return NULL; - } -- if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ -+ if ((n = BN_new()) == NULL || (e = BN_new()) == NULL || -+ (r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ - /* server key */ - (r = sshbuf_get_u32(msg, NULL)) != 0 || - (r = sshbuf_get_bignum1(msg, NULL)) != 0 || - (r = sshbuf_get_bignum1(msg, NULL)) != 0 || - /* host key */ - (r = sshbuf_get_u32(msg, NULL)) != 0 || -- (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 || -- (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) { -+ (r = sshbuf_get_bignum1(msg, e)) != 0 || -+ (r = sshbuf_get_bignum1(msg, n)) != 0 || -+ RSA_set0_key(rsa->rsa, n, e, NULL) == 0) { - buf_err: -+ BN_free(n); -+ BN_free(e); - error("%s: buffer error: %s", __func__, ssh_err(r)); - sshbuf_reset(msg); - return NULL; -diff -up openssh-7.4p1/ssh-pkcs11-client.c.openssl openssh-7.4p1/ssh-pkcs11-client.c ---- openssh-7.4p1/ssh-pkcs11-client.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-pkcs11-client.c 2016-12-23 17:47:36.437817755 +0100 +diff -up openssh/sshkey.h.openssl openssh/sshkey.h +--- openssh/sshkey.h.openssl 2017-09-26 13:19:31.780249593 +0200 ++++ openssh/sshkey.h 2017-09-26 13:19:31.803249734 +0200 +@@ -199,7 +199,7 @@ int sshkey_parse_private_fileblob_type(s + const char *passphrase, struct sshkey **keyp, char **commentp); + + /* XXX should be internal, but used by ssh-keygen */ +-int ssh_rsa_generate_additional_parameters(struct sshkey *); ++int ssh_rsa_generate_additional_parameters(struct sshkey *, BIGNUM *iqmp); + + #ifdef SSHKEY_INTERNAL + int ssh_rsa_sign(const struct sshkey *key, +diff -up openssh/ssh-pkcs11-client.c.openssl openssh/ssh-pkcs11-client.c +--- openssh/ssh-pkcs11-client.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-pkcs11-client.c 2017-09-26 13:19:31.803249734 +0200 @@ -143,12 +143,14 @@ pkcs11_rsa_private_encrypt(int flen, con static int wrap_key(RSA *rsa) @@ -3569,9 +2672,9 @@ diff -up openssh-7.4p1/ssh-pkcs11-client.c.openssl openssh-7.4p1/ssh-pkcs11-clie return (0); } -diff -up openssh-7.4p1/ssh-pkcs11.c.openssl openssh-7.4p1/ssh-pkcs11.c ---- openssh-7.4p1/ssh-pkcs11.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-pkcs11.c 2016-12-23 17:47:36.437817755 +0100 +diff -up openssh/ssh-pkcs11.c.openssl openssh/ssh-pkcs11.c +--- openssh/ssh-pkcs11.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-pkcs11.c 2017-09-26 13:19:31.803249734 +0200 @@ -67,7 +67,7 @@ struct pkcs11_key { struct pkcs11_provider *provider; CK_ULONG slotidx; @@ -3656,26 +2759,94 @@ diff -up openssh-7.4p1/ssh-pkcs11.c.openssl openssh-7.4p1/ssh-pkcs11.c + RSA_get0_key(rsa, &n, &e, NULL); + if (rsa && n && e && pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { - key = sshkey_new(KEY_UNSPEC); - key->rsa = rsa; -diff -up openssh-7.4p1/ssh-rsa.c.openssl openssh-7.4p1/ssh-rsa.c ---- openssh-7.4p1/ssh-rsa.c.openssl 2016-12-19 05:59:41.000000000 +0100 -+++ openssh-7.4p1/ssh-rsa.c 2016-12-23 17:47:36.437817755 +0100 -@@ -100,7 +100,7 @@ ssh_rsa_sign(const struct sshkey *key, u - hash_alg = rsa_hash_alg_from_ident(alg_ident); + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); +diff -up openssh/ssh-rsa.c.openssl openssh/ssh-rsa.c +--- openssh/ssh-rsa.c.openssl 2017-09-19 06:26:43.000000000 +0200 ++++ openssh/ssh-rsa.c 2017-09-26 13:19:31.803249734 +0200 +@@ -78,37 +78,46 @@ rsa_hash_alg_nid(int type) + } + } + +-/* calculate p-1 and q-1 */ ++/* calculate d mod p-1 and d mod q-1 */ + int +-ssh_rsa_generate_additional_parameters(struct sshkey *key) ++ssh_rsa_generate_additional_parameters(struct sshkey *key, BIGNUM *iqmp) + { +- RSA *rsa; + BIGNUM *aux = NULL; + BN_CTX *ctx = NULL; + int r; ++ const BIGNUM *p, *q, *d; ++ BIGNUM *dmp1 = NULL, *dmq1 = NULL; + + if (key == NULL || key->rsa == NULL || + sshkey_type_plain(key->type) != KEY_RSA) + return SSH_ERR_INVALID_ARGUMENT; + +- if ((ctx = BN_CTX_new()) == NULL) +- return SSH_ERR_ALLOC_FAIL; +- if ((aux = BN_new()) == NULL) { ++ RSA_get0_factors(key->rsa, &p, &q); ++ RSA_get0_key(key->rsa, NULL, NULL, &d); ++ ++ if ((ctx = BN_CTX_new()) == NULL || ++ (aux = BN_new()) == NULL || ++ (dmp1 = BN_new()) == NULL || ++ (dmq1 = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } +- rsa = key->rsa; + +- if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || +- (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || +- (BN_sub(aux, rsa->p, BN_value_one()) == 0) || +- (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { ++ if ((BN_sub(aux, q, BN_value_one()) == 0) || ++ (BN_mod(dmq1, d, aux, ctx) == 0) || ++ (BN_sub(aux, p, BN_value_one()) == 0) || ++ (BN_mod(dmp1, d, aux, ctx) == 0) || ++ (RSA_set0_crt_params(key->rsa, dmp1, dmq1, iqmp) == 0)) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } ++ dmp1 = NULL; ++ dmq1 = NULL; + r = 0; + out: + BN_clear_free(aux); ++ BN_clear_free(dmp1); ++ BN_clear_free(dmq1); + BN_CTX_free(ctx); + return r; + } +@@ -136,7 +145,7 @@ ssh_rsa_sign(const struct sshkey *key, u if (key == NULL || key->rsa == NULL || hash_alg == -1 || - sshkey_type_plain(key->type) != KEY_RSA || -- BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) -+ RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) + sshkey_type_plain(key->type) != KEY_RSA) return SSH_ERR_INVALID_ARGUMENT; +- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) ++ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) + return SSH_ERR_KEY_LENGTH; slen = RSA_size(key->rsa); if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) -@@ -172,7 +172,7 @@ ssh_rsa_verify(const struct sshkey *key, - - if (key == NULL || key->rsa == NULL || +@@ -210,7 +219,7 @@ ssh_rsa_verify(const struct sshkey *key, sshkey_type_plain(key->type) != KEY_RSA || -- BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE || -+ RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; - +- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) ++ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) + return SSH_ERR_KEY_LENGTH; + + if ((b = sshbuf_from(sig, siglen)) == NULL) +--- openssh-7.6p1/configure.ac.openssl 2017-10-04 15:47:48.440672023 +0200 ++++ openssh-7.6p1/configure.ac 2017-10-04 15:47:23.327531495 +0200 +@@ -2730,6 +2730,7 @@ + AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")]) + ;; + 100*) ;; # 1.0.x ++ 101*) ;; # 1.1.x is supported by this patch too + 200*) ;; # LibreSSL + *) + AC_MSG_ERROR([OpenSSL >= 1.1.0 is not yet supported (have "$ssl_library_ver")]) diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index f973010..b36671d 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -2,26 +2,25 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c --- openssh-7.4p1/channels.c.x11max 2016-12-23 15:46:32.071506625 +0100 +++ openssh-7.4p1/channels.c 2016-12-23 15:46:32.139506636 +0100 @@ -152,8 +152,8 @@ static int all_opens_permitted = 0; + #define FWD_PERMIT_ANY_HOST "*" /* -- X11 forwarding */ - -/* Maximum number of fake X11 displays to try. */ -#define MAX_DISPLAYS 1000 +/* Minimum port number for X11 forwarding */ +#define X11_PORT_MIN 6000 - /* Saved X11 local (client) display. */ - static char *x11_saved_display = NULL; -@@ -4228,7 +4228,8 @@ channel_send_window_changes(void) + /* + * Data structure for storing which hosts are permitted for forward requests. +@@ -4228,7 +4228,7 @@ channel_send_window_changes(void) */ int - x11_create_display_inet(int x11_display_offset, int x11_use_localhost, -- int single_connection, u_int *display_numberp, int **chanids) -+ int x11_max_displays, int single_connection, u_int *display_numberp, -+ int **chanids) + x11_create_display_inet(struct ssh *ssh, int x11_display_offset, +- int x11_use_localhost, int single_connection, ++ int x11_use_localhost, int x11_max_displays, int single_connection, + u_int *display_numberp, int **chanids) { Channel *nc = NULL; - int display_number, sock; @@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_ if (chanids == NULL) return -1; @@ -38,7 +37,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c + if (port < X11_PORT_MIN) /* overflow */ + break; memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; + hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; @@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_ if (num_socks > 0) @@ -51,7 +50,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c } @@ -4441,7 +4447,7 @@ x11_connect_display(void) memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; + hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%u", 6000 + display_number); + snprintf(strport, sizeof strport, "%u", X11_PORT_MIN + display_number); @@ -71,8 +70,8 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c } freeaddrinfo(aitop); if (!ai) { -- error("connect %.100s port %u: %.100s", buf, 6000 + display_number, -- strerror(errno)); +- error("connect %.100s port %u: %.100s", buf, +- 6000 + display_number, strerror(errno)); + error("connect %.100s port %u: %.100s", buf, + X11_PORT_MIN + display_number, strerror(errno)); return -1; @@ -83,13 +82,13 @@ diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h +++ openssh-7.4p1/channels.h 2016-12-23 15:46:32.139506636 +0100 @@ -293,7 +293,7 @@ int permitopen_port(const char *); - void channel_set_x11_refuse_time(u_int); - int x11_connect_display(void); --int x11_create_display_inet(int, int, int, u_int *, int **); -+int x11_create_display_inet(int, int, int, int, u_int *, int **); - int x11_input_open(int, u_int32_t, void *); - void x11_request_forwarding_with_spoofing(int, const char *, const char *, - const char *, int); + void channel_set_x11_refuse_time(struct ssh *, u_int); + int x11_connect_display(struct ssh *); +-int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **); ++int x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **); + void x11_request_forwarding_with_spoofing(struct ssh *, int, + const char *, const char *, const char *, int); + diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c --- openssh-7.4p1/servconf.c.x11max 2016-12-23 15:46:32.133506635 +0100 +++ openssh-7.4p1/servconf.c 2016-12-23 15:47:27.320519121 +0100 @@ -179,7 +178,7 @@ diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c @@ -2518,8 +2518,9 @@ session_setup_x11fwd(Session *s) return 0; } - if (x11_create_display_inet(options.x11_display_offset, + if (x11_create_display_inet(ssh, options.x11_display_offset, - options.x11_use_localhost, s->single_connection, - &s->display_number, &s->x11_chanids) == -1) { + options.x11_use_localhost, options.x11_max_displays, diff --git a/openssh-7.5p1-gss-environment.patch b/openssh-7.5p1-gss-environment.patch index cba5696..5b5d661 100644 --- a/openssh-7.5p1-gss-environment.patch +++ b/openssh-7.5p1-gss-environment.patch @@ -62,8 +62,8 @@ index 954a0dd..0819483 100644 char *krb5_ccname; + int krb5_set_env; #endif - Buffer *loginmsg; - void *methoddata; + struct sshbuf *loginmsg; + @@ -220,7 +221,7 @@ int sys_auth_passwd(Authctxt *, const char *); #if defined(KRB5) && !defined(HEIMDAL) @@ -240,9 +240,9 @@ index 6f2b0ac..73ef2c2 100644 void ssh_gssapi_cleanup_creds(void); -void ssh_gssapi_storecreds(void); +int ssh_gssapi_storecreds(void); + const char *ssh_gssapi_displayname(void); char *ssh_gssapi_server_mechanisms(void); - int ssh_gssapi_oid_table_ok(); diff --git a/sshd.c b/sshd.c index ce2e374..3c4e13e 100644 --- a/sshd.c diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index b65731c..75b7e6e 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -1,28 +1,3 @@ -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 3a1aedce72c2..a8d472a63ccb 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -50,6 +50,9 @@ - #include - - #include -+#ifdef __s390__ -+#include -+#endif - - #include - #include -@@ -235,7 +235,7 @@ static const struct sock_filter preauth_insns[] = { - * x86-64 syscall under some circumstances, e.g. - * https://bugs.debian.org/849923 - */ -- SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT); -+ SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT), - #endif - - /* Default deny */ - - In order to use the OpenSSL-ibmpkcs11 engine it is needed to allow flock and ipc calls, because this engine calls OpenCryptoki (a PKCS#11 implementation) which calls the libraries that will communicate with the diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch new file mode 100644 index 0000000..c9e3e24 --- /dev/null +++ b/openssh-7.6p1-audit.patch @@ -0,0 +1,2151 @@ +diff -up openssh-7.6p1/audit-bsm.c.audit openssh-7.6p1/audit-bsm.c +--- openssh-7.6p1/audit-bsm.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/audit-bsm.c 2017-10-04 17:18:32.834505048 +0200 +@@ -373,10 +373,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 +@@ -391,6 +404,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) + { +@@ -452,4 +471,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-7.6p1/audit.c.audit openssh-7.6p1/audit.c +--- openssh-7.6p1/audit.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/audit.c 2017-10-04 17:18:32.834505048 +0200 +@@ -26,6 +26,7 @@ + + #include + #include ++#include + + #ifdef SSH_AUDIT_EVENTS + +@@ -34,6 +35,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 +@@ -41,6 +47,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 +@@ -69,13 +76,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); + } + +@@ -109,6 +113,37 @@ 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); ++ crypto_name = key_ssh_name(key); ++ if (audit_keyusage(host_user, crypto_name, sshkey_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. +@@ -138,6 +173,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. + * +@@ -172,13 +218,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, result %d", ++ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits, ++ 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-7.6p1/audit.h.audit openssh-7.6p1/audit.h +--- openssh-7.6p1/audit.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/audit.h 2017-10-04 17:18:32.834505048 +0200 +@@ -26,6 +26,7 @@ + # define _SSH_AUDIT_H + + #include "loginrec.h" ++#include "key.h" + + enum ssh_audit_event_type { + SSH_LOGIN_EXCEED_MAXTRIES, +@@ -43,13 +44,33 @@ enum ssh_audit_event_type { + SSH_CONNECTION_ABANDON, /* closed without completing auth */ + SSH_AUDIT_UNKNOWN + }; ++ ++enum ssh_audit_kex { ++ SSH_AUDIT_UNSUPPORTED_CIPHER, ++ SSH_AUDIT_UNSUPPORTED_MAC, ++ SSH_AUDIT_UNSUPPORTED_COMPRESSION ++}; + 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-7.6p1/audit-linux.c.audit openssh-7.6p1/audit-linux.c +--- openssh-7.6p1/audit-linux.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/audit-linux.c 2017-10-04 17:18:32.835505053 +0200 +@@ -33,25 +33,38 @@ + + #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" ++#include "channels.h" ++#include "session.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; + + if ((audit_fd = audit_open()) < 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,9 +78,97 @@ linux_audit_record_event(int uid, const + 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", ssh_remote_port(active_state)); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, ssh_remote_ipaddr(active_state), NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", ++ type, bits, fp, ssh_remote_port(active_state)); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, ssh_remote_ipaddr(active_state), 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 +@@ -76,24 +177,51 @@ audit_connection_from(const char *host, + /* 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, session_get_remote_name_or_ip(active_state, utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_LOGIN); ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, session_get_remote_name_or_ip(active_state, 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, session_get_remote_name_or_ip(active_state, 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, session_get_remote_name_or_ip(active_state, 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 +@@ -103,24 +231,180 @@ 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, ++ ssh_remote_ipaddr(ssh), "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, ++ ssh_remote_ipaddr(ssh), "ssh", 0, event); ++ linux_audit_user_logxxx(-1, audit_username(), NULL, ++ ssh_remote_ipaddr(ssh), "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, ++ ssh_remote_ipaddr(ssh), "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, ++ session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_END); ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, ++ session_get_remote_name_or_ip(ssh, 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, +- ssh_remote_ipaddr(ssh), "sshd", 0); ++ linux_audit_user_logxxx(-1, audit_username(), NULL, ++ ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN); + break; + default: + debug("%s: unhandled event %d", __func__, event); + break; + } + } ++ ++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], ssh_remote_port(active_state), (s = get_local_ipaddr(packet_get_connection_in())), ++ ssh_local_port(active_state)); ++ 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, ssh_remote_ipaddr(active_state), 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 struct sshcipher *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, ++ ssh_remote_port(active_state), (s = get_local_ipaddr(packet_get_connection_in())), ssh_local_port(active_state)); ++ 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, ssh_remote_ipaddr(active_state), 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, ++ ssh_remote_port(active_state), ++ (s = get_local_ipaddr(packet_get_connection_in())), ++ ssh_local_port(active_state)); ++ 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, ssh_remote_ipaddr(active_state), 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() ? NULL : ssh_remote_ipaddr(active_state), ++ 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-7.6p1/auditstub.c.audit openssh-7.6p1/auditstub.c +--- openssh-7.6p1/auditstub.c.audit 2017-10-04 17:18:32.835505053 +0200 ++++ openssh-7.6p1/auditstub.c 2017-10-04 17:18:32.835505053 +0200 +@@ -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 ++ */ ++ ++#include ++ ++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-7.6p1/auth2.c.audit openssh-7.6p1/auth2.c +--- openssh-7.6p1/auth2.c.audit 2017-10-04 17:18:32.746504598 +0200 ++++ openssh-7.6p1/auth2.c 2017-10-04 17:18:32.835505053 +0200 +@@ -255,9 +255,6 @@ input_userauth_request(int type, u_int32 + } else { + /* Invalid user, fake password information */ + authctxt->pw = fakepw(); +-#ifdef SSH_AUDIT_EVENTS +- PRIVSEP(audit_event(SSH_INVALID_USER)); +-#endif + } + #ifdef USE_PAM + if (options.use_pam) +diff -up openssh-7.6p1/auth2-hostbased.c.audit openssh-7.6p1/auth2-hostbased.c +--- openssh-7.6p1/auth2-hostbased.c.audit 2017-10-04 17:18:32.683504276 +0200 ++++ openssh-7.6p1/auth2-hostbased.c 2017-10-04 17:18:32.835505053 +0200 +@@ -152,7 +152,7 @@ userauth_hostbased(struct ssh *ssh) + /* test for allowed key and correct signature */ + authenticated = 0; + if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && +- PRIVSEP(sshkey_verify(key, sig, slen, ++ PRIVSEP(hostbased_key_verify(key, sig, slen, + sshbuf_ptr(b), sshbuf_len(b), ssh->compat)) == 0) + authenticated = 1; + +@@ -169,6 +169,19 @@ done: + return authenticated; + } + ++int ++hostbased_key_verify(const struct sshkey *key, const u_char *sig, size_t slen, ++ const u_char *data, size_t datalen, u_int compat) ++{ ++ int rv; ++ ++ rv = sshkey_verify(key, sig, slen, data, datalen, compat); ++#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-7.6p1/auth2-pubkey.c.audit openssh-7.6p1/auth2-pubkey.c +--- openssh-7.6p1/auth2-pubkey.c.audit 2017-10-04 17:18:32.828505018 +0200 ++++ openssh-7.6p1/auth2-pubkey.c 2017-10-04 17:18:32.835505053 +0200 +@@ -206,7 +206,7 @@ userauth_pubkey(struct ssh *ssh) + /* test for correct signature */ + authenticated = 0; + if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && +- PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), ++ PRIVSEP(user_key_verify(key, sig, slen, sshbuf_ptr(b), + sshbuf_len(b), ssh->compat)) == 0) { + authenticated = 1; + } +@@ -250,6 +250,19 @@ done: + return authenticated; + } + ++int ++user_key_verify(const struct sshkey *key, const u_char *sig, size_t slen, ++ const u_char *data, size_t datalen, u_int compat) ++{ ++ int rv; ++ ++ rv = sshkey_verify(key, sig, slen, data, datalen, compat); ++#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-7.6p1/auth.c.audit openssh-7.6p1/auth.c +--- openssh-7.6p1/auth.c.audit 2017-10-04 17:18:32.746504598 +0200 ++++ openssh-7.6p1/auth.c 2017-10-04 17:18:32.835505053 +0200 +@@ -599,9 +599,6 @@ getpwnamallow(const char *user) + record_failed_login(user, + auth_get_canonical_hostname(ssh, 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-7.6p1/auth.h.audit openssh-7.6p1/auth.h +--- openssh-7.6p1/auth.h.audit 2017-10-04 17:18:32.768504711 +0200 ++++ openssh-7.6p1/auth.h 2017-10-04 17:18:32.836505059 +0200 +@@ -198,6 +198,7 @@ struct passwd * getpwnamallow(const char + + char *expand_authorized_keys(const char *, struct passwd *pw); + char *authorized_principals_file(struct passwd *); ++int user_key_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, u_int); + + FILE *auth_openkeyfile(const char *, struct passwd *, int); + FILE *auth_openprincipals(const char *, struct passwd *, int); +@@ -217,6 +218,7 @@ struct sshkey *get_hostkey_private_by_ty + int get_hostkey_index(struct sshkey *, int, struct ssh *); + int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **, + size_t *, const u_char *, size_t, const char *, u_int); ++int hostbased_key_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, u_int); + + /* debug messages during authentication */ + void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); +diff -up openssh-7.6p1/cipher.c.audit openssh-7.6p1/cipher.c +--- openssh-7.6p1/cipher.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/cipher.c 2017-10-04 17:18:32.836505059 +0200 +@@ -61,25 +61,6 @@ struct sshcipher_ctx { + const struct sshcipher *cipher; + }; + +-struct sshcipher { +- char *name; +- u_int block_size; +- u_int key_len; +- u_int iv_len; /* defaults to block_size */ +- u_int auth_len; +- u_int flags; +-#define CFLAG_CBC (1<<0) +-#define CFLAG_CHACHAPOLY (1<<1) +-#define CFLAG_AESCTR (1<<2) +-#define CFLAG_NONE (1<<3) +-#define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */ +-#ifdef WITH_OPENSSL +- const EVP_CIPHER *(*evptype)(void); +-#else +- void *ignored; +-#endif +-}; +- + static const struct sshcipher ciphers[] = { + #ifdef WITH_OPENSSL + { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc }, +diff -up openssh-7.6p1/cipher.h.audit openssh-7.6p1/cipher.h +--- openssh-7.6p1/cipher.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/cipher.h 2017-10-04 17:18:32.836505059 +0200 +@@ -45,7 +45,25 @@ + #define CIPHER_ENCRYPT 1 + #define CIPHER_DECRYPT 0 + +-struct sshcipher; ++struct sshcipher { ++ char *name; ++ u_int block_size; ++ u_int key_len; ++ u_int iv_len; /* defaults to block_size */ ++ u_int auth_len; ++ u_int flags; ++#define CFLAG_CBC (1<<0) ++#define CFLAG_CHACHAPOLY (1<<1) ++#define CFLAG_AESCTR (1<<2) ++#define CFLAG_NONE (1<<3) ++#define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */ ++#ifdef WITH_OPENSSL ++ const EVP_CIPHER *(*evptype)(void); ++#else ++ void *ignored; ++#endif ++}; ++ + struct sshcipher_ctx; + + const struct sshcipher *cipher_by_name(const char *); +diff -up openssh-7.6p1/kex.c.audit openssh-7.6p1/kex.c +--- openssh-7.6p1/kex.c.audit 2017-10-04 17:18:32.822504987 +0200 ++++ openssh-7.6p1/kex.c 2017-10-04 17:18:32.836505059 +0200 +@@ -54,6 +54,7 @@ + #include "ssherr.h" + #include "sshbuf.h" + #include "digest.h" ++#include "audit.h" + + #ifdef GSSAPI + #include "ssh-gss.h" +@@ -692,8 +693,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(SSH_AUDIT_UNSUPPORTED_CIPHER); ++#endif + return SSH_ERR_NO_CIPHER_ALG_MATCH; ++ } + if ((enc->cipher = cipher_by_name(name)) == NULL) { + free(name); + return SSH_ERR_INTERNAL_ERROR; +@@ -713,8 +718,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(SSH_AUDIT_UNSUPPORTED_MAC); ++#endif + return SSH_ERR_NO_MAC_ALG_MATCH; ++ } + if (mac_setup(mac, name) < 0) { + free(name); + return SSH_ERR_INTERNAL_ERROR; +@@ -733,8 +742,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(SSH_AUDIT_UNSUPPORTED_COMPRESSION); ++#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) { +@@ -904,6 +917,10 @@ kex_choose_conf(struct ssh *ssh) + dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); + dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); + dh_need = MAXIMUM(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; +@@ -1037,3 +1054,33 @@ 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->iv_len); ++ 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-7.6p1/kex.h.audit openssh-7.6p1/kex.h +--- openssh-7.6p1/kex.h.audit 2017-10-04 17:18:32.822504987 +0200 ++++ openssh-7.6p1/kex.h 2017-10-04 17:18:32.836505059 +0200 +@@ -219,6 +219,8 @@ int kexgss_client(struct ssh *); + int kexgss_server(struct ssh *); + #endif + ++void newkeys_destroy(struct newkeys *newkeys); ++ + int kex_dh_hash(int, 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-7.6p1/key.h.audit openssh-7.6p1/key.h +--- openssh-7.6p1/key.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/key.h 2017-10-04 17:18:32.836505059 +0200 +@@ -43,6 +43,7 @@ typedef struct sshkey Key; + #define key_ssh_name_plain sshkey_ssh_name_plain + #define key_type_from_name sshkey_type_from_name + #define key_is_cert sshkey_is_cert ++#define key_is_private sshkey_is_private + #define key_type_plain sshkey_type_plain + #endif + +diff -up openssh-7.6p1/mac.c.audit openssh-7.6p1/mac.c +--- openssh-7.6p1/mac.c.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/mac.c 2017-10-04 17:18:32.836505059 +0200 +@@ -242,6 +242,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-7.6p1/mac.h.audit openssh-7.6p1/mac.h +--- openssh-7.6p1/mac.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/mac.h 2017-10-04 17:18:32.837505064 +0200 +@@ -49,5 +49,6 @@ int mac_compute(struct sshmac *, u_int3 + int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, + const u_char *, size_t); + void mac_clear(struct sshmac *); ++void mac_destroy(struct sshmac *); + + #endif /* SSHMAC_H */ +diff -up openssh-7.6p1/Makefile.in.audit openssh-7.6p1/Makefile.in +--- openssh-7.6p1/Makefile.in.audit 2017-10-04 17:18:32.749504614 +0200 ++++ openssh-7.6p1/Makefile.in 2017-10-04 17:18:32.837505064 +0200 +@@ -100,7 +100,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + 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 \ +- platform-pledge.o platform-tracing.o platform-misc.o ++ platform-pledge.o platform-tracing.o platform-misc.o \ ++ auditstub.o + + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ + sshconnect.o sshconnect2.o mux.o +diff -up openssh-7.6p1/monitor.c.audit openssh-7.6p1/monitor.c +--- openssh-7.6p1/monitor.c.audit 2017-10-04 17:18:32.824504997 +0200 ++++ openssh-7.6p1/monitor.c 2017-10-04 17:18:32.837505064 +0200 +@@ -102,6 +102,7 @@ + #include "compat.h" + #include "ssh2.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 *); +@@ -222,6 +230,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}, +@@ -260,6 +272,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} + }; +@@ -1396,7 +1413,9 @@ mm_answer_keyverify(int sock, struct ssh + u_char *signature, *data, *blob; + size_t signaturelen, datalen, bloblen; + int r, ret, valid_data = 0, encoded_ret; ++ int type = 0; + ++ type = buffer_get_int(m); + if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || + (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || + (r = sshbuf_get_string(m, &data, &datalen)) != 0) +@@ -1405,6 +1424,8 @@ mm_answer_keyverify(int sock, struct ssh + 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__); + + /* XXX use sshkey_froms here; need to change key_blob, etc. */ + if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0) +@@ -1414,21 +1435,24 @@ mm_answer_keyverify(int sock, struct ssh + case MM_USERKEY: + valid_data = monitor_valid_userblob(data, datalen); + auth_method = "publickey"; ++ ret = user_key_verify(key, signature, signaturelen, data, ++ datalen, active_state->compat); + break; + case MM_HOSTKEY: + valid_data = monitor_valid_hostbasedblob(data, datalen, + hostbased_cuser, hostbased_chost); ++ ret = hostbased_key_verify(key, signature, signaturelen, data, ++ datalen, active_state->compat); + auth_method = "hostbased"; + break; + default: + valid_data = 0; ++ ret = 0; + break; + } + if (!valid_data) + fatal("%s: bad signature data blob", __func__); + +- ret = sshkey_verify(key, signature, signaturelen, data, datalen, +- active_state->compat); + debug3("%s: %s %p signature %s", __func__, auth_method, key, + (ret == 0) ? "verified" : "unverified"); + auth2_record_key(authctxt, ret == 0, key); +@@ -1485,6 +1509,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); + } + +@@ -1588,6 +1618,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); +@@ -1630,11 +1662,45 @@ 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; ++#ifdef SSH_AUDIT_EVENTS ++ s->command_handle = audit_run_command(cmd); ++#endif ++ ++ 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); + } +@@ -1702,6 +1768,7 @@ monitor_apply_keystate(struct monitor *p + void + mm_get_keystate(struct monitor *pmonitor) + { ++ Buffer m; + debug3("%s: Waiting for new keys", __func__); + + if ((child_state = sshbuf_new()) == NULL) +@@ -1709,6 +1776,19 @@ 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 ++ 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) ++ ; ++ + } + + +@@ -1976,3 +2056,86 @@ 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); ++ ++ return 0; ++} ++#endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-7.6p1/monitor.h.audit openssh-7.6p1/monitor.h +--- openssh-7.6p1/monitor.h.audit 2017-10-04 17:18:32.781504777 +0200 ++++ openssh-7.6p1/monitor.h 2017-10-04 17:18:32.837505064 +0200 +@@ -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 + + }; + +diff -up openssh-7.6p1/monitor_wrap.c.audit openssh-7.6p1/monitor_wrap.c +--- openssh-7.6p1/monitor_wrap.c.audit 2017-10-04 17:18:32.750504619 +0200 ++++ openssh-7.6p1/monitor_wrap.c 2017-10-04 17:18:32.838505069 +0200 +@@ -463,7 +463,7 @@ mm_key_allowed(enum mm_keytype type, con + */ + + int +-mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, ++mm_sshkey_verify(enum mm_keytype type, const struct sshkey *key, const u_char *sig, size_t siglen, + const u_char *data, size_t datalen, u_int compat) + { + Buffer m; +@@ -478,6 +478,7 @@ mm_sshkey_verify(const struct sshkey *ke + 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); +@@ -497,6 +498,20 @@ mm_sshkey_verify(const struct sshkey *ke + return 0; + } + ++int ++mm_hostbased_key_verify(const struct sshkey *key, const u_char *sig, size_t siglen, ++ const u_char *data, size_t datalen, u_int compat) ++{ ++ return mm_sshkey_verify(MM_HOSTKEY, key, sig, siglen, data, datalen, compat); ++} ++ ++int ++mm_user_key_verify(const struct sshkey *key, const u_char *sig, size_t siglen, ++ const u_char *data, size_t datalen, u_int compat) ++{ ++ return mm_sshkey_verify(MM_USERKEY, key, sig, siglen, data, datalen, compat); ++} ++ + void + mm_send_keystate(struct monitor *monitor) + { +@@ -874,10 +889,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); + +@@ -885,6 +901,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 */ +@@ -1020,3 +1056,70 @@ 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); ++ buffer_free(&m); ++} ++#endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-7.6p1/monitor_wrap.h.audit openssh-7.6p1/monitor_wrap.h +--- openssh-7.6p1/monitor_wrap.h.audit 2017-10-04 17:18:32.750504619 +0200 ++++ openssh-7.6p1/monitor_wrap.h 2017-10-04 17:18:32.838505069 +0200 +@@ -53,7 +53,9 @@ int mm_key_allowed(enum mm_keytype, cons + int mm_user_key_allowed(struct passwd *, struct sshkey *, int); + int mm_hostbased_key_allowed(struct passwd *, const char *, + const char *, struct sshkey *); +-int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, ++int mm_hostbased_key_verify(const struct sshkey *, const u_char *, size_t, ++ const u_char *, size_t, u_int); ++int mm_user_key_verify(const struct sshkey *, const u_char *, size_t, + const u_char *, size_t, u_int); + + #ifdef GSSAPI +@@ -78,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-7.6p1/packet.c.audit openssh-7.6p1/packet.c +--- openssh-7.6p1/packet.c.audit 2017-10-04 17:18:32.672504220 +0200 ++++ openssh-7.6p1/packet.c 2017-10-04 17:25:48.141741390 +0200 +@@ -67,6 +67,7 @@ + #include "key.h" /* typedefs XXX */ + + #include "xmalloc.h" ++#include "audit.h" + #include "crc32.h" + #include "compat.h" + #include "ssh2.h" +@@ -502,6 +503,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. +@@ -566,18 +574,11 @@ ssh_packet_close_internal(struct ssh *ss + { + struct session_state *state = ssh->state; + u_int mode; ++ u_int had_keys = packet_state_has_keys(state); + + if (!state->initialized) + return; + state->initialized = 0; +- if (do_close) { +- if (state->connection_in == state->connection_out) { +- 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); +@@ -615,8 +616,16 @@ ssh_packet_close_internal(struct ssh *ss + } + cipher_free(state->send_context); + cipher_free(state->receive_context); ++ if (had_keys) ++ audit_session_key_free(MODE_MAX); + state->send_context = state->receive_context = NULL; + if (do_close) { ++ if (state->connection_in == state->connection_out) { ++ close(state->connection_out); ++ } else { ++ close(state->connection_in); ++ close(state->connection_out); ++ } + free(ssh->remote_ipaddr); + ssh->remote_ipaddr = NULL; + free(ssh->state); +@@ -854,6 +863,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + (unsigned long long)state->p_read.blocks, + (unsigned long long)state->p_send.bytes, + (unsigned long long)state->p_send.blocks); ++ audit_session_key_free(mode); + cipher_free(*ccp); + *ccp = NULL; + kex_free_newkeys(state->newkeys[mode]); +@@ -2135,6 +2145,72 @@ 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_free(state->receive_context); ++ cipher_free(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)); ++ if (active_state != NULL) ++ packet_destroy_state(active_state->state); ++ if (audit_it) { ++#ifdef SSH_AUDIT_EVENTS ++ if (privsep) ++ audit_session_key_free(MODE_MAX); ++ else ++ audit_session_key_free_body(MODE_MAX, getpid(), getuid()); ++#endif ++ } ++} ++ + /* Reset after_authentication and reset compression in post-auth privsep */ + static int + ssh_packet_set_postauth(struct ssh *ssh) +diff -up openssh-7.6p1/packet.h.audit openssh-7.6p1/packet.h +--- openssh-7.6p1/packet.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/packet.h 2017-10-04 17:18:32.838505069 +0200 +@@ -217,4 +217,5 @@ extern struct ssh *active_state; + # undef EC_POINT + #endif + ++void packet_destroy_all(int, int); + #endif /* PACKET_H */ +diff -up openssh-7.6p1/session.c.audit openssh-7.6p1/session.c +--- openssh-7.6p1/session.c.audit 2017-10-04 17:18:32.812504936 +0200 ++++ openssh-7.6p1/session.c 2017-10-04 17:18:32.839505074 +0200 +@@ -138,7 +138,7 @@ extern char *__progname; + 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. */ +@@ -605,6 +605,14 @@ do_exec_pty(struct ssh *ssh, Session *s, + /* Parent. Close the slave side of the pseudo tty. */ + close(ttyfd); + ++#if !defined(HAVE_OSF_SIA) && defined(SSH_AUDIT_EVENTS) ++ /* do_login in the child did not affect state in this process, ++ compensate. From an architectural standpoint, this is extremely ++ ugly. */ ++ if (command != NULL) ++ audit_count_session_open(); ++#endif ++ + /* Enter interactive session. */ + s->ptymaster = ptymaster; + packet_set_interactive(1, +@@ -724,15 +732,19 @@ do_exec(struct ssh *ssh, Session *s, con + s->self); + + #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(ssh, s, command); +@@ -1499,8 +1511,11 @@ do_child(struct ssh *ssh, Session *s, co + int r = 0; + + /* remove hostkey from the child's memory */ +- destroy_sensitive_data(); ++ destroy_sensitive_data(1); + packet_clear_keys(); ++ /* 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) { +@@ -1714,6 +1729,9 @@ session_unused(int id) + sessions[id].ttyfd = -1; + sessions[id].ptymaster = -1; + sessions[id].x11_chanids = NULL; ++#ifdef SSH_AUDIT_EVENTS ++ sessions[id].command_handle = -1; ++#endif + sessions[id].next_unused = sessions_first_unused; + sessions_first_unused = id; + } +@@ -1796,6 +1814,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("%s: unknown id %d", __func__, id); ++ session_dump(); ++ return NULL; ++} ++ ++Session * + session_by_tty(char *tty) + { + int i; +@@ -2307,6 +2338,32 @@ session_exit_message(struct ssh *ssh, Se + chan_write_failed(ssh, 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(struct ssh *ssh, Session *s) + { +@@ -2320,6 +2377,10 @@ session_close(struct ssh *ssh, Session * + + 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); +@@ -2528,6 +2589,15 @@ do_authenticated2(struct ssh *ssh, Authc + server_loop2(ssh, 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(struct ssh *ssh, Authctxt *authctxt) + { +@@ -2585,7 +2655,7 @@ do_cleanup(struct ssh *ssh, Authctxt *au + * or if running in monitor. + */ + if (!use_privsep || mm_is_monitor()) +- session_destroy_all(ssh, session_pty_cleanup2); ++ session_destroy_all(ssh, do_cleanup_one_session); + } + + /* Return a name for the remote host that fits inside utmp_size */ +diff -up openssh-7.6p1/session.h.audit openssh-7.6p1/session.h +--- openssh-7.6p1/session.h.audit 2017-10-02 21:34:26.000000000 +0200 ++++ openssh-7.6p1/session.h 2017-10-04 17:18:32.839505074 +0200 +@@ -60,6 +60,12 @@ struct Session { + char *name; + char *val; + } *env; ++ ++ /* exec */ ++#ifdef SSH_AUDIT_EVENTS ++ int command_handle; ++ char *command; ++#endif + }; + + void do_authenticated(struct ssh *, Authctxt *); +@@ -72,8 +78,10 @@ void session_close_by_pid(struct ssh *s + void session_close_by_channel(struct ssh *, int, void *); + void session_destroy_all(struct ssh *, 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(struct ssh *, Session *); + void do_setusercontext(struct passwd *); +diff -up openssh-7.6p1/sshd.c.audit openssh-7.6p1/sshd.c +--- openssh-7.6p1/sshd.c.audit 2017-10-04 17:18:32.830505028 +0200 ++++ openssh-7.6p1/sshd.c 2017-10-04 17:18:32.839505074 +0200 +@@ -122,6 +122,7 @@ + #include "ssh-gss.h" + #endif + #include "monitor_wrap.h" ++#include "audit.h" + #include "ssh-sandbox.h" + #include "version.h" + #include "ssherr.h" +@@ -248,7 +249,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); + static void do_ssh2_kex(void); + +@@ -265,6 +266,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) + { +@@ -475,18 +485,45 @@ sshd_exchange_identification(struct ssh + } + } + +-/* 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; ++#ifdef SSH_AUDIT_EVENTS ++ pid_t pid; ++ uid_t uid; + ++ pid = getpid(); ++ uid = getuid(); ++#endif + 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) { ++#ifdef SSH_AUDIT_EVENTS ++ if (privsep) ++ PRIVSEP(audit_destroy_sensitive_data(fp, ++ pid, uid)); ++ else ++ audit_destroy_sensitive_data(fp, ++ pid, uid); ++#endif ++ 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; + } +@@ -499,12 +536,30 @@ demote_sensitive_data(void) + { + struct sshkey *tmp; + int i; ++#ifdef SSH_AUDIT_EVENTS ++ pid_t pid; ++ uid_t uid; + ++ pid = getpid(); ++ uid = getuid(); ++#endif + 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 (fp != NULL) { ++#ifdef SSH_AUDIT_EVENTS ++ audit_destroy_sensitive_data(fp, pid, uid); ++#endif ++ free(fp); ++ } + } + /* Certs do not need demotion */ + } +@@ -587,7 +642,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) { +@@ -1162,6 +1217,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); +@@ -2165,6 +2221,9 @@ main(int ac, char **av) + do_authenticated(ssh, 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); +@@ -2344,6 +2403,15 @@ void + cleanup_exit(int i) + { + struct ssh *ssh = active_state; /* XXX */ ++ 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(ssh, the_authctxt); +@@ -2356,9 +2424,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-7.6p1/sshkey.c.audit openssh-7.6p1/sshkey.c +--- openssh-7.6p1/sshkey.c.audit 2017-10-04 17:18:32.758504660 +0200 ++++ openssh-7.6p1/sshkey.c 2017-10-04 17:18:32.839505074 +0200 +@@ -295,6 +295,32 @@ sshkey_type_is_valid_ca(int type) + } + + int ++sshkey_is_private(const struct sshkey *k) ++{ ++ switch (k->type) { ++#ifdef WITH_OPENSSL ++ case KEY_RSA_CERT: ++ case KEY_RSA: ++ return k->rsa->d != NULL; ++ 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 /* OPENSSL_HAS_ECC */ ++#endif /* WITH_OPENSSL */ ++ 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-7.6p1/sshkey.h.audit openssh-7.6p1/sshkey.h +--- openssh-7.6p1/sshkey.h.audit 2017-10-04 17:18:32.758504660 +0200 ++++ openssh-7.6p1/sshkey.h 2017-10-04 17:18:32.840505079 +0200 +@@ -133,6 +133,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 --git a/openssh-7.6p1-cleanup-selinux.patch b/openssh-7.6p1-cleanup-selinux.patch new file mode 100644 index 0000000..49510f7 --- /dev/null +++ b/openssh-7.6p1-cleanup-selinux.patch @@ -0,0 +1,253 @@ +diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c +--- openssh/auth2-pubkey.c.refactor 2017-09-27 13:10:19.556830609 +0200 ++++ openssh/auth2-pubkey.c 2017-09-27 13:10:19.677831274 +0200 +@@ -72,6 +72,9 @@ + extern ServerOptions options; + extern u_char *session_id2; + extern u_int session_id2_len; ++extern int inetd_flag; ++extern int rexeced_flag; ++extern Authctxt *the_authctxt; + + static int + userauth_pubkey(struct ssh *ssh) +@@ -432,7 +435,8 @@ match_principals_command(struct passwd * + + if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command, + ac, av, &f, +- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) ++ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, ++ (inetd_flag && !rexeced_flag), the_authctxt)) == 0) + goto out; + + uid_swapped = 1; +@@ -762,7 +766,8 @@ user_key_command_allowed2(struct passwd + + if ((pid = subprocess("AuthorizedKeysCommand", pw, command, + ac, av, &f, +- SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0) ++ SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, ++ (inetd_flag && !rexeced_flag), the_authctxt)) == 0) + goto out; + + uid_swapped = 1; +diff -up openssh/misc.c.refactor openssh/misc.c +--- openssh/misc.c.refactor 2017-09-27 13:10:19.640831071 +0200 ++++ openssh/misc.c 2017-09-27 13:10:19.678831279 +0200 +@@ -1435,7 +1435,8 @@ argv_assemble(int argc, char **argv) + */ + pid_t + subprocess(const char *tag, struct passwd *pw, const char *command, +- int ac, char **av, FILE **child, u_int flags) ++ int ac, char **av, FILE **child, u_int flags, int inetd, ++ void *the_authctxt) + { + FILE *f = NULL; + struct stat st; +@@ -1551,7 +1552,7 @@ subprocess(const char *tag, struct passw + } + + #ifdef WITH_SELINUX +- if (sshd_selinux_setup_env_variables() < 0) { ++ if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) { + error ("failed to copy environment: %s", + strerror(errno)); + _exit(127); +diff -up openssh/misc.h.refactor openssh/misc.h +--- openssh/misc.h.refactor 2017-09-25 01:48:10.000000000 +0200 ++++ openssh/misc.h 2017-09-27 13:10:19.678831279 +0200 +@@ -144,7 +144,7 @@ int exited_cleanly(pid_t, const char *, + #define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */ + #define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */ + pid_t subprocess(const char *, struct passwd *, +- const char *, int, char **, FILE **, u_int flags); ++ const char *, int, char **, FILE **, u_int flags, int, void *); + + struct stat; + int safe_path(const char *, struct stat *, const char *, uid_t, +diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h +--- openssh/openbsd-compat/port-linux.h.refactor 2017-09-27 13:10:19.634831038 +0200 ++++ openssh/openbsd-compat/port-linux.h 2017-09-27 13:10:54.954025248 +0200 +@@ -26,8 +26,8 @@ void ssh_selinux_setfscreatecon(const ch + + int sshd_selinux_enabled(void); + void sshd_selinux_copy_context(void); +-void sshd_selinux_setup_exec_context(char *); +-int sshd_selinux_setup_env_variables(void); ++void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int); ++int sshd_selinux_setup_env_variables(int inetd, void *); + void sshd_selinux_change_privsep_preauth_context(void); + #endif + +diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compat/port-linux-sshd.c +--- openssh/openbsd-compat/port-linux-sshd.c.refactor 2017-09-27 13:10:19.634831038 +0200 ++++ openssh/openbsd-compat/port-linux-sshd.c 2017-09-27 13:12:06.811420371 +0200 +@@ -48,11 +48,6 @@ + #include + #endif + +-extern ServerOptions options; +-extern Authctxt *the_authctxt; +-extern int inetd_flag; +-extern int rexeced_flag; +- + /* Wrapper around is_selinux_enabled() to log its return value once only */ + int + sshd_selinux_enabled(void) +@@ -222,7 +217,8 @@ get_user_context(const char *sename, con + } + + static void +-ssh_selinux_get_role_level(char **role, const char **level) ++ssh_selinux_get_role_level(char **role, const char **level, ++ Authctxt *the_authctxt) + { + *role = NULL; + *level = NULL; +@@ -240,8 +236,8 @@ ssh_selinux_get_role_level(char **role, + + /* Return the default security context for the given username */ + static int +-sshd_selinux_getctxbyname(char *pwname, +- security_context_t *default_sc, security_context_t *user_sc) ++sshd_selinux_getctxbyname(char *pwname, security_context_t *default_sc, ++ security_context_t *user_sc, int inetd, Authctxt *the_authctxt) + { + char *sename, *lvl; + char *role; +@@ -249,7 +245,7 @@ sshd_selinux_getctxbyname(char *pwname, + int r = 0; + context_t con = NULL; + +- ssh_selinux_get_role_level(&role, &reqlvl); ++ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt); + + #ifdef HAVE_GETSEUSERBYNAME + if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { +@@ -271,7 +267,7 @@ sshd_selinux_getctxbyname(char *pwname, + + if (r == 0) { + /* If launched from xinetd, we must use current level */ +- if (inetd_flag && !rexeced_flag) { ++ if (inetd) { + security_context_t sshdsc=NULL; + + if (getcon_raw(&sshdsc) < 0) +@@ -332,7 +328,8 @@ sshd_selinux_getctxbyname(char *pwname, + + /* Setup environment variables for pam_selinux */ + static int +-sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) ++sshd_selinux_setup_variables(int(*set_it)(char *, const char *), int inetd, ++ Authctxt *the_authctxt) + { + const char *reqlvl; + char *role; +@@ -341,11 +338,11 @@ sshd_selinux_setup_variables(int(*set_it + + debug3("%s: setting execution context", __func__); + +- ssh_selinux_get_role_level(&role, &reqlvl); ++ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt); + + rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : ""); + +- if (inetd_flag && !rexeced_flag) { ++ if (inetd) { + use_current = "1"; + } else { + use_current = ""; +@@ -361,9 +358,10 @@ sshd_selinux_setup_variables(int(*set_it + } + + static int +-sshd_selinux_setup_pam_variables(void) ++sshd_selinux_setup_pam_variables(int inetd, ++ int(pam_setenv)(char *, const char *), Authctxt *the_authctxt) + { +- return sshd_selinux_setup_variables(do_pam_putenv); ++ return sshd_selinux_setup_variables(pam_setenv, inetd, the_authctxt); + } + + static int +@@ -373,25 +371,28 @@ do_setenv(char *name, const char *value) + } + + int +-sshd_selinux_setup_env_variables(void) ++sshd_selinux_setup_env_variables(int inetd, void *the_authctxt) + { +- return sshd_selinux_setup_variables(do_setenv); ++ Authctxt *authctxt = (Authctxt *) the_authctxt; ++ return sshd_selinux_setup_variables(do_setenv, inetd, authctxt); + } + + /* Set the execution context to the default for the specified user */ + void +-sshd_selinux_setup_exec_context(char *pwname) ++sshd_selinux_setup_exec_context(char *pwname, int inetd, ++ int(pam_setenv)(char *, const char *), void *the_authctxt, int use_pam) + { + security_context_t user_ctx = NULL; + int r = 0; + security_context_t default_ctx = NULL; ++ Authctxt *authctxt = (Authctxt *) the_authctxt; + + if (!sshd_selinux_enabled()) + return; + +- if (options.use_pam) { ++ if (use_pam) { + /* do not compute context, just setup environment for pam_selinux */ +- if (sshd_selinux_setup_pam_variables()) { ++ if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) { + switch (security_getenforce()) { + case -1: + fatal("%s: security_getenforce() failed", __func__); +@@ -409,7 +410,7 @@ sshd_selinux_setup_exec_context(char *pw + + debug3("%s: setting execution context", __func__); + +- r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); ++ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt); + if (r >= 0) { + r = setexeccon(user_ctx); + if (r < 0) { +diff -up openssh/platform.c.refactor openssh/platform.c +--- openssh/platform.c.refactor 2017-09-27 13:10:19.574830708 +0200 ++++ openssh/platform.c 2017-09-27 13:11:45.475303050 +0200 +@@ -33,6 +33,9 @@ + + extern int use_privsep; + extern ServerOptions options; ++extern int inetd_flag; ++extern int rexeced_flag; ++extern Authctxt *the_authctxt; + + void + platform_pre_listen(void) +@@ -184,7 +187,9 @@ platform_setusercontext_post_groups(stru + } + #endif /* HAVE_SETPCRED */ + #ifdef WITH_SELINUX +- sshd_selinux_setup_exec_context(pw->pw_name); ++ sshd_selinux_setup_exec_context(pw->pw_name, ++ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt, ++ options.use_pam); + #endif + } + +diff -up openssh/sshd.c.refactor openssh/sshd.c +--- openssh/sshd.c.refactor 2017-09-27 13:10:19.674831257 +0200 ++++ openssh/sshd.c 2017-09-27 13:12:01.635391909 +0200 +@@ -2135,7 +2135,9 @@ main(int ac, char **av) + } + #endif + #ifdef WITH_SELINUX +- sshd_selinux_setup_exec_context(authctxt->pw->pw_name); ++ sshd_selinux_setup_exec_context(authctxt->pw->pw_name, ++ (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt, ++ options.use_pam); + #endif + #ifdef USE_PAM + if (options.use_pam) { diff --git a/openssh.spec b/openssh.spec index 1085896..81672c2 100644 --- a/openssh.spec +++ b/openssh.spec @@ -65,10 +65,10 @@ %endif # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 -%global openssh_ver 7.5p1 -%global openssh_rel 6 +%global openssh_ver 7.6p1 +%global openssh_rel 1 %global pam_ssh_agent_ver 0.10.3 -%global pam_ssh_agent_rel 2 +%global pam_ssh_agent_rel 3 Summary: An open source implementation of SSH protocol version 2 Name: openssh @@ -107,7 +107,7 @@ Patch104: openssh-7.3p1-openssl-1.1.0.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1402 # https://bugzilla.redhat.com/show_bug.cgi?id=1171248 # record pfs= field in CRYPTO_SESSION audit event -Patch200: openssh-7.2p1-audit.patch +Patch200: openssh-7.6p1-audit.patch # Audit race condition in forked child (#1310684) Patch201: openssh-7.1p2-audit-race-condition.patch @@ -223,15 +223,14 @@ Patch932: openssh-7.0p1-gssKexAlgorithms.patch Patch933: openssh-7.0p1-show-more-fingerprints.patch # make s390 use /dev/ crypto devices -- ignore closefrom Patch939: openssh-7.2p2-s390-closefrom.patch -# expose more information to PAM -# https://github.com/openssh/openssh-portable/pull/47 -Patch940: openssh-7.2p2-expose-pam.patch # Move MAX_DISPLAYS to a configuration option (#1341302) Patch944: openssh-7.3p1-x11-max-displays.patch # Help systemd to track the running service Patch948: openssh-7.4p1-systemd.patch -# Fix typo in sandbox code; missing header for s390 -Patch949: openssh-7.5p1-sandbox.patch +# Pass inetd flags for SELinux down to openbsd compat level +Patch949: openssh-7.6p1-cleanup-selinux.patch +# Sandbox adjustments for s390 and audit +Patch950: openssh-7.5p1-sandbox.patch License: BSD @@ -451,11 +450,11 @@ popd %patch932 -p1 -b .gsskexalg %patch933 -p1 -b .fingerprint %patch939 -p1 -b .s390-dev -%patch940 -p1 -b .expose-pam %patch944 -p1 -b .x11max %patch948 -p1 -b .systemd -%patch949 -p1 -b .sandbox %patch807 -p1 -b .gsskex-ec +%patch949 -p1 -b .refactor +%patch950 -p1 -b .sandbox %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race diff --git a/pam_ssh_agent_auth-0.9.3-agent_structure.patch b/pam_ssh_agent_auth-0.9.3-agent_structure.patch index f4532b5..99f99f7 100644 --- a/pam_ssh_agent_auth-0.9.3-agent_structure.patch +++ b/pam_ssh_agent_auth-0.9.3-agent_structure.patch @@ -1,6 +1,6 @@ -diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/identity.h.psaa-agent openssh-7.1p2/pam_ssh_agent_auth-0.10.2/identity.h ---- openssh-7.1p2/pam_ssh_agent_auth-0.10.2/identity.h.psaa-agent 2014-03-31 19:35:16.000000000 +0200 -+++ openssh-7.1p2/pam_ssh_agent_auth-0.10.2/identity.h 2016-01-22 15:47:15.999919059 +0100 +diff -up openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/identity.h +--- openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-agent 2016-11-13 04:24:32.000000000 +0100 ++++ openssh/pam_ssh_agent_auth-0.10.3/identity.h 2017-09-27 14:25:49.421739027 +0200 @@ -38,6 +38,12 @@ typedef struct identity Identity; typedef struct idlist Idlist; @@ -14,9 +14,9 @@ diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/identity.h.psaa-agent openssh-7 struct identity { TAILQ_ENTRY(identity) next; AuthenticationConnection *ac; /* set if agent supports key */ -diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/iterate_ssh_agent_keys.c.psaa-agent openssh-7.1p2/pam_ssh_agent_auth-0.10.2/iterate_ssh_agent_keys.c ---- openssh-7.1p2/pam_ssh_agent_auth-0.10.2/iterate_ssh_agent_keys.c.psaa-agent 2016-01-22 15:47:15.998919060 +0100 -+++ openssh-7.1p2/pam_ssh_agent_auth-0.10.2/iterate_ssh_agent_keys.c 2016-01-22 15:53:38.427768239 +0100 +diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c +--- openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-agent 2017-09-27 14:25:49.420739021 +0200 ++++ openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c 2017-09-27 14:25:49.421739027 +0200 @@ -39,6 +39,7 @@ #include "buffer.h" #include "key.h" @@ -25,7 +25,7 @@ diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/iterate_ssh_agent_keys.c.psaa-a #include #include #include "ssh2.h" -@@ -285,36 +286,44 @@ pamsshagentauth_find_authorized_keys(con +@@ -291,36 +292,43 @@ pamsshagentauth_find_authorized_keys(con { Buffer session_id2 = { 0 }; Identity *id; @@ -44,8 +44,7 @@ diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/iterate_ssh_agent_keys.c.psaa-a if ((ac = ssh_get_authentication_connection_for_uid(uid))) { verbose("Contacted ssh-agent of user %s (%u)", ruser, uid); - for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2)) -+ if ((r = ssh_fetch_identitylist(ac->fd, 2, -+ &idlist)) != 0) { ++ if ((r = ssh_fetch_identitylist(ac->fd, &idlist)) != 0) { + if (r != SSH_ERR_AGENT_NO_IDENTITIES) + fprintf(stderr, "error fetching identities for " + "protocol %d: %s\n", 2, ssh_err(r)); @@ -79,10 +78,60 @@ diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/iterate_ssh_agent_keys.c.psaa-a } else { verbose("No ssh-agent could be contacted"); -diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c.psaa-agent openssh-7.1p2/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c ---- openssh-7.1p2/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c.psaa-agent 2016-01-22 15:47:15.995919061 +0100 -+++ openssh-7.1p2/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c 2016-01-22 16:06:20.611464261 +0100 -@@ -55,10 +55,11 @@ extern uint8_t session_id_len; +diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c +--- openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-agent 2017-09-27 14:26:04.277820716 +0200 ++++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c 2017-09-27 14:26:34.426986497 +0200 +@@ -70,7 +70,7 @@ pamsshagentauth_check_authkeys_file(FILE + char *fp; + + found_key = 0; +- found = key_new(key->type); ++ found = sshkey_new(key->type); + + while(read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { + char *cp = NULL; /* *key_options = NULL; */ +@@ -80,7 +80,7 @@ pamsshagentauth_check_authkeys_file(FILE + if(!*cp || *cp == '\n' || *cp == '#') + continue; + +- if(key_read(found, &cp) != 1) { ++ if(sshkey_read(found, &cp) != 0) { + /* no key? check if there are options for this key */ + int quoted = 0; + +@@ -94,24 +94,24 @@ pamsshagentauth_check_authkeys_file(FILE + } + /* Skip remaining whitespace. */ + for(; *cp == ' ' || *cp == '\t'; cp++); +- if(key_read(found, &cp) != 1) { ++ if(sshkey_read(found, &cp) != 0) { + verbose("user_key_allowed: advance: '%s'", cp); + /* still no key? advance to next line */ + continue; + } + } +- if(key_equal(found, key)) { ++ if(sshkey_equal(found, key)) { + found_key = 1; + logit("matching key found: file/command %s, line %lu", file, + linenum); + fp = sshkey_fingerprint(found, SSH_DIGEST_MD5, SSH_FP_HEX); + logit("Found matching %s key: %s", +- key_type(found), fp); ++ sshkey_type(found), fp); + free(fp); + break; + } + } +- key_free(found); ++ sshkey_free(found); + if(!found_key) + verbose("key not found"); + return found_key; +diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c +--- openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-agent 2017-09-27 14:25:49.420739021 +0200 ++++ openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c 2017-09-27 14:25:49.422739032 +0200 +@@ -57,10 +57,11 @@ extern uint8_t session_id_len; int userauth_pubkey_from_id(const char *ruser, Identity * id, Buffer * session_id2) { @@ -96,25 +145,12 @@ diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c.psaa- int authenticated = 0; pkalg = (char *) key_ssh_name(id->key); -@@ -82,7 +83,7 @@ userauth_pubkey_from_id(const char *ruse +@@ -84,7 +85,7 @@ userauth_pubkey_from_id(const char *ruse buffer_put_cstring(&b, pkalg); buffer_put_string(&b, pkblob, blen); - if(ssh_agent_sign(id->ac, id->key, &sig, &slen, buffer_ptr(&b), buffer_len(&b)) != 0) -+ if(ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, buffer_ptr(&b), buffer_len(&b), 0) != 0) - goto user_auth_clean_exit; - - /* test for correct signature */ -diff --git a/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c b/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c ---- a/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c -+++ b/pam_ssh_agent_auth-0.10.2/userauth_pubkey_from_id.c -@@ -85,7 +85,7 @@ userauth_pubkey_from_id(const char *ruser, Identity * id, Buffer * session_id2) - buffer_put_cstring(&b, pkalg); - buffer_put_string(&b, pkblob, blen); - -- if(ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, buffer_ptr(&b), buffer_len(&b), 0) != 0) + if(ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, buffer_ptr(&b), buffer_len(&b), NULL, 0) != 0) goto user_auth_clean_exit; /* test for correct signature */ -