From: Stefan Schantl Date: Sat, 4 Apr 2015 20:58:32 +0000 (+0200) Subject: openssh: Update to 6.8p1. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17d728c8b5030bc68123daf2a95ccd2cf691ab2c;p=ipfire-3.x.git openssh: Update to 6.8p1. Fixes #10534. --- diff --git a/openssh/openssh.nm b/openssh/openssh.nm index 10d43f474..59491fdeb 100644 --- a/openssh/openssh.nm +++ b/openssh/openssh.nm @@ -4,7 +4,7 @@ ############################################################################### name = openssh -version = 6.1p1 +version = 6.8p1 release = 1 groups = Application/Internet @@ -37,38 +37,6 @@ build zlib-devel end - # Apply patches in a special order - patches - openssh-6.1p1-coverity.patch - openssh-5.8p1-fingerprint.patch - openssh-5.8p1-getaddrinfo.patch - openssh-5.8p1-packet.patch - openssh-6.1p1-authenticationmethods.patch - openssh-6.1p1-role-mls.patch - openssh-5.9p1-sftp-chroot.patch - openssh-6.1p1-akc.patch - openssh-5.2p1-allow-ip-opts.patch - openssh-5.9p1-randclean.patch - openssh-5.8p1-keyperm.patch - openssh-5.8p2-remove-stale-control-socket.patch - openssh-5.9p1-ipv6man.patch - openssh-5.8p2-sigpipe.patch - openssh-6.1p1-askpass-ld.patch - openssh-5.5p1-x11.patch - openssh-5.6p1-exit-deadlock.patch - openssh-5.1p1-askpass-progress.patch - openssh-4.3p2-askpass-grab-info.patch - openssh-5.9p1-edns.patch - openssh-5.1p1-scp-manpage.patch - openssh-5.8p1-localdomain.patch - openssh-5.9p1-ipfire.patch - openssh-6.0p1-entropy.patch - openssh-6.1p1-vendor.patch - openssh-5.8p2-force_krb.patch - openssh-6.1p1-kuserok.patch - openssh-6.1p1-required-authentications.patch - end - configure_options += \ --sysconfdir=%{sysconfdir}/ssh \ --datadir=%{datadir}/sshd \ @@ -94,6 +62,13 @@ build # Disable GSS API authentication because KRB5 is required for that. sed -e "s/^.*GSSAPIAuthentication/#&/" -i %{BUILDROOT}/etc/ssh/ssh_config + # Enable PAM usage, disable ChallengeResponseAuthentication and disable Motd. + sed \ + -e '/^#ChallengeResponseAuthentication yes$/c ChallengeResponseAuthentication no' \ + -e '/^#PrintMotd yes$/c PrintMotd no' \ + -e '/^#UsePAM no$/c UsePAM yes' \ + -i %{BUILDROOT}/etc/ssh/sshd_config + # Install scriptfile for key generation mkdir -pv %{BUILDROOT}%{sbindir} install -m 754 %{DIR_SOURCE}/sshd-keygen %{BUILDROOT}%{sbindir} diff --git a/openssh/patches/openssh-4.3p2-askpass-grab-info.patch b/openssh/patches/openssh-4.3p2-askpass-grab-info.patch deleted file mode 100644 index e9dc835ea..000000000 --- a/openssh/patches/openssh-4.3p2-askpass-grab-info.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- openssh-4.3p2/contrib/gnome-ssh-askpass2.c.grab-info 2006-07-17 15:10:11.000000000 +0200 -+++ openssh-4.3p2/contrib/gnome-ssh-askpass2.c 2006-07-17 15:25:04.000000000 +0200 -@@ -65,9 +65,12 @@ - err = gtk_message_dialog_new(NULL, 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, -- "Could not grab %s. " -- "A malicious client may be eavesdropping " -- "on your session.", what); -+ "SSH password dialog could not grab the %s input.\n" -+ "This might be caused by application such as screensaver, " -+ "however it could also mean that someone may be eavesdropping " -+ "on your session.\n" -+ "Either close the application which grabs the %s or " -+ "log out and log in again to prevent this from happening.", what, what); - gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); - gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label), - TRUE); diff --git a/openssh/patches/openssh-5.1p1-askpass-progress.patch b/openssh/patches/openssh-5.1p1-askpass-progress.patch deleted file mode 100644 index ec93b87fd..000000000 --- a/openssh/patches/openssh-5.1p1-askpass-progress.patch +++ /dev/null @@ -1,79 +0,0 @@ -diff -up openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress openssh-5.1p1/contrib/gnome-ssh-askpass2.c ---- openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress 2008-07-23 19:05:26.000000000 +0200 -+++ openssh-5.1p1/contrib/gnome-ssh-askpass2.c 2008-07-23 19:05:26.000000000 +0200 -@@ -53,6 +53,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -83,13 +84,24 @@ ok_dialog(GtkWidget *entry, gpointer dia - gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); - } - -+static void -+move_progress(GtkWidget *entry, gpointer progress) -+{ -+ gdouble step; -+ g_return_if_fail(GTK_IS_PROGRESS_BAR(progress)); -+ -+ step = g_random_double_range(0.03, 0.1); -+ gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress), step); -+ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress)); -+} -+ - static int - passphrase_dialog(char *message) - { - const char *failed; - char *passphrase, *local; - int result, grab_tries, grab_server, grab_pointer; -- GtkWidget *dialog, *entry; -+ GtkWidget *dialog, *entry, *progress, *hbox; - GdkGrabStatus status; - - grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); -@@ -102,13 +114,31 @@ passphrase_dialog(char *message) - "%s", - message); - -+ hbox = gtk_hbox_new(FALSE, 0); -+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, -+ FALSE, 0); -+ gtk_widget_show(hbox); -+ - entry = gtk_entry_new(); -- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, -+ gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, - FALSE, 0); -+ gtk_entry_set_width_chars(GTK_ENTRY(entry), 2); - gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); - gtk_widget_grab_focus(entry); - gtk_widget_show(entry); - -+ hbox = gtk_hbox_new(FALSE, 0); -+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, -+ FALSE, 8); -+ gtk_widget_show(hbox); -+ -+ progress = gtk_progress_bar_new(); -+ -+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally"); -+ gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE, -+ TRUE, 5); -+ gtk_widget_show(progress); -+ - gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); - gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); - gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); -@@ -119,6 +149,8 @@ passphrase_dialog(char *message) - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(ok_dialog), dialog); -+ g_signal_connect(G_OBJECT(entry), "changed", -+ G_CALLBACK(move_progress), progress); - - gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); - diff --git a/openssh/patches/openssh-5.1p1-scp-manpage.patch b/openssh/patches/openssh-5.1p1-scp-manpage.patch deleted file mode 100644 index e314a05a2..000000000 --- a/openssh/patches/openssh-5.1p1-scp-manpage.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -up openssh-5.1p1/scp.1.manpage openssh-5.1p1/scp.1 ---- openssh-5.1p1/scp.1.manpage 2008-07-12 09:12:49.000000000 +0200 -+++ openssh-5.1p1/scp.1 2008-07-23 19:18:15.000000000 +0200 -@@ -66,6 +66,14 @@ treating file names containing - as host specifiers. - Copies between two remote hosts are also permitted. - .Pp -+When copying a source file to a target file which already exists, -+.Nm -+will replace the contents of the target file (keeping the inode). -+.Pp -+If the target file does not yet exist, an empty file with the target -+file name is created, then filled with the source file contents. -+No attempt is made at "near-atomic" transfer using temporary files. -+.Pp - The options are as follows: - .Bl -tag -width Ds - .It Fl 1 diff --git a/openssh/patches/openssh-5.2p1-allow-ip-opts.patch b/openssh/patches/openssh-5.2p1-allow-ip-opts.patch deleted file mode 100644 index 96aaab1d0..000000000 --- a/openssh/patches/openssh-5.2p1-allow-ip-opts.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -up openssh-5.2p1/canohost.c.ip-opts openssh-5.2p1/canohost.c ---- openssh-5.2p1/canohost.c.ip-opts 2009-02-14 06:28:21.000000000 +0100 -+++ openssh-5.2p1/canohost.c 2009-09-01 15:31:29.000000000 +0200 -@@ -169,12 +169,27 @@ check_ip_options(int sock, char *ipaddr) - option_size = sizeof(options); - if (getsockopt(sock, ipproto, IP_OPTIONS, options, - &option_size) >= 0 && option_size != 0) { -- text[0] = '\0'; -- for (i = 0; i < option_size; i++) -- snprintf(text + i*3, sizeof(text) - i*3, -- " %2.2x", options[i]); -- fatal("Connection from %.100s with IP options:%.800s", -- ipaddr, text); -+ i = 0; -+ do { -+ switch (options[i]) { -+ case 0: -+ case 1: -+ ++i; -+ break; -+ case 131: -+ case 137: -+ /* Fail, fatally, if we detect either loose or strict -+ * source routing options. */ -+ text[0] = '\0'; -+ for (i = 0; i < option_size; i++) -+ snprintf(text + i*3, sizeof(text) - i*3, -+ " %2.2x", options[i]); -+ fatal("Connection from %.100s with IP options:%.800s", -+ ipaddr, text); -+ default: -+ i += options[i + 1]; -+ } -+ } while (i < option_size); - } - #endif /* IP_OPTIONS */ - } diff --git a/openssh/patches/openssh-5.5p1-x11.patch b/openssh/patches/openssh-5.5p1-x11.patch deleted file mode 100644 index cac5d5e1d..000000000 --- a/openssh/patches/openssh-5.5p1-x11.patch +++ /dev/null @@ -1,54 +0,0 @@ -diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c ---- openssh-5.3p1/channels.c.bz595935 2010-08-12 14:19:28.000000000 +0200 -+++ openssh-5.3p1/channels.c 2010-08-12 14:33:51.000000000 +0200 -@@ -3185,7 +3185,7 @@ x11_create_display_inet(int x11_display_ - } - - static int --connect_local_xsocket_path(const char *pathname) -+connect_local_xsocket_path(const char *pathname, int len) - { - int sock; - struct sockaddr_un addr; -@@ -3195,11 +3195,14 @@ connect_local_xsocket_path(const char *p - error("socket: %.100s", strerror(errno)); - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; -- strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); -- if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) -+ if (len <= 0) -+ return -1; -+ if (len > sizeof addr.sun_path) -+ len = sizeof addr.sun_path; -+ memcpy(addr.sun_path, pathname, len); -+ if (connect(sock, (struct sockaddr *)&addr, sizeof addr - (sizeof addr.sun_path - len) ) == 0) - return sock; - close(sock); -- error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); - return -1; - } - -@@ -3207,8 +3210,21 @@ static int - connect_local_xsocket(u_int dnr) - { - char buf[1024]; -- snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr); -- return connect_local_xsocket_path(buf); -+ int len; -+#ifdef linux -+ int ret; -+#endif -+ len = snprintf(buf + 1, sizeof (buf) - 1, _PATH_UNIX_X, dnr); -+#ifdef linux -+ /* try abstract socket first */ -+ buf[0] = '\0'; -+ if ((ret = connect_local_xsocket_path(buf, len + 1)) >= 0) -+ return ret; -+#endif -+ if ((ret = connect_local_xsocket_path(buf + 1, len)) >= 0) -+ return ret; -+ error("connect %.100s: %.100s", buf + 1, strerror(errno)); -+ return -1; - } - - int diff --git a/openssh/patches/openssh-5.6p1-exit-deadlock.patch b/openssh/patches/openssh-5.6p1-exit-deadlock.patch deleted file mode 100644 index 278dfa153..000000000 --- a/openssh/patches/openssh-5.6p1-exit-deadlock.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up openssh-5.6p1/channels.c.exit-deadlock openssh-5.6p1/channels.c ---- openssh-5.6p1/channels.c.exit-deadlock 2010-08-05 15:09:48.000000000 +0200 -+++ openssh-5.6p1/channels.c 2010-08-23 12:41:43.000000000 +0200 -@@ -1647,6 +1647,10 @@ channel_handle_wfd(Channel *c, fd_set *r - u_int dlen, olen = 0; - int len; - -+ if(c->wfd != -1 && buffer_len(&c->output) > 0 && c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { -+ debug("channel %d: forcing write", c->self); -+ FD_SET(c->wfd, writeset); -+ } - /* Send buffered output data to the socket. */ - if (c->wfd != -1 && - FD_ISSET(c->wfd, writeset) && diff --git a/openssh/patches/openssh-5.6p1-redhat.patch b/openssh/patches/openssh-5.6p1-redhat.patch deleted file mode 100644 index d1df8c122..000000000 --- a/openssh/patches/openssh-5.6p1-redhat.patch +++ /dev/null @@ -1,101 +0,0 @@ -diff -up openssh-5.6p1/ssh_config.redhat openssh-5.6p1/ssh_config ---- openssh-5.6p1/ssh_config.redhat 2010-01-12 09:40:27.000000000 +0100 -+++ openssh-5.6p1/ssh_config 2010-09-03 15:21:17.000000000 +0200 -@@ -45,3 +45,16 @@ - # PermitLocalCommand no - # VisualHostKey no - # ProxyCommand ssh -q -W %h:%p gateway.example.com -+Host * -+ GSSAPIAuthentication yes -+# If this option is set to yes then remote X11 clients will have full access -+# to the original X11 display. As virtually no X11 client supports the untrusted -+# mode correctly we set this to yes. -+ ForwardX11Trusted yes -+# Look up the host key SSHFP records -+ VerifyHostKeyDNS ask -+# Send locale-related environment variables -+ SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES -+ SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT -+ SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE -+ SendEnv XMODIFIERS -diff -up openssh-5.6p1/sshd_config.0.redhat openssh-5.6p1/sshd_config.0 ---- openssh-5.6p1/sshd_config.0.redhat 2010-08-23 05:24:16.000000000 +0200 -+++ openssh-5.6p1/sshd_config.0 2010-09-03 15:23:20.000000000 +0200 -@@ -537,9 +537,9 @@ DESCRIPTION - - SyslogFacility - Gives the facility code that is used when logging messages from -- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, -- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The -- default is AUTH. -+ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV, -+ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. -+ The default is AUTH. - - TCPKeepAlive - Specifies whether the system should send TCP keepalive messages -diff -up openssh-5.6p1/sshd_config.5.redhat openssh-5.6p1/sshd_config.5 ---- openssh-5.6p1/sshd_config.5.redhat 2010-07-02 05:37:17.000000000 +0200 -+++ openssh-5.6p1/sshd_config.5 2010-09-03 15:21:17.000000000 +0200 -@@ -919,7 +919,7 @@ Note that this option applies to protoco - .It Cm SyslogFacility - Gives the facility code that is used when logging messages from - .Xr sshd 8 . --The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, -+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, - LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. - The default is AUTH. - .It Cm TCPKeepAlive -diff -up openssh-5.6p1/sshd_config.redhat openssh-5.6p1/sshd_config ---- openssh-5.6p1/sshd_config.redhat 2009-10-11 12:51:09.000000000 +0200 -+++ openssh-5.6p1/sshd_config 2010-09-03 15:21:17.000000000 +0200 -@@ -31,6 +31,7 @@ - # Logging - # obsoletes QuietMode and FascistLogging - #SyslogFacility AUTH -+SyslogFacility AUTHPRIV - #LogLevel INFO - - # Authentication: -@@ -58,9 +59,11 @@ - # To disable tunneled clear text passwords, change to no here! - #PasswordAuthentication yes - #PermitEmptyPasswords no -+PasswordAuthentication yes - - # Change to no to disable s/key passwords - #ChallengeResponseAuthentication yes -+ChallengeResponseAuthentication no - - # Kerberos options - #KerberosAuthentication no -@@ -70,7 +73,9 @@ - - # GSSAPI options - #GSSAPIAuthentication no -+GSSAPIAuthentication yes - #GSSAPICleanupCredentials yes -+GSSAPICleanupCredentials yes - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -@@ -82,11 +87,19 @@ - # PAM authentication, then enable this but set PasswordAuthentication - # and ChallengeResponseAuthentication to 'no'. - #UsePAM no -+UsePAM yes -+ -+# Accept locale-related environment variables -+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES -+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT -+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE -+AcceptEnv XMODIFIERS - - #AllowAgentForwarding yes - #AllowTcpForwarding yes - #GatewayPorts no - #X11Forwarding no -+X11Forwarding yes - #X11DisplayOffset 10 - #X11UseLocalhost yes - #PrintMotd yes diff --git a/openssh/patches/openssh-5.8p1-fingerprint.patch b/openssh/patches/openssh-5.8p1-fingerprint.patch deleted file mode 100644 index a0438ff6d..000000000 --- a/openssh/patches/openssh-5.8p1-fingerprint.patch +++ /dev/null @@ -1,421 +0,0 @@ -diff -up openssh-5.8p1/auth2-hostbased.c.fingerprint openssh-5.8p1/auth2-hostbased.c ---- openssh-5.8p1/auth2-hostbased.c.fingerprint 2010-08-05 05:04:50.000000000 +0200 -+++ openssh-5.8p1/auth2-hostbased.c 2011-02-25 09:17:18.000000000 +0100 -@@ -196,16 +196,18 @@ hostbased_key_allowed(struct passwd *pw, - - if (host_status == HOST_OK) { - if (key_is_cert(key)) { -- fp = key_fingerprint(key->cert->signature_key, -- SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_selected_fingerprint(key->cert->signature_key, -+ SSH_FP_HEX); - verbose("Accepted certificate ID \"%s\" signed by " -- "%s CA %s from %s@%s", key->cert->key_id, -- key_type(key->cert->signature_key), fp, -+ "%s CA %s%s from %s@%s", key->cert->key_id, -+ key_type(key->cert->signature_key), -+ key_fingerprint_prefix(), fp, - cuser, lookup); - } else { -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -- verbose("Accepted %s public key %s from %s@%s", -- key_type(key), fp, cuser, lookup); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ verbose("Accepted %s public key %s%s from %s@%s", -+ key_type(key), key_fingerprint_prefix(), -+ fp, cuser, lookup); - } - xfree(fp); - } -diff -up openssh-5.8p1/auth2-pubkey.c.fingerprint openssh-5.8p1/auth2-pubkey.c ---- openssh-5.8p1/auth2-pubkey.c.fingerprint 2010-12-01 01:50:14.000000000 +0100 -+++ openssh-5.8p1/auth2-pubkey.c 2011-02-25 09:17:18.000000000 +0100 -@@ -319,10 +319,10 @@ user_key_allowed2(struct passwd *pw, Key - continue; - if (!key_is_cert_authority) - continue; -- fp = key_fingerprint(found, SSH_FP_MD5, -- SSH_FP_HEX); -- debug("matching CA found: file %s, line %lu, %s %s", -- file, linenum, key_type(found), fp); -+ fp = key_selected_fingerprint(found, SSH_FP_HEX); -+ debug("matching CA found: file %s, line %lu, %s %s%s", -+ file, linenum, key_type(found), -+ key_fingerprint_prefix(), fp); - /* - * If the user has specified a list of principals as - * a key option, then prefer that list to matching -@@ -362,9 +362,9 @@ user_key_allowed2(struct passwd *pw, Key - found_key = 1; - debug("matching key found: file %s, line %lu", - file, linenum); -- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); -- verbose("Found matching %s key: %s", -- key_type(found), fp); -+ fp = key_selected_fingerprint(found, SSH_FP_HEX); -+ verbose("Found matching %s key: %s%s", -+ key_type(found), key_fingerprint_prefix(), fp); - xfree(fp); - break; - } -@@ -388,13 +388,13 @@ user_cert_trusted_ca(struct passwd *pw, - if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) - return 0; - -- ca_fp = key_fingerprint(key->cert->signature_key, -- SSH_FP_MD5, SSH_FP_HEX); -+ ca_fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX); - - if (key_in_file(key->cert->signature_key, - options.trusted_user_ca_keys, 1) != 1) { -- debug2("%s: CA %s %s is not listed in %s", __func__, -- key_type(key->cert->signature_key), ca_fp, -+ debug2("%s: CA %s%s %s is not listed in %s", __func__, -+ key_type(key->cert->signature_key), -+ key_fingerprint_prefix(), ca_fp, - options.trusted_user_ca_keys); - goto out; - } -diff -up openssh-5.8p1/auth.c.fingerprint openssh-5.8p1/auth.c ---- openssh-5.8p1/auth.c.fingerprint 2010-12-01 02:21:51.000000000 +0100 -+++ openssh-5.8p1/auth.c 2011-02-25 09:17:18.000000000 +0100 -@@ -639,9 +639,10 @@ auth_key_is_revoked(Key *key) - return 1; - case 1: - /* Key revoked */ -- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -+ key_fp = key_selected_fingerprint(key, SSH_FP_HEX); - error("WARNING: authentication attempt with a revoked " -- "%s key %s ", key_type(key), key_fp); -+ "%s key %s%s ", key_type(key), -+ key_fingerprint_prefix(), key_fp); - xfree(key_fp); - return 1; - } -diff -up openssh-5.8p1/auth-rsa.c.fingerprint openssh-5.8p1/auth-rsa.c ---- openssh-5.8p1/auth-rsa.c.fingerprint 2010-12-04 23:01:47.000000000 +0100 -+++ openssh-5.8p1/auth-rsa.c 2011-02-25 09:17:18.000000000 +0100 -@@ -318,9 +318,9 @@ auth_rsa(Authctxt *authctxt, BIGNUM *cli - * options; this will be reset if the options cause the - * authentication to be rejected. - */ -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -- verbose("Found matching %s key: %s", -- key_type(key), fp); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ verbose("Found matching %s key: %s%s", -+ key_type(key), key_fingerprint_prefix(), fp); - xfree(fp); - key_free(key); - -diff -up openssh-5.8p1/key.c.fingerprint openssh-5.8p1/key.c ---- openssh-5.8p1/key.c.fingerprint 2011-02-04 01:48:34.000000000 +0100 -+++ openssh-5.8p1/key.c 2011-02-25 09:18:16.000000000 +0100 -@@ -594,6 +594,34 @@ key_fingerprint(Key *k, enum fp_type dgs - return retval; - } - -+enum fp_type -+key_fingerprint_selection(void) -+{ -+ static enum fp_type rv; -+ static char rv_defined = 0; -+ char *env; -+ -+ if (!rv_defined) { -+ env = getenv("SSH_FINGERPRINT_TYPE"); -+ rv = (env && !strcmp (env, "sha")) ? -+ SSH_FP_SHA1 : SSH_FP_MD5; -+ rv_defined = 1; -+ } -+ return rv; -+} -+ -+char * -+key_selected_fingerprint(Key *k, enum fp_rep dgst_rep) -+{ -+ return key_fingerprint(k, key_fingerprint_selection(), dgst_rep); -+} -+ -+char * -+key_fingerprint_prefix(void) -+{ -+ return key_fingerprint_selection() == SSH_FP_SHA1 ? "sha1:" : ""; -+} -+ - /* - * Reads a multiple-precision integer in decimal from the buffer, and advances - * the pointer. The integer must already be initialized. This function is -diff -up openssh-5.8p1/key.h.fingerprint openssh-5.8p1/key.h ---- openssh-5.8p1/key.h.fingerprint 2010-11-05 00:19:49.000000000 +0100 -+++ openssh-5.8p1/key.h 2011-02-25 09:17:18.000000000 +0100 -@@ -96,6 +96,9 @@ int key_equal_public(const Key *, cons - int key_equal(const Key *, const Key *); - char *key_fingerprint(Key *, enum fp_type, enum fp_rep); - u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *); -+enum fp_type key_fingerprint_selection(void); -+char *key_selected_fingerprint(Key *, enum fp_rep); -+char *key_fingerprint_prefix(void); - const char *key_type(const Key *); - const char *key_cert_type(const Key *); - int key_write(const Key *, FILE *); -diff -up openssh-5.8p1/ssh-add.c.fingerprint openssh-5.8p1/ssh-add.c ---- openssh-5.8p1/ssh-add.c.fingerprint 2010-11-11 04:17:02.000000000 +0100 -+++ openssh-5.8p1/ssh-add.c 2011-02-25 09:17:18.000000000 +0100 -@@ -280,10 +280,10 @@ list_identities(AuthenticationConnection - key = ssh_get_next_identity(ac, &comment, version)) { - had_identities = 1; - if (do_fp) { -- fp = key_fingerprint(key, SSH_FP_MD5, -- SSH_FP_HEX); -- printf("%d %s %s (%s)\n", -- key_size(key), fp, comment, key_type(key)); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ printf("%d %s%s %s (%s)\n", -+ key_size(key), key_fingerprint_prefix(), -+ fp, comment, key_type(key)); - xfree(fp); - } else { - if (!key_write(key, stdout)) -diff -up openssh-5.8p1/ssh-agent.c.fingerprint openssh-5.8p1/ssh-agent.c ---- openssh-5.8p1/ssh-agent.c.fingerprint 2010-12-01 01:50:35.000000000 +0100 -+++ openssh-5.8p1/ssh-agent.c 2011-02-25 09:17:18.000000000 +0100 -@@ -199,9 +199,9 @@ confirm_key(Identity *id) - char *p; - int ret = -1; - -- p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); -- if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", -- id->comment, p)) -+ p = key_selected_fingerprint(id->key, SSH_FP_HEX); -+ if (ask_permission("Allow use of key %s?\nKey fingerprint %s%s.", -+ id->comment, key_fingerprint_prefix(), p)) - ret = 0; - xfree(p); - -diff -up openssh-5.8p1/sshconnect2.c.fingerprint openssh-5.8p1/sshconnect2.c ---- openssh-5.8p1/sshconnect2.c.fingerprint 2010-12-01 02:21:51.000000000 +0100 -+++ openssh-5.8p1/sshconnect2.c 2011-02-25 09:17:18.000000000 +0100 -@@ -590,8 +590,9 @@ input_userauth_pk_ok(int type, u_int32_t - key->type, pktype); - goto done; - } -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -- debug2("input_userauth_pk_ok: fp %s", fp); -+ fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ debug2("input_userauth_pk_ok: fp %s%s", -+ key_fingerprint_prefix(), fp); - xfree(fp); - - /* -@@ -1203,8 +1204,9 @@ sign_and_send_pubkey(Authctxt *authctxt, - int have_sig = 1; - char *fp; - -- fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); -- debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); -+ fp = key_selected_fingerprint(id->key, SSH_FP_HEX); -+ debug3("sign_and_send_pubkey: %s %s%s", key_type(id->key), -+ key_fingerprint_prefix(), fp); - xfree(fp); - - if (key_to_blob(id->key, &blob, &bloblen) == 0) { -diff -up openssh-5.8p1/sshconnect.c.fingerprint openssh-5.8p1/sshconnect.c ---- openssh-5.8p1/sshconnect.c.fingerprint 2011-01-16 13:17:59.000000000 +0100 -+++ openssh-5.8p1/sshconnect.c 2011-02-25 09:17:18.000000000 +0100 -@@ -798,10 +798,10 @@ check_host_key(char *hostname, struct so - "key for IP address '%.128s' to the list " - "of known hosts.", type, ip); - } else if (options.visual_host_key) { -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -- ra = key_fingerprint(host_key, SSH_FP_MD5, -- SSH_FP_RANDOMART); -- logit("Host key fingerprint is %s\n%s\n", fp, ra); -+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); -+ ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART); -+ logit("Host key fingerprint is %s%s\n%s\n", -+ key_fingerprint_prefix(), fp, ra); - xfree(ra); - xfree(fp); - } -@@ -838,9 +838,8 @@ check_host_key(char *hostname, struct so - else - snprintf(msg1, sizeof(msg1), "."); - /* The default */ -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -- ra = key_fingerprint(host_key, SSH_FP_MD5, -- SSH_FP_RANDOMART); -+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); -+ ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART); - msg2[0] = '\0'; - if (options.verify_host_key_dns) { - if (matching_host_key_dns) -@@ -855,10 +854,11 @@ check_host_key(char *hostname, struct so - snprintf(msg, sizeof(msg), - "The authenticity of host '%.200s (%s)' can't be " - "established%s\n" -- "%s key fingerprint is %s.%s%s\n%s" -+ "%s key fingerprint is %s%s.%s%s\n%s" - "Are you sure you want to continue connecting " - "(yes/no)? ", -- host, ip, msg1, type, fp, -+ host, ip, msg1, type, -+ key_fingerprint_prefix(), fp, - options.visual_host_key ? "\n" : "", - options.visual_host_key ? ra : "", - msg2); -@@ -1104,8 +1104,9 @@ verify_host_key(char *host, struct socka - int flags = 0; - char *fp; - -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -- debug("Server host key: %s %s", key_type(host_key), fp); -+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); -+ debug("Server host key: %s %s%s", key_type(host_key), -+ key_fingerprint_prefix(), fp); - xfree(fp); - - /* XXX certs are not yet supported for DNS */ -@@ -1214,14 +1215,15 @@ show_other_keys(struct hostkeys *hostkey - continue; - if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) - continue; -- fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX); -- ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART); -+ fp = key_selected_fingerprint(found->key, SSH_FP_HEX); -+ ra = key_selected_fingerprint(found->key, SSH_FP_RANDOMART); - logit("WARNING: %s key found for host %s\n" - "in %s:%lu\n" -- "%s key fingerprint %s.", -+ "%s key fingerprint %s%s.", - key_type(found->key), - found->host, found->file, found->line, -- key_type(found->key), fp); -+ key_type(found->key), -+ key_fingerprint_prefix(), fp); - if (options.visual_host_key) - logit("%s", ra); - xfree(ra); -@@ -1236,7 +1238,7 @@ warn_changed_key(Key *host_key) - { - char *fp; - -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); - - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); -@@ -1244,8 +1246,8 @@ warn_changed_key(Key *host_key) - error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); - error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); - error("It is also possible that a host key has just been changed."); -- error("The fingerprint for the %s key sent by the remote host is\n%s.", -- key_type(host_key), fp); -+ error("The fingerprint for the %s key sent by the remote host is\n%s%s.", -+ key_type(host_key),key_fingerprint_prefix(), fp); - error("Please contact your system administrator."); - - xfree(fp); -diff -up openssh-5.8p1/ssh-keygen.c.fingerprint openssh-5.8p1/ssh-keygen.c ---- openssh-5.8p1/ssh-keygen.c.fingerprint 2011-01-11 07:20:31.000000000 +0100 -+++ openssh-5.8p1/ssh-keygen.c 2011-02-25 09:17:18.000000000 +0100 -@@ -714,13 +714,14 @@ do_fingerprint(struct passwd *pw) - { - FILE *f; - Key *public; -- char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; -+ char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra, *pfx; - int i, skip = 0, num = 0, invalid = 1; - enum fp_rep rep; - enum fp_type fptype; - struct stat st; - -- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; -+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection(); -+ pfx = print_bubblebabble ? "" : key_fingerprint_prefix(); - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - - if (!have_identity) -@@ -732,8 +733,8 @@ do_fingerprint(struct passwd *pw) - public = key_load_public(identity_file, &comment); - if (public != NULL) { - fp = key_fingerprint(public, fptype, rep); -- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); -- printf("%u %s %s (%s)\n", key_size(public), fp, comment, -+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); -+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, comment, - key_type(public)); - if (log_level >= SYSLOG_LEVEL_VERBOSE) - printf("%s\n", ra); -@@ -798,8 +799,8 @@ do_fingerprint(struct passwd *pw) - } - comment = *cp ? cp : comment; - fp = key_fingerprint(public, fptype, rep); -- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); -- printf("%u %s %s (%s)\n", key_size(public), fp, -+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); -+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, - comment ? comment : "no comment", key_type(public)); - if (log_level >= SYSLOG_LEVEL_VERBOSE) - printf("%s\n", ra); -@@ -823,13 +824,15 @@ printhost(FILE *f, const char *name, Key - if (print_fingerprint) { - enum fp_rep rep; - enum fp_type fptype; -- char *fp, *ra; -+ char *fp, *ra, *pfx; - -- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; -+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection(); -+ pfx = print_bubblebabble ? "" : key_fingerprint_prefix(); - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; -+ - fp = key_fingerprint(public, fptype, rep); -- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); -- printf("%u %s %s (%s)\n", key_size(public), fp, name, -+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); -+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, name, - key_type(public)); - if (log_level >= SYSLOG_LEVEL_VERBOSE) - printf("%s\n", ra); -@@ -1695,16 +1698,17 @@ do_show_cert(struct passwd *pw) - fatal("%s is not a certificate", identity_file); - v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; - -- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -- ca_fp = key_fingerprint(key->cert->signature_key, -- SSH_FP_MD5, SSH_FP_HEX); -+ key_fp = key_selected_fingerprint(key, SSH_FP_HEX); -+ ca_fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX); - - printf("%s:\n", identity_file); - printf(" Type: %s %s certificate\n", key_ssh_name(key), - key_cert_type(key)); -- printf(" Public key: %s %s\n", key_type(key), key_fp); -- printf(" Signing CA: %s %s\n", -- key_type(key->cert->signature_key), ca_fp); -+ printf(" Public key: %s %s%s\n", key_type(key), -+ key_fingerprint_prefix(), key_fp); -+ printf(" Signing CA: %s %s%s\n", -+ key_type(key->cert->signature_key), -+ key_fingerprint_prefix(), ca_fp); - printf(" Key ID: \"%s\"\n", key->cert->key_id); - if (!v00) { - printf(" Serial: %llu\n", -@@ -2249,13 +2253,12 @@ passphrase_again: - fclose(f); - - if (!quiet) { -- char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); -- char *ra = key_fingerprint(public, SSH_FP_MD5, -- SSH_FP_RANDOMART); -+ char *fp = key_selected_fingerprint(public, SSH_FP_HEX); -+ char *ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); - printf("Your public key has been saved in %s.\n", - identity_file); - printf("The key fingerprint is:\n"); -- printf("%s %s\n", fp, comment); -+ printf("%s%s %s\n", key_fingerprint_prefix(), fp, comment); - printf("The key's randomart image is:\n"); - printf("%s\n", ra); - xfree(ra); diff --git a/openssh/patches/openssh-5.8p1-getaddrinfo.patch b/openssh/patches/openssh-5.8p1-getaddrinfo.patch deleted file mode 100644 index 6f640670d..000000000 --- a/openssh/patches/openssh-5.8p1-getaddrinfo.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -up openssh-5.8p1/sshconnect.c.getaddrinfo openssh-5.8p1/sshconnect.c ---- openssh-5.8p1/sshconnect.c.getaddrinfo 2011-04-27 09:51:44.521384633 +0200 -+++ openssh-5.8p1/sshconnect.c 2011-04-27 09:53:21.224443308 +0200 -@@ -355,6 +355,7 @@ ssh_connect(const char *host, struct soc - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; -+ hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; - snprintf(strport, sizeof strport, "%u", port); - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) - fatal("%s: Could not resolve hostname %.100s: %s", __progname, diff --git a/openssh/patches/openssh-5.8p1-localdomain.patch b/openssh/patches/openssh-5.8p1-localdomain.patch deleted file mode 100644 index 2f216584d..000000000 --- a/openssh/patches/openssh-5.8p1-localdomain.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up openssh-5.8p1/sshd_config.localdomain openssh-5.8p1/sshd_config ---- openssh-5.8p1/sshd_config.localdomain 2011-04-22 11:37:49.273648812 +0200 -+++ openssh-5.8p1/sshd_config 2011-04-22 11:39:31.758648401 +0200 -@@ -130,6 +130,10 @@ X11Forwarding yes - # override default of no subsystems - Subsystem sftp /usr/libexec/sftp-server - -+# Uncomment this if you want to use .local domain -+#Host *.local -+# CheckHostIP no -+ - # Example of overriding settings on a per-user basis - #Match User anoncvs - # X11Forwarding no diff --git a/openssh/patches/openssh-5.8p1-packet.patch b/openssh/patches/openssh-5.8p1-packet.patch deleted file mode 100644 index 4951af63c..000000000 --- a/openssh/patches/openssh-5.8p1-packet.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh-5.8p1/packet.c.packet openssh-5.8p1/packet.c ---- openssh-5.8p1/packet.c.packet 2011-04-05 13:29:06.998648899 +0200 -+++ openssh-5.8p1/packet.c 2011-04-05 13:30:32.967648596 +0200 -@@ -294,6 +294,8 @@ packet_connection_is_on_socket(void) - struct sockaddr_storage from, to; - socklen_t fromlen, tolen; - -+ if (!active_state) -+ return 0; - /* filedescriptors in and out are the same, so it's a socket */ - if (active_state->connection_in == active_state->connection_out) - return 1; diff --git a/openssh/patches/openssh-5.8p2-force_krb.patch b/openssh/patches/openssh-5.8p2-force_krb.patch deleted file mode 100644 index 1842ce474..000000000 --- a/openssh/patches/openssh-5.8p2-force_krb.patch +++ /dev/null @@ -1,288 +0,0 @@ -diff -up openssh-5.8p2/gss-serv-krb5.c.force_krb openssh-5.8p2/gss-serv-krb5.c ---- openssh-5.8p2/gss-serv-krb5.c.force_krb 2006-09-01 07:38:36.000000000 +0200 -+++ openssh-5.8p2/gss-serv-krb5.c 2011-05-19 03:41:45.801109545 +0200 -@@ -32,7 +32,9 @@ - #include - - #include -+#include - #include -+#include - - #include "xmalloc.h" - #include "key.h" -@@ -40,12 +42,11 @@ - #include "auth.h" - #include "log.h" - #include "servconf.h" -+#include "misc.h" - - #include "buffer.h" - #include "ssh-gss.h" - --extern ServerOptions options; -- - #ifdef HEIMDAL - # include - #else -@@ -56,6 +57,16 @@ extern ServerOptions options; - # endif - #endif - -+extern Authctxt *the_authctxt; -+extern ServerOptions options; -+ -+/* all commands are allowed by default */ -+char **k5users_allowed_cmds = NULL; -+ -+static int ssh_gssapi_k5login_exists(); -+static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, -+ int); -+ - static krb5_context krb_context = NULL; - - /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -83,10 +94,11 @@ ssh_gssapi_krb5_init(void) - */ - - static int --ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) -+ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *luser) - { - krb5_principal princ; - int retval; -+ int k5login_exists; - - if (ssh_gssapi_krb5_init() == 0) - return 0; -@@ -97,10 +109,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - krb5_get_err_text(krb_context, retval)); - return 0; - } -- if (krb5_kuserok(krb_context, princ, name)) { -+ /* krb5_kuserok() returns 1 if .k5login DNE and this is self-login. -+ * We have to make sure to check .k5users in that case. */ -+ k5login_exists = ssh_gssapi_k5login_exists(); -+ /* NOTE: .k5login and .k5users must opened as root, not the user, -+ * because if they are on a krb5-protected filesystem, user credentials -+ * to access these files aren't available yet. */ -+ if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) { - retval = 1; - logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", -- name, (char *)client->displayname.value); -+ luser, (char *)client->displayname.value); -+ } else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value, -+ luser, k5login_exists)) { -+ retval = 1; -+ logit("Authorized to %s, krb5 principal %s " -+ "(ssh_gssapi_krb5_cmdok)", -+ luser, (char *)client->displayname.value); - } else - retval = 0; - -@@ -108,6 +132,134 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - return retval; - } - -+/* Test for existence of .k5login. -+ * We need this as part of our .k5users check, because krb5_kuserok() -+ * returns success if .k5login DNE and user is logging in as himself. -+ * With .k5login absent and .k5users present, we don't want absence -+ * of .k5login to authorize self-login. (absence of both is required) -+ * Returns 1 if .k5login is available, 0 otherwise. -+ */ -+static int -+ssh_gssapi_k5login_exists() -+{ -+ char file[MAXPATHLEN]; -+ struct passwd *pw = the_authctxt->pw; -+ -+ snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); -+ return access(file, F_OK) == 0; -+} -+ -+/* check .k5users for login or command authorization -+ * Returns 1 if principal is authorized, 0 otherwise. -+ * If principal is authorized, (global) k5users_allowed_cmds may be populated. -+ */ -+static int -+ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, -+ const char *luser, int k5login_exists) -+{ -+ FILE *fp; -+ char file[MAXPATHLEN]; -+ char line[BUFSIZ]; -+ char kuser[65]; /* match krb5_kuserok() */ -+ struct stat st; -+ struct passwd *pw = the_authctxt->pw; -+ int found_principal = 0; -+ int ncommands = 0, allcommands = 0; -+ u_long linenum; -+ -+ snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); -+ /* If both .k5login and .k5users DNE, self-login is ok. */ -+ if (!k5login_exists && (access(file, F_OK) == -1)) { -+ return (krb5_aname_to_localname(krb_context, principal, -+ sizeof(kuser), kuser) == 0) && -+ (strcmp(kuser, luser) == 0); -+ } -+ if ((fp = fopen(file, "r")) == NULL) { -+ int saved_errno = errno; -+ /* 2nd access check to ease debugging if file perms are wrong. -+ * But we don't want to report this if .k5users simply DNE. */ -+ if (access(file, F_OK) == 0) { -+ logit("User %s fopen %s failed: %s", -+ pw->pw_name, file, strerror(saved_errno)); -+ } -+ return 0; -+ } -+ /* .k5users must be owned either by the user or by root */ -+ if (fstat(fileno(fp), &st) == -1) { -+ /* can happen, but very wierd error so report it */ -+ logit("User %s fstat %s failed: %s", -+ pw->pw_name, file, strerror(errno)); -+ fclose(fp); -+ return 0; -+ } -+ if (!(st.st_uid == pw->pw_uid || st.st_uid == 0)) { -+ logit("User %s %s is not owned by root or user", -+ pw->pw_name, file); -+ fclose(fp); -+ return 0; -+ } -+ /* .k5users must be a regular file. krb5_kuserok() doesn't do this -+ * check, but we don't want to be deficient if they add a check. */ -+ if (!S_ISREG(st.st_mode)) { -+ logit("User %s %s is not a regular file", pw->pw_name, file); -+ fclose(fp); -+ return 0; -+ } -+ /* file exists; initialize k5users_allowed_cmds (to none!) */ -+ k5users_allowed_cmds = xcalloc(++ncommands, -+ sizeof(*k5users_allowed_cmds)); -+ -+ /* Check each line. ksu allows unlimited length lines. We don't. */ -+ while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line), -+ &linenum) != -1) { -+ char *token; -+ -+ /* we parse just like ksu, even though we could do better */ -+ token = strtok(line, " \t\n"); -+ if (strcmp(name, token) == 0) { -+ /* we matched on client principal */ -+ found_principal = 1; -+ if ((token = strtok(NULL, " \t\n")) == NULL) { -+ /* only shell is allowed */ -+ k5users_allowed_cmds[ncommands-1] = -+ xstrdup(pw->pw_shell); -+ k5users_allowed_cmds = -+ xrealloc(k5users_allowed_cmds, ++ncommands, -+ sizeof(*k5users_allowed_cmds)); -+ break; -+ } -+ /* process the allowed commands */ -+ while (token) { -+ if (strcmp(token, "*") == 0) { -+ allcommands = 1; -+ break; -+ } -+ k5users_allowed_cmds[ncommands-1] = -+ xstrdup(token); -+ k5users_allowed_cmds = -+ xrealloc(k5users_allowed_cmds, ++ncommands, -+ sizeof(*k5users_allowed_cmds)); -+ token = strtok(NULL, " \t\n"); -+ } -+ } -+ } -+ if (k5users_allowed_cmds) { -+ /* terminate vector */ -+ k5users_allowed_cmds[ncommands-1] = NULL; -+ /* if all commands are allowed, free vector */ -+ if (allcommands) { -+ int i; -+ for (i = 0; i < ncommands; i++) { -+ free(k5users_allowed_cmds[i]); -+ } -+ free(k5users_allowed_cmds); -+ k5users_allowed_cmds = NULL; -+ } -+ } -+ fclose(fp); -+ return found_principal; -+} -+ - - /* This writes out any forwarded credentials from the structure populated - * during userauth. Called after we have setuid to the user */ -diff -up openssh-5.8p2/session.c.force_krb openssh-5.8p2/session.c ---- openssh-5.8p2/session.c.force_krb 2011-05-19 03:41:41.000000000 +0200 -+++ openssh-5.8p2/session.c 2011-05-19 03:43:32.437173662 +0200 -@@ -816,6 +816,29 @@ do_exec(Session *s, const char *command) - debug("Forced command (key option) '%.900s'", command); - } - -+#ifdef GSSAPI -+#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */ -+ else if (k5users_allowed_cmds) { -+ const char *match = command; -+ int allowed = 0, i = 0; -+ -+ if (!match) -+ match = s->pw->pw_shell; -+ while (k5users_allowed_cmds[i]) { -+ if (strcmp(match, k5users_allowed_cmds[i++]) == 0) { -+ debug("Allowed command '%.900s'", match); -+ allowed = 1; -+ break; -+ } -+ } -+ if (!allowed) { -+ debug("command '%.900s' not allowed", match); -+ return 1; -+ } -+ } -+#endif -+#endif -+ - #ifdef SSH_AUDIT_EVENTS - if (s->command != NULL || s->command_handle != -1) - fatal("do_exec: command already set"); -diff -up openssh-5.8p2/sshd.8.force_krb openssh-5.8p2/sshd.8 ---- openssh-5.8p2/sshd.8.force_krb 2011-05-19 03:41:30.582114401 +0200 -+++ openssh-5.8p2/sshd.8 2011-05-19 03:41:46.159106308 +0200 -@@ -320,6 +320,7 @@ Finally, the server and the client enter - The client tries to authenticate itself using - host-based authentication, - public key authentication, -+GSSAPI authentication, - challenge-response authentication, - or password authentication. - .Pp -@@ -788,6 +789,12 @@ This file is used in exactly the same wa - but allows host-based authentication without permitting login with - rlogin/rsh. - .Pp -+.It Pa ~/.k5login -+.It Pa ~/.k5users -+These files enforce GSSAPI/Kerberos authentication access control. -+Further details are described in -+.Xr ksu 1 . -+.Pp - .It Pa ~/.ssh/ - This directory is the default location for all user-specific configuration - and authentication information. -diff -up openssh-5.8p2/ssh-gss.h.force_krb openssh-5.8p2/ssh-gss.h ---- openssh-5.8p2/ssh-gss.h.force_krb 2007-06-12 15:40:39.000000000 +0200 -+++ openssh-5.8p2/ssh-gss.h 2011-05-19 03:41:46.302234118 +0200 -@@ -48,6 +48,10 @@ - #define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name - #endif /* GSS_C_NT_... */ - #endif /* !HEIMDAL */ -+ -+/* .k5users support */ -+extern char **k5users_allowed_cmds; -+ - #endif /* KRB5 */ - - /* draft-ietf-secsh-gsskeyex-06 */ diff --git a/openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch b/openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch deleted file mode 100644 index 4a25d9e15..000000000 --- a/openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up openssh-5.8p2/mux.c.remove_stale openssh-5.8p2/mux.c ---- openssh-5.8p2/mux.c.remove_stale 2011-01-14 02:01:32.000000000 +0100 -+++ openssh-5.8p2/mux.c 2011-06-09 15:27:42.556360291 +0200 -@@ -1867,6 +1867,9 @@ muxclient(const char *path) - unlink(path); - } else if (errno == ENOENT) { - debug("Control socket \"%.100s\" does not exist", path); -+ } else if (errno == ECONNREFUSED) { -+ debug("Removing stale control socket \"%.100s\"", path); -+ unlink(path); - } else { - error("Control socket connect(%.100s): %s", path, - strerror(errno)); diff --git a/openssh/patches/openssh-5.8p2-sigpipe.patch b/openssh/patches/openssh-5.8p2-sigpipe.patch deleted file mode 100644 index 56af045ea..000000000 --- a/openssh/patches/openssh-5.8p2-sigpipe.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c ---- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200 -+++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200 -@@ -715,6 +715,8 @@ main(int argc, char **argv) - fdlim_set(maxfd); - fdcon = xcalloc(maxfd, sizeof(con)); - -+ signal(SIGPIPE, SIG_IGN); -+ - read_wait_nfdset = howmany(maxfd, NFDBITS); - read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); - diff --git a/openssh/patches/openssh-5.9p1-akc.patch b/openssh/patches/openssh-5.9p1-akc.patch deleted file mode 100644 index 62a478b1d..000000000 --- a/openssh/patches/openssh-5.9p1-akc.patch +++ /dev/null @@ -1,452 +0,0 @@ -diff -up openssh-5.9p1/auth2-pubkey.c.akc openssh-5.9p1/auth2-pubkey.c ---- openssh-5.9p1/auth2-pubkey.c.akc 2011-09-14 07:24:40.876512251 +0200 -+++ openssh-5.9p1/auth2-pubkey.c 2011-09-14 07:24:43.318458515 +0200 -@@ -27,6 +27,7 @@ - - #include - #include -+#include - - #include - #include -@@ -276,27 +277,15 @@ match_principals_file(char *file, struct - - /* return 1 if user allows given key */ - static int --user_key_allowed2(struct passwd *pw, Key *key, char *file) -+user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw) - { - char line[SSH_MAX_PUBKEY_BYTES]; - const char *reason; - int found_key = 0; -- FILE *f; - u_long linenum = 0; - Key *found; - char *fp; - -- /* Temporarily use the user's uid. */ -- temporarily_use_uid(pw); -- -- debug("trying public key file %s", file); -- f = auth_openkeyfile(file, pw, options.strict_modes); -- -- if (!f) { -- restore_uid(); -- return 0; -- } -- - found_key = 0; - found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); - -@@ -389,8 +378,6 @@ user_key_allowed2(struct passwd *pw, Key - break; - } - } -- restore_uid(); -- fclose(f); - key_free(found); - if (!found_key) - debug2("key not found"); -@@ -452,13 +439,191 @@ user_cert_trusted_ca(struct passwd *pw, - return ret; - } - --/* check whether given key is in .ssh/authorized_keys* */ -+/* return 1 if user allows given key */ -+static int -+user_key_allowed2(struct passwd *pw, Key *key, char *file) -+{ -+ FILE *f; -+ int found_key = 0; -+ -+ /* Temporarily use the user's uid. */ -+ temporarily_use_uid(pw); -+ -+ debug("trying public key file %s", file); -+ f = auth_openkeyfile(file, pw, options.strict_modes); -+ -+ if (f) { -+ found_key = user_search_key_in_file (f, file, key, pw); -+ fclose(f); -+ } -+ -+ restore_uid(); -+ return found_key; -+} -+ -+#ifdef WITH_AUTHORIZED_KEYS_COMMAND -+ -+#define WHITESPACE " \t\r\n" -+ -+/* return 1 if user allows given key */ -+static int -+user_key_via_command_allowed2(struct passwd *pw, Key *key) -+{ -+ FILE *f; -+ int found_key = 0; -+ char *progname = NULL; -+ char *cp; -+ struct passwd *runas_pw; -+ struct stat st; -+ int childdescriptors[2], i; -+ pid_t pstat, pid, child; -+ -+ if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/') -+ return 0; -+ -+ /* get the run as identity from config */ -+ runas_pw = (options.authorized_keys_command_runas == NULL)? pw -+ : getpwnam (options.authorized_keys_command_runas); -+ if (!runas_pw) { -+ error("%s: getpwnam(\"%s\"): %s", __func__, -+ options.authorized_keys_command_runas, strerror(errno)); -+ return 0; -+ } -+ -+ /* Temporarily use the specified uid. */ -+ if (runas_pw->pw_uid != 0) -+ temporarily_use_uid(runas_pw); -+ -+ progname = xstrdup(options.authorized_keys_command); -+ -+ debug3("%s: checking program '%s'", __func__, progname); -+ -+ if (stat (progname, &st) < 0) { -+ error("%s: stat(\"%s\"): %s", __func__, -+ progname, strerror(errno)); -+ goto go_away; -+ } -+ -+ if (st.st_uid != 0 || (st.st_mode & 022) != 0) { -+ error("bad ownership or modes for AuthorizedKeysCommand \"%s\"", -+ progname); -+ goto go_away; -+ } -+ -+ if (!S_ISREG(st.st_mode)) { -+ error("AuthorizedKeysCommand \"%s\" is not a regular file", -+ progname); -+ goto go_away; -+ } -+ -+ /* -+ * Descend the path, checking that each component is a -+ * root-owned directory with strict permissions. -+ */ -+ do { -+ if ((cp = strrchr(progname, '/')) == NULL) -+ break; -+ else -+ *cp = '\0'; -+ -+ debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname)); -+ -+ if (stat((*progname == '\0' ? "/" : progname), &st) != 0) { -+ error("%s: stat(\"%s\"): %s", __func__, -+ progname, strerror(errno)); -+ goto go_away; -+ } -+ if (st.st_uid != 0 || (st.st_mode & 022) != 0) { -+ error("bad ownership or modes for AuthorizedKeysCommand path component \"%s\"", -+ progname); -+ goto go_away; -+ } -+ if (!S_ISDIR(st.st_mode)) { -+ error("AuthorizedKeysCommand path component \"%s\" is not a directory", -+ progname); -+ goto go_away; -+ } -+ } while (1); -+ -+ /* open the pipe and read the keys */ -+ if (pipe(childdescriptors)) { -+ error("failed to pipe(2) for AuthorizedKeysCommand: %s", -+ strerror(errno)); -+ goto go_away; -+ } -+ -+ child = fork(); -+ if (child == -1) { -+ error("failed to fork(2) for AuthorizedKeysCommand: %s", -+ strerror(errno)); -+ goto go_away; -+ } else if (child == 0) { -+ /* we're in the child process here -- we should never return from this block. */ -+ /* permanently drop privs in child process */ -+ if (runas_pw->pw_uid != 0) { -+ restore_uid(); -+ permanently_set_uid(runas_pw); -+ } -+ -+ close(childdescriptors[0]); -+ /* put the write end of the pipe on stdout (FD 1) */ -+ if (dup2(childdescriptors[1], 1) == -1) { -+ error("failed to dup2(2) from AuthorizedKeysCommand: %s", -+ strerror(errno)); -+ _exit(127); -+ } -+ -+ debug3("about to execl() AuthorizedKeysCommand: \"%s\" \"%s\"", options.authorized_keys_command, pw->pw_name); -+ /* see session.c:child_close_fds() */ -+ for (i = 3; i < 64; ++i) { -+ close(i); -+ } -+ -+ execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL); -+ -+ /* if we got here, it didn't work */ -+ error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */ -+ _exit(127); -+ } -+ -+ close(childdescriptors[1]); -+ f = fdopen(childdescriptors[0], "r"); -+ if (!f) { -+ error("%s: could not buffer FDs from AuthorizedKeysCommand (\"%s\", \"r\"): %s", __func__, -+ options.authorized_keys_command, strerror (errno)); -+ goto go_away; -+ } -+ -+ found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw); -+ fclose (f); -+ do { -+ pid = waitpid(child, &pstat, 0); -+ } while (pid == -1 && errno == EINTR); -+ -+ /* what about the return value from the child process? */ -+go_away: -+ if (progname) -+ xfree (progname); -+ -+ if (runas_pw->pw_uid != 0) -+ restore_uid(); -+ return found_key; -+} -+#endif -+ -+/* check whether given key is in 0) -+ return success; -+#endif -+ - if (auth_key_is_revoked(key)) - return 0; - if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key)) -diff -up openssh-5.9p1/configure.ac.akc openssh-5.9p1/configure.ac ---- openssh-5.9p1/configure.ac.akc 2011-09-14 07:24:42.863494886 +0200 -+++ openssh-5.9p1/configure.ac 2011-09-14 07:24:43.441583848 +0200 -@@ -1421,6 +1421,18 @@ AC_ARG_WITH([audit], - esac ] - ) - -+# Check whether user wants AuthorizedKeysCommand support -+AKC_MSG="no" -+AC_ARG_WITH(authorized-keys-command, -+ [ --with-authorized-keys-command Enable AuthorizedKeysCommand support], -+ [ -+ if test "x$withval" != "xno" ; then -+ AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support]) -+ AKC_MSG="yes" -+ fi -+ ] -+) -+ - dnl Checks for library functions. Please keep in alphabetical order - AC_CHECK_FUNCS([ \ - arc4random \ -@@ -4239,6 +4251,7 @@ echo " SELinux support - echo " Smartcard support: $SCARD_MSG" - echo " S/KEY support: $SKEY_MSG" - echo " TCP Wrappers support: $TCPW_MSG" -+echo " AuthorizedKeysCommand support: $AKC_MSG" - echo " MD5 password support: $MD5_MSG" - echo " libedit support: $LIBEDIT_MSG" - echo " Solaris process contract support: $SPC_MSG" -diff -up openssh-5.9p1/servconf.c.akc openssh-5.9p1/servconf.c ---- openssh-5.9p1/servconf.c.akc 2011-09-14 07:24:29.402475399 +0200 -+++ openssh-5.9p1/servconf.c 2011-09-14 07:56:27.158585590 +0200 -@@ -139,6 +139,8 @@ initialize_server_options(ServerOptions - options->num_permitted_opens = -1; - options->adm_forced_command = NULL; - options->chroot_directory = NULL; -+ options->authorized_keys_command = NULL; -+ options->authorized_keys_command_runas = NULL; - options->zero_knowledge_password_authentication = -1; - options->revoked_keys_file = NULL; - options->trusted_user_ca_keys = NULL; -@@ -348,6 +350,7 @@ typedef enum { - sZeroKnowledgePasswordAuthentication, sHostCertificate, - sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, - sKexAlgorithms, sIPQoS, -+ sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs, - sDeprecated, sUnsupported - } ServerOpCodes; - -@@ -487,6 +490,13 @@ static struct { - { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, - { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, - { "ipqos", sIPQoS, SSHCFG_ALL }, -+#ifdef WITH_AUTHORIZED_KEYS_COMMAND -+ { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, -+ { "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL }, -+#else -+ { "authorizedkeyscommand", sUnsupported, SSHCFG_ALL }, -+ { "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL }, -+#endif - { NULL, sBadOption, 0 } - }; - -@@ -1462,6 +1472,24 @@ process_server_config_line(ServerOptions - } - break; - -+ case sAuthorizedKeysCommand: -+ len = strspn(cp, WHITESPACE); -+ if (*activep && options->authorized_keys_command == NULL) -+ options->authorized_keys_command = xstrdup(cp + len); -+ return 0; -+ -+ case sAuthorizedKeysCommandRunAs: -+ charptr = &options->authorized_keys_command_runas; -+ -+ arg = strdelim(&cp); -+ if (!arg || *arg == '\0') -+ fatal("%s line %d: missing account.", -+ filename, linenum); -+ -+ if (*activep && *charptr == NULL) -+ *charptr = xstrdup(arg); -+ break; -+ - case sDeprecated: - logit("%s line %d: Deprecated option %s", - filename, linenum, arg); -@@ -1573,6 +1601,8 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(zero_knowledge_password_authentication); - M_CP_INTOPT(second_zero_knowledge_password_authentication); - M_CP_INTOPT(two_factor_authentication); -+ M_CP_STROPT(authorized_keys_command); -+ M_CP_STROPT(authorized_keys_command_runas); - M_CP_INTOPT(permit_root_login); - M_CP_INTOPT(permit_empty_passwd); - -@@ -1839,6 +1869,8 @@ dump_config(ServerOptions *o) - dump_cfg_string(sRevokedKeys, o->revoked_keys_file); - dump_cfg_string(sAuthorizedPrincipalsFile, - o->authorized_principals_file); -+ dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); -+ dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas); - - /* string arguments requiring a lookup */ - dump_cfg_string(sLogLevel, log_level_name(o->log_level)); -diff -up openssh-5.9p1/servconf.h.akc openssh-5.9p1/servconf.h ---- openssh-5.9p1/servconf.h.akc 2011-09-14 07:24:29.511480441 +0200 -+++ openssh-5.9p1/servconf.h 2011-09-14 07:24:43.678459183 +0200 -@@ -174,6 +174,8 @@ typedef struct { - char *revoked_keys_file; - char *trusted_user_ca_keys; - char *authorized_principals_file; -+ char *authorized_keys_command; -+ char *authorized_keys_command_runas; - } ServerOptions; - - /* -diff -up openssh-5.9p1/sshd_config.0.akc openssh-5.9p1/sshd_config.0 ---- openssh-5.9p1/sshd_config.0.akc 2011-09-07 01:16:30.000000000 +0200 -+++ openssh-5.9p1/sshd_config.0 2011-09-14 07:24:43.791460201 +0200 -@@ -71,6 +71,23 @@ DESCRIPTION - - See PATTERNS in ssh_config(5) for more information on patterns. - -+ AuthorizedKeysCommand -+ -+ Specifies a program to be used for lookup of the user's -+ public keys. The program will be invoked with its first -+ argument the name of the user being authorized, and should produce -+ on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS -+ in sshd(8)). By default (or when set to the empty string) there is no -+ AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully -+ authorize the user, authorization falls through to the -+ AuthorizedKeysFile. Note that this option has an effect -+ only with PubkeyAuthentication turned on. -+ -+ AuthorizedKeysCommandRunAs -+ Specifies the user under whose account the AuthorizedKeysCommand is run. -+ Empty string (the default value) means the user being authorized -+ is used. -+ - AuthorizedKeysFile - Specifies the file that contains the public keys that can be used - for user authentication. The format is described in the -@@ -401,7 +418,8 @@ DESCRIPTION - - Only a subset of keywords may be used on the lines following a - Match keyword. Available keywords are AllowAgentForwarding, -- AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile, -+ AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand, -+ AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile, - Banner, ChrootDirectory, ForceCommand, GatewayPorts, - GSSAPIAuthentication, HostbasedAuthentication, - HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication, -diff -up openssh-5.9p1/sshd_config.5.akc openssh-5.9p1/sshd_config.5 ---- openssh-5.9p1/sshd_config.5.akc 2011-09-14 07:24:29.793520372 +0200 -+++ openssh-5.9p1/sshd_config.5 2011-09-14 07:24:43.912583678 +0200 -@@ -706,6 +706,8 @@ Available keywords are - .Cm AllowAgentForwarding , - .Cm AllowTcpForwarding , - .Cm AuthorizedKeysFile , -+.Cm AuthorizedKeysCommand , -+.Cm AuthorizedKeysCommandRunAs , - .Cm AuthorizedPrincipalsFile , - .Cm Banner , - .Cm ChrootDirectory , -@@ -718,6 +720,7 @@ Available keywords are - .Cm KerberosAuthentication , - .Cm MaxAuthTries , - .Cm MaxSessions , -+.Cm PubkeyAuthentication , - .Cm PasswordAuthentication , - .Cm PermitEmptyPasswords , - .Cm PermitOpen , -@@ -926,6 +929,20 @@ Specifies a list of revoked public keys. - Keys listed in this file will be refused for public key authentication. - Note that if this file is not readable, then public key authentication will - be refused for all users. -+.It Cm AuthorizedKeysCommand -+Specifies a program to be used for lookup of the user's -+public keys. The program will be invoked with its first -+argument the name of the user being authorized, and should produce -+on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS -+in sshd(8)). By default (or when set to the empty string) there is no -+AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully -+authorize the user, authorization falls through to the -+AuthorizedKeysFile. Note that this option has an effect -+only with PubkeyAuthentication turned on. -+.It Cm AuthorizedKeysCommandRunAs -+Specifies the user under whose account the AuthorizedKeysCommand is run. Empty -+string (the default value) means the user being authorized is used. -+.Dq - .It Cm RhostsRSAAuthentication - Specifies whether rhosts or /etc/hosts.equiv authentication together - with successful RSA host authentication is allowed. -diff -up openssh-5.9p1/sshd_config.akc openssh-5.9p1/sshd_config ---- openssh-5.9p1/sshd_config.akc 2011-09-14 07:24:29.620461608 +0200 -+++ openssh-5.9p1/sshd_config 2011-09-14 07:24:44.034462546 +0200 -@@ -49,6 +49,9 @@ - # but this is overridden so installations will only check .ssh/authorized_keys - AuthorizedKeysFile .ssh/authorized_keys - -+#AuthorizedKeysCommand none -+#AuthorizedKeysCommandRunAs nobody -+ - # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts - #RhostsRSAAuthentication no - # similar for protocol version 2 diff --git a/openssh/patches/openssh-5.9p1-edns.patch b/openssh/patches/openssh-5.9p1-edns.patch deleted file mode 100644 index 34f385126..000000000 --- a/openssh/patches/openssh-5.9p1-edns.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff -up openssh-5.9p1/dns.c.edns openssh-5.9p1/dns.c ---- openssh-5.9p1/dns.c.edns 2010-08-31 14:41:14.000000000 +0200 -+++ openssh-5.9p1/dns.c 2011-09-09 08:05:27.782440497 +0200 -@@ -177,6 +177,7 @@ verify_host_key_dns(const char *hostname - { - u_int counter; - int result; -+ unsigned int rrset_flags = 0; - struct rrsetinfo *fingerprints = NULL; - - u_int8_t hostkey_algorithm; -@@ -200,8 +201,19 @@ verify_host_key_dns(const char *hostname - return -1; - } - -+ /* -+ * Original getrrsetbyname function, found on OpenBSD for example, -+ * doesn't accept any flag and prerequisite for obtaining AD bit in -+ * DNS response is set by "options edns0" in resolv.conf. -+ * -+ * Our version is more clever and use RRSET_FORCE_EDNS0 flag. -+ */ -+#ifndef HAVE_GETRRSETBYNAME -+ rrset_flags |= RRSET_FORCE_EDNS0; -+#endif - result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, -- DNS_RDATATYPE_SSHFP, 0, &fingerprints); -+ DNS_RDATATYPE_SSHFP, rrset_flags, &fingerprints); -+ - if (result) { - verbose("DNS lookup error: %s", dns_result_totext(result)); - return -1; -diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.c ---- openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns 2009-07-13 03:38:23.000000000 +0200 -+++ openssh-5.9p1/openbsd-compat/getrrsetbyname.c 2011-09-09 15:03:39.930500801 +0200 -@@ -209,8 +209,8 @@ getrrsetbyname(const char *hostname, uns - goto fail; - } - -- /* don't allow flags yet, unimplemented */ -- if (flags) { -+ /* Allow RRSET_FORCE_EDNS0 flag only. */ -+ if ((flags & ~RRSET_FORCE_EDNS0) != 0) { - result = ERRSET_INVAL; - goto fail; - } -@@ -226,9 +226,9 @@ getrrsetbyname(const char *hostname, uns - #endif /* DEBUG */ - - #ifdef RES_USE_DNSSEC -- /* turn on DNSSEC if EDNS0 is configured */ -- if (_resp->options & RES_USE_EDNS0) -- _resp->options |= RES_USE_DNSSEC; -+ /* turn on DNSSEC if required */ -+ if (flags & RRSET_FORCE_EDNS0) -+ _resp->options |= (RES_USE_EDNS0|RES_USE_DNSSEC); - #endif /* RES_USE_DNSEC */ - - /* make query */ -diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.h ---- openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns 2007-10-26 08:26:50.000000000 +0200 -+++ openssh-5.9p1/openbsd-compat/getrrsetbyname.h 2011-09-09 08:05:27.965438689 +0200 -@@ -72,6 +72,9 @@ - #ifndef RRSET_VALIDATED - # define RRSET_VALIDATED 1 - #endif -+#ifndef RRSET_FORCE_EDNS0 -+# define RRSET_FORCE_EDNS0 0x0001 -+#endif - - /* - * Return codes for getrrsetbyname() diff --git a/openssh/patches/openssh-5.9p1-ipfire.patch b/openssh/patches/openssh-5.9p1-ipfire.patch deleted file mode 100644 index cdb49c628..000000000 --- a/openssh/patches/openssh-5.9p1-ipfire.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff -up openssh-5.9p0/ssh_config.redhat openssh-5.9p0/ssh_config ---- openssh-5.9p0/ssh_config.redhat 2010-01-12 09:40:27.000000000 +0100 -+++ openssh-5.9p0/ssh_config 2011-09-05 14:48:16.386439023 +0200 -@@ -45,3 +45,14 @@ - # PermitLocalCommand no - # VisualHostKey no - # ProxyCommand ssh -q -W %h:%p gateway.example.com -+Host * -+ GSSAPIAuthentication yes -+# If this option is set to yes then remote X11 clients will have full access -+# to the original X11 display. As virtually no X11 client supports the untrusted -+# mode correctly we set this to yes. -+ ForwardX11Trusted yes -+# Send locale-related environment variables -+ SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES -+ SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT -+ SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE -+ SendEnv XMODIFIERS -diff -up openssh-5.9p0/sshd_config.0.redhat openssh-5.9p0/sshd_config.0 ---- openssh-5.9p0/sshd_config.0.redhat 2011-09-05 14:48:08.522441255 +0200 -+++ openssh-5.9p0/sshd_config.0 2011-09-05 14:48:16.477443868 +0200 -@@ -581,9 +581,9 @@ DESCRIPTION - - SyslogFacility - Gives the facility code that is used when logging messages from -- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, -- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The -- default is AUTH. -+ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV, -+ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. -+ The default is AUTH. - - TCPKeepAlive - Specifies whether the system should send TCP keepalive messages -diff -up openssh-5.9p0/sshd_config.5.redhat openssh-5.9p0/sshd_config.5 ---- openssh-5.9p0/sshd_config.5.redhat 2011-09-05 14:48:08.657564688 +0200 -+++ openssh-5.9p0/sshd_config.5 2011-09-05 14:48:16.589501736 +0200 -@@ -1029,7 +1029,7 @@ Note that this option applies to protoco - .It Cm SyslogFacility - Gives the facility code that is used when logging messages from - .Xr sshd 8 . --The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, -+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, - LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. - The default is AUTH. - .It Cm TCPKeepAlive -diff -up openssh-5.9p0/sshd_config.redhat openssh-5.9p0/sshd_config ---- openssh-5.9p0/sshd_config.redhat 2011-09-05 14:48:16.250626793 +0200 -+++ openssh-5.9p0/sshd_config 2011-09-05 15:06:01.513443553 +0200 -@@ -32,6 +32,7 @@ - # Logging - # obsoletes QuietMode and FascistLogging - #SyslogFacility AUTH -+SyslogFacility AUTHPRIV - #LogLevel INFO - - # Authentication: -@@ -65,9 +66,11 @@ AuthorizedKeysFile .ssh/authorized_keys - # To disable tunneled clear text passwords, change to no here! - #PasswordAuthentication yes - #PermitEmptyPasswords no -+PasswordAuthentication yes - - # Change to no to disable s/key passwords - #ChallengeResponseAuthentication yes -+ChallengeResponseAuthentication no - - # Kerberos options - #KerberosAuthentication no -@@ -77,7 +80,9 @@ AuthorizedKeysFile .ssh/authorized_keys - - # GSSAPI options - #GSSAPIAuthentication no -+GSSAPIAuthentication yes - #GSSAPICleanupCredentials yes -+GSSAPICleanupCredentials yes - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will -@@ -89,6 +94,7 @@ AuthorizedKeysFile .ssh/authorized_keys - # PAM authentication, then enable this but set PasswordAuthentication - # and ChallengeResponseAuthentication to 'no'. - #UsePAM no -+UsePAM yes - - #TwoFactorAuthentication no - #SecondPubkeyAuthentication yes -@@ -101,6 +107,7 @@ AuthorizedKeysFile .ssh/authorized_keys - #AllowTcpForwarding yes - #GatewayPorts no - #X11Forwarding no -+X11Forwarding yes - #X11DisplayOffset 10 - #X11UseLocalhost yes - #PrintMotd yes -@@ -121,6 +128,12 @@ AuthorizedKeysFile .ssh/authorized_keys - # no default banner path - #Banner none - -+# Accept locale-related environment variables -+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES -+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT -+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE -+AcceptEnv XMODIFIERS -+ - # override default of no subsystems - Subsystem sftp /usr/libexec/sftp-server - diff --git a/openssh/patches/openssh-5.9p1-ipv6man.patch b/openssh/patches/openssh-5.9p1-ipv6man.patch deleted file mode 100644 index ece1a73d3..000000000 --- a/openssh/patches/openssh-5.9p1-ipv6man.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1 ---- openssh-5.9p0/ssh.1.ipv6man 2011-08-05 22:17:32.000000000 +0200 -+++ openssh-5.9p0/ssh.1 2011-08-31 13:08:34.880024485 +0200 -@@ -1400,6 +1400,8 @@ manual page for more information. - .Nm - exits with the exit status of the remote command or with 255 - if an error occurred. -+.Sh IPV6 -+IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. - .Sh SEE ALSO - .Xr scp 1 , - .Xr sftp 1 , -diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8 ---- openssh-5.9p0/sshd.8.ipv6man 2011-08-05 22:17:32.000000000 +0200 -+++ openssh-5.9p0/sshd.8 2011-08-31 13:10:34.129039094 +0200 -@@ -940,6 +940,8 @@ concurrently for different ports, this c - started last). - The content of this file is not sensitive; it can be world-readable. - .El -+.Sh IPV6 -+IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. - .Sh SEE ALSO - .Xr scp 1 , - .Xr sftp 1 , diff --git a/openssh/patches/openssh-5.9p1-keygen.patch b/openssh/patches/openssh-5.9p1-keygen.patch deleted file mode 100644 index 69d4a6f43..000000000 --- a/openssh/patches/openssh-5.9p1-keygen.patch +++ /dev/null @@ -1,80 +0,0 @@ -diff -up openssh-5.9p0/ssh-keygen.0.keygen openssh-5.9p0/ssh-keygen.0 ---- openssh-5.9p0/ssh-keygen.0.keygen 2011-08-29 16:30:02.000000000 +0200 -+++ openssh-5.9p0/ssh-keygen.0 2011-08-30 13:47:56.208087184 +0200 -@@ -4,7 +4,7 @@ NAME - ssh-keygen - authentication key generation, management and conversion - - SYNOPSIS -- ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment] -+ ssh-keygen [-q] [-o] [-b bits] -t type [-N new_passphrase] [-C comment] - [-f output_keyfile] - ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] - ssh-keygen -i [-m key_format] [-f input_keyfile] -@@ -181,6 +181,8 @@ DESCRIPTION - principals may be specified, separated by commas. Please see the - CERTIFICATES section for details. - -+ -o Overwrite the key without prompting user. -+ - -O option - Specify a certificate option when signing a key. This option may - be specified multiple times. Please see the CERTIFICATES section -diff -up openssh-5.9p0/ssh-keygen.1.keygen openssh-5.9p0/ssh-keygen.1 ---- openssh-5.9p0/ssh-keygen.1.keygen 2011-08-30 13:32:30.787149917 +0200 -+++ openssh-5.9p0/ssh-keygen.1 2011-08-30 13:46:42.638087171 +0200 -@@ -45,6 +45,7 @@ - .Bk -words - .Nm ssh-keygen - .Op Fl q -+.Op Fl o - .Op Fl b Ar bits - .Fl t Ar type - .Op Fl N Ar new_passphrase -@@ -339,6 +340,8 @@ Multiple principals may be specified, se - Please see the - .Sx CERTIFICATES - section for details. -+.It Fl o -+Overwrite the key without prompting user. - .It Fl O Ar option - Specify a certificate option when signing a key. - This option may be specified multiple times. -diff -up openssh-5.9p0/ssh-keygen.c.keygen openssh-5.9p0/ssh-keygen.c ---- openssh-5.9p0/ssh-keygen.c.keygen 2011-08-30 13:32:20.268149992 +0200 -+++ openssh-5.9p0/ssh-keygen.c 2011-08-30 13:39:34.550214102 +0200 -@@ -73,6 +73,7 @@ int change_passphrase = 0; - int change_comment = 0; - - int quiet = 0; -+int overwrite = 0; - - int log_level = SYSLOG_LEVEL_INFO; - -@@ -1959,7 +1960,7 @@ main(int argc, char **argv) - exit(1); - } - -- while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:" -+ while ((opt = getopt(argc, argv, "AegiqopclBHLhvxXyF:b:f:t:D:I:P:m:N:n:" - "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) { - switch (opt) { - case 'A': -@@ -2042,6 +2043,9 @@ main(int argc, char **argv) - case 'q': - quiet = 1; - break; -+ case 'o': -+ overwrite = 1; -+ break; - case 'e': - case 'x': - /* export key */ -@@ -2278,7 +2282,7 @@ main(int argc, char **argv) - } - } - /* If the file already exists, ask the user to confirm. */ -- if (stat(identity_file, &st) >= 0) { -+ if (!overwrite && stat(identity_file, &st) >= 0) { - char yesno[3]; - printf("%s already exists.\n", identity_file); - printf("Overwrite (y/n)? "); diff --git a/openssh/patches/openssh-5.9p1-randclean.patch b/openssh/patches/openssh-5.9p1-randclean.patch deleted file mode 100644 index a2c5d3349..000000000 --- a/openssh/patches/openssh-5.9p1-randclean.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up openssh-5.9p0/entropy.c.randclean openssh-5.9p0/entropy.c ---- openssh-5.9p0/entropy.c.randclean 2011-08-30 13:52:45.000000000 +0200 -+++ openssh-5.9p0/entropy.c 2011-08-30 13:57:44.630111338 +0200 -@@ -217,6 +217,9 @@ seed_rng(void) - fatal("OpenSSL version mismatch. Built against %lx, you " - "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); - -+ /* clean the PRNG status when exiting the program */ -+ atexit(RAND_cleanup); -+ - #ifndef OPENSSL_PRNG_ONLY - if (RAND_status() == 1) { - debug3("RNG is ready, skipping seeding"); diff --git a/openssh/patches/openssh-5.9p1-sftp-chroot.patch b/openssh/patches/openssh-5.9p1-sftp-chroot.patch deleted file mode 100644 index cfe4366fd..000000000 --- a/openssh/patches/openssh-5.9p1-sftp-chroot.patch +++ /dev/null @@ -1,63 +0,0 @@ -diff -up openssh-5.9p0/openbsd-compat/port-linux.c.sftp-chroot openssh-5.9p0/openbsd-compat/port-linux.c ---- openssh-5.9p0/openbsd-compat/port-linux.c.sftp-chroot 2011-09-01 04:12:22.743024608 +0200 -+++ openssh-5.9p0/openbsd-compat/port-linux.c 2011-09-01 04:12:23.069088065 +0200 -@@ -503,6 +503,23 @@ ssh_selinux_change_context(const char *n - xfree(newctx); - } - -+void -+ssh_selinux_copy_context(void) -+{ -+ char *ctx; -+ -+ if (!ssh_selinux_enabled()) -+ return; -+ -+ if (getexeccon((security_context_t *)&ctx) < 0) { -+ logit("%s: getcon failed with %s", __func__, strerror (errno)); -+ return; -+ } -+ if (setcon(ctx) < 0) -+ logit("%s: setcon failed with %s", __func__, strerror (errno)); -+ xfree(ctx); -+} -+ - #endif /* WITH_SELINUX */ - - #ifdef LINUX_OOM_ADJUST -diff -up openssh-5.9p0/openbsd-compat/port-linux.h.sftp-chroot openssh-5.9p0/openbsd-compat/port-linux.h ---- openssh-5.9p0/openbsd-compat/port-linux.h.sftp-chroot 2011-01-25 02:16:18.000000000 +0100 -+++ openssh-5.9p0/openbsd-compat/port-linux.h 2011-09-01 04:12:23.163088777 +0200 -@@ -24,6 +24,7 @@ int ssh_selinux_enabled(void); - void ssh_selinux_setup_pty(char *, const char *); - void ssh_selinux_setup_exec_context(char *); - void ssh_selinux_change_context(const char *); -+void ssh_selinux_chopy_context(void); - void ssh_selinux_setfscreatecon(const char *); - #endif - -diff -up openssh-5.9p0/session.c.sftp-chroot openssh-5.9p0/session.c ---- openssh-5.9p0/session.c.sftp-chroot 2011-09-01 04:12:19.698049195 +0200 -+++ openssh-5.9p0/session.c 2011-09-01 04:40:03.598148719 +0200 -@@ -1519,6 +1519,9 @@ do_setusercontext(struct passwd *pw) - pw->pw_uid); - chroot_path = percent_expand(tmp, "h", pw->pw_dir, - "u", pw->pw_name, (char *)NULL); -+#ifdef WITH_SELINUX -+ ssh_selinux_change_context("chroot_user_t"); -+#endif - safely_chroot(chroot_path, pw->pw_uid); - free(tmp); - free(chroot_path); -@@ -1788,7 +1791,10 @@ do_child(Session *s, const char *command - optind = optreset = 1; - __progname = argv[0]; - #ifdef WITH_SELINUX -- ssh_selinux_change_context("sftpd_t"); -+ if (options.chroot_directory == NULL || -+ strcasecmp(options.chroot_directory, "none") == 0) { -+ ssh_selinux_copy_context(); -+ } - #endif - exit(sftp_server_main(i, argv, s->pw)); - } diff --git a/openssh/patches/openssh-6.0p1-entropy.patch b/openssh/patches/openssh-6.0p1-entropy.patch deleted file mode 100644 index 79f05f4aa..000000000 --- a/openssh/patches/openssh-6.0p1-entropy.patch +++ /dev/null @@ -1,272 +0,0 @@ -diff -up openssh-6.0p1/entropy.c.entropy openssh-6.0p1/entropy.c ---- openssh-6.0p1/entropy.c.entropy 2012-08-06 20:51:59.131033413 +0200 -+++ openssh-6.0p1/entropy.c 2012-08-06 20:51:59.171033257 +0200 -@@ -237,6 +237,9 @@ seed_rng(void) - memset(buf, '\0', sizeof(buf)); - - #endif /* OPENSSL_PRNG_ONLY */ -+#ifdef __linux__ -+ linux_seed(); -+#endif /* __linux__ */ - if (RAND_status() != 1) - fatal("PRNG is not seeded"); - } -diff -up openssh-6.0p1/openbsd-compat/Makefile.in.entropy openssh-6.0p1/openbsd-compat/Makefile.in ---- openssh-6.0p1/openbsd-compat/Makefile.in.entropy 2012-08-06 20:51:59.100033534 +0200 -+++ openssh-6.0p1/openbsd-compat/Makefile.in 2012-08-06 20:51:59.171033257 +0200 -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport - - COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o - --PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o -+PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o - - .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff -up openssh-6.0p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.0p1/openbsd-compat/port-linux-prng.c ---- openssh-6.0p1/openbsd-compat/port-linux-prng.c.entropy 2012-08-06 20:51:59.171033257 +0200 -+++ openssh-6.0p1/openbsd-compat/port-linux-prng.c 2012-08-06 20:51:59.171033257 +0200 -@@ -0,0 +1,59 @@ -+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ -+ -+/* -+ * Copyright (c) 2011 Jan F. Chadima -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/* -+ * Linux-specific portability code - prng support -+ */ -+ -+#include "includes.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "log.h" -+#include "xmalloc.h" -+#include "servconf.h" -+#include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" -+ -+void -+linux_seed(void) -+{ -+ int len; -+ char *env = getenv("SSH_USE_STRONG_RNG"); -+ char *random = "/dev/random"; -+ size_t ienv, randlen = 6; -+ -+ if (!env || !strcmp(env, "0")) -+ random = "/dev/urandom"; -+ else if ((ienv = atoi(env)) > 6) -+ randlen = ienv; -+ -+ errno = 0; -+ if ((len = RAND_load_file(random, randlen)) != randlen) { -+ if (errno) -+ fatal ("cannot read from %s, %s", random, strerror(errno)); -+ else -+ fatal ("EOF reading %s", random); -+ } -+} -diff -up openssh-6.0p1/ssh.1.entropy openssh-6.0p1/ssh.1 ---- openssh-6.0p1/ssh.1.entropy 2012-08-06 20:51:59.139033382 +0200 -+++ openssh-6.0p1/ssh.1 2012-08-06 20:51:59.174033245 +0200 -@@ -1269,6 +1269,23 @@ For more information, see the - .Cm PermitUserEnvironment - option in - .Xr sshd_config 5 . -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.It Ev SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh FILES - .Bl -tag -width Ds -compact - .It Pa ~/.rhosts -diff -up openssh-6.1p1/ssh-add.0.entropy openssh-6.1p1/ssh-add.0 ---- openssh-6.1p1/ssh-add.0.entropy 2012-11-12 13:11:42.717393364 +0100 -+++ openssh-6.1p1/ssh-add.0 2012-11-12 13:12:46.288108790 +0100 -@@ -81,6 +81,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 6 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-6.1p1/ssh-add.1.entropy openssh-6.1p1/ssh-add.1 ---- openssh-6.1p1/ssh-add.1.entropy 2011-10-18 07:06:33.000000000 +0200 -+++ openssh-6.1p1/ssh-add.1 2012-11-12 13:11:24.711476108 +0100 -@@ -160,6 +160,20 @@ to make this work.) - Identifies the path of a - .Ux Ns -domain - socket used to communicate with the agent. -+.It Ev SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. - .El - .Sh FILES - .Bl -tag -width Ds - .It Pa ~/.ssh/identity -diff -up openssh-6.0p1/ssh-agent.1.entropy openssh-6.0p1/ssh-agent.1 ---- openssh-6.0p1/ssh-agent.1.entropy 2010-12-01 01:50:35.000000000 +0100 -+++ openssh-6.0p1/ssh-agent.1 2012-08-06 20:51:59.172033253 +0200 -@@ -198,6 +198,24 @@ sockets used to contain the connection t - These sockets should only be readable by the owner. - The sockets should get automatically removed when the agent exits. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-add 1 , -diff -up openssh-6.0p1/sshd.8.entropy openssh-6.0p1/sshd.8 ---- openssh-6.0p1/sshd.8.entropy 2012-08-06 20:51:59.139033382 +0200 -+++ openssh-6.0p1/sshd.8 2012-08-06 20:51:59.174033245 +0200 -@@ -943,6 +943,24 @@ concurrently for different ports, this c - started last). - The content of this file is not sensitive; it can be world-readable. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh IPV6 - IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. - .Sh SEE ALSO -diff -up openssh-6.0p1/ssh-keygen.1.entropy openssh-6.0p1/ssh-keygen.1 ---- openssh-6.0p1/ssh-keygen.1.entropy 2011-10-18 07:05:21.000000000 +0200 -+++ openssh-6.0p1/ssh-keygen.1 2012-08-06 20:51:59.173033249 +0200 -@@ -675,6 +675,24 @@ Contains Diffie-Hellman groups used for - The file format is described in - .Xr moduli 5 . - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-add 1 , -diff -up openssh-6.0p1/ssh-keysign.8.entropy openssh-6.0p1/ssh-keysign.8 ---- openssh-6.0p1/ssh-keysign.8.entropy 2010-08-31 14:41:14.000000000 +0200 -+++ openssh-6.0p1/ssh-keysign.8 2012-08-06 20:51:59.173033249 +0200 -@@ -78,6 +78,24 @@ must be set-uid root if host-based authe - If these files exist they are assumed to contain public certificate - information corresponding with the private keys above. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-keygen 1 , diff --git a/openssh/patches/openssh-6.1p1-akc.patch b/openssh/patches/openssh-6.1p1-akc.patch deleted file mode 100644 index 0401ba078..000000000 --- a/openssh/patches/openssh-6.1p1-akc.patch +++ /dev/null @@ -1,565 +0,0 @@ -diff -up openssh-6.1p1/auth2-pubkey.c.akc openssh-6.1p1/auth2-pubkey.c ---- openssh-6.1p1/auth2-pubkey.c.akc 2012-11-28 17:12:43.238524384 +0100 -+++ openssh-6.1p1/auth2-pubkey.c 2012-11-28 17:12:43.263524297 +0100 -@@ -27,9 +27,13 @@ - - #include - #include -+#include - -+#include - #include -+#include - #include -+#include - #include - #include - #include -@@ -260,7 +264,7 @@ match_principals_file(char *file, struct - if (strcmp(cp, cert->principals[i]) == 0) { - debug3("matched principal \"%.100s\" " - "from file \"%s\" on line %lu", -- cert->principals[i], file, linenum); -+ cert->principals[i], file, linenum); - if (auth_parse_options(pw, line_opts, - file, linenum) != 1) - continue; -@@ -273,31 +277,22 @@ match_principals_file(char *file, struct - fclose(f); - restore_uid(); - return 0; --} -+} - --/* return 1 if user allows given key */ -+/* -+ * Checks whether key is allowed in authorized_keys-format file, -+ * returns 1 if the key is allowed or 0 otherwise. -+ */ - static int --user_key_allowed2(struct passwd *pw, Key *key, char *file) -+check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) - { - char line[SSH_MAX_PUBKEY_BYTES]; - const char *reason; - int found_key = 0; -- FILE *f; - u_long linenum = 0; - Key *found; - char *fp; - -- /* Temporarily use the user's uid. */ -- temporarily_use_uid(pw); -- -- debug("trying public key file %s", file); -- f = auth_openkeyfile(file, pw, options.strict_modes); -- -- if (!f) { -- restore_uid(); -- return 0; -- } -- - found_key = 0; - found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); - -@@ -390,8 +385,6 @@ user_key_allowed2(struct passwd *pw, Key - break; - } - } -- restore_uid(); -- fclose(f); - key_free(found); - if (!found_key) - debug2("key not found"); -@@ -453,7 +446,173 @@ user_cert_trusted_ca(struct passwd *pw, - return ret; - } - --/* check whether given key is in .ssh/authorized_keys* */ -+/* -+ * Checks whether key is allowed in file. -+ * returns 1 if the key is allowed or 0 otherwise. -+ */ -+static int -+user_key_allowed2(struct passwd *pw, Key *key, char *file) -+{ -+ FILE *f; -+ int found_key = 0; -+ -+ /* Temporarily use the user's uid. */ -+ temporarily_use_uid(pw); -+ -+ debug("trying public key file %s", file); -+ if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) { -+ found_key = check_authkeys_file(f, file, key, pw); -+ fclose(f); -+ } -+ -+ restore_uid(); -+ return found_key; -+} -+ -+/* -+ * Checks whether key is allowed in output of command. -+ * returns 1 if the key is allowed or 0 otherwise. -+ */ -+static int -+user_key_command_allowed2(struct passwd *user_pw, Key *key) -+{ -+ FILE *f; -+ int ok, found_key = 0; -+ struct passwd *pw; -+ struct stat st; -+ int status, devnull, p[2], i; -+ pid_t pid; -+ char errmsg[512]; -+ -+ if (options.authorized_keys_command == NULL || -+ options.authorized_keys_command[0] != '/') -+ return 0; -+ -+ /* If no user specified to run commands the default to target user */ -+ if (options.authorized_keys_command_user == NULL) -+ pw = user_pw; -+ else { -+ pw = getpwnam(options.authorized_keys_command_user); -+ if (pw == NULL) { -+ error("AuthorizedKeyCommandUser \"%s\" not found: %s", -+ options.authorized_keys_command, strerror(errno)); -+ return 0; -+ } -+ } -+ -+ temporarily_use_uid(pw); -+ if (stat(options.authorized_keys_command, &st) < 0) { -+ error("Could not stat AuthorizedKeysCommand \"%s\": %s", -+ options.authorized_keys_command, strerror(errno)); -+ goto out; -+ } -+ -+ if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0, -+ errmsg, sizeof(errmsg)) != 0) { -+ error("Unsafe AuthorizedKeysCommand: %s", errmsg); -+ goto out; -+ } -+ -+ /* open the pipe and read the keys */ -+ if (pipe(p) != 0) { -+ error("%s: pipe: %s", __func__, strerror(errno)); -+ goto out; -+ } -+ -+ debug3("Running AuthorizedKeysCommand: \"%s\" as \"%s\"", -+ options.authorized_keys_command, pw->pw_name); -+ -+ /* -+ * Don't want to call this in the child, where it can fatal() and -+ * run cleanup_exit() code. -+ */ -+ restore_uid(); -+ -+ switch ((pid = fork())) { -+ case -1: /* error */ -+ error("%s: fork: %s", __func__, strerror(errno)); -+ close(p[0]); -+ close(p[1]); -+ return 0; -+ case 0: /* child */ -+ for (i = 0; i < NSIG; i++) -+ signal(i, SIG_DFL); -+ -+ /* Don't use permanently_set_uid() here to avoid fatal() */ -+ if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { -+ error("setresgid %u: %s", (u_int)pw->pw_gid, -+ strerror(errno)); -+ _exit(1); -+ } -+ if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) { -+ error("setresuid %u: %s", (u_int)pw->pw_uid, -+ strerror(errno)); -+ _exit(1); -+ } -+ -+ close(p[0]); -+ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { -+ error("%s: open %s: %s", __func__, _PATH_DEVNULL, -+ strerror(errno)); -+ _exit(1); -+ } -+ if (dup2(devnull, STDIN_FILENO) == -1 || -+ dup2(p[1], STDOUT_FILENO) == -1 || -+ dup2(devnull, STDERR_FILENO) == -1) { -+ error("%s: dup2: %s", __func__, strerror(errno)); -+ _exit(1); -+ } -+ closefrom(STDERR_FILENO + 1); -+ -+ execl(options.authorized_keys_command, -+ options.authorized_keys_command, pw->pw_name, NULL); -+ -+ error("AuthorizedKeysCommand %s exec failed: %s", -+ options.authorized_keys_command, strerror(errno)); -+ _exit(127); -+ default: /* parent */ -+ break; -+ } -+ -+ temporarily_use_uid(pw); -+ -+ close(p[1]); -+ if ((f = fdopen(p[0], "r")) == NULL) { -+ error("%s: fdopen: %s", __func__, strerror(errno)); -+ close(p[0]); -+ /* Don't leave zombie child */ -+ while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) -+ ; -+ goto out; -+ } -+ ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); -+ fclose(f); -+ -+ while (waitpid(pid, &status, 0) == -1) { -+ if (errno != EINTR) { -+ error("%s: waitpid: %s", __func__, strerror(errno)); -+ goto out; -+ } -+ } -+ if (WIFSIGNALED(status)) { -+ error("AuthorizedKeysCommand %s exited on signal %d", -+ options.authorized_keys_command, WTERMSIG(status)); -+ goto out; -+ } else if (WEXITSTATUS(status) != 0) { -+ error("AuthorizedKeysCommand %s returned status %d", -+ options.authorized_keys_command, WEXITSTATUS(status)); -+ goto out; -+ } -+ found_key = ok; -+ out: -+ restore_uid(); -+ -+ return found_key; -+} -+ -+/* -+ * Check whether key authenticates and authorises the user. -+ */ - int - user_key_allowed(struct passwd *pw, Key *key) - { -@@ -469,6 +628,10 @@ user_key_allowed(struct passwd *pw, Key - if (success) - return success; - -+ success = user_key_command_allowed2(pw, key); -+ if (success > 0) -+ return success; -+ - for (i = 0; !success && i < options.num_authkeys_files; i++) { - file = expand_authorized_keys( - options.authorized_keys_files[i], pw); -diff -up openssh-6.1p1/auth.c.akc openssh-6.1p1/auth.c ---- openssh-6.1p1/auth.c.akc 2012-11-28 17:12:43.187524558 +0100 -+++ openssh-6.1p1/auth.c 2012-11-28 17:12:43.263524297 +0100 -@@ -411,39 +411,41 @@ check_key_in_hostfiles(struct passwd *pw - - - /* -- * Check a given file for security. This is defined as all components -+ * Check a given path for security. This is defined as all components - * of the path to the file must be owned by either the owner of - * of the file or root and no directories must be group or world writable. - * - * XXX Should any specific check be done for sym links ? - * -- * Takes an open file descriptor, the file name, a uid and and -+ * Takes an the file name, its stat information (preferably from fstat() to -+ * avoid races), the uid of the expected owner, their home directory and an - * error buffer plus max size as arguments. - * - * Returns 0 on success and -1 on failure - */ --static int --secure_filename(FILE *f, const char *file, struct passwd *pw, -- char *err, size_t errlen) -+int -+auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, -+ uid_t uid, char *err, size_t errlen) - { -- uid_t uid = pw->pw_uid; - char buf[MAXPATHLEN], homedir[MAXPATHLEN]; - char *cp; - int comparehome = 0; - struct stat st; - -- if (realpath(file, buf) == NULL) { -- snprintf(err, errlen, "realpath %s failed: %s", file, -+ if (realpath(name, buf) == NULL) { -+ snprintf(err, errlen, "realpath %s failed: %s", name, - strerror(errno)); - return -1; - } -- if (realpath(pw->pw_dir, homedir) != NULL) -+ if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) - comparehome = 1; - -- /* check the open file to avoid races */ -- if (fstat(fileno(f), &st) < 0 || -- (st.st_uid != 0 && st.st_uid != uid) || -- (st.st_mode & 022) != 0) { -+ if (!S_ISREG(stp->st_mode)) { -+ snprintf(err, errlen, "%s is not a regular file", buf); -+ return -1; -+ } -+ if ((stp->st_uid != 0 && stp->st_uid != uid) || -+ (stp->st_mode & 022) != 0) { - snprintf(err, errlen, "bad ownership or modes for file %s", - buf); - return -1; -@@ -479,6 +481,31 @@ secure_filename(FILE *f, const char *fil - return 0; - } - -+/* -+ * Version of secure_path() that accepts an open file descriptor to -+ * avoid races. -+ * -+ * Returns 0 on success and -1 on failure -+ */ -+static int -+secure_filename(FILE *f, const char *file, struct passwd *pw, -+ char *err, size_t errlen) -+{ -+ uid_t uid = pw->pw_uid; -+ char buf[MAXPATHLEN], homedir[MAXPATHLEN]; -+ char *cp; -+ int comparehome = 0; -+ struct stat st; -+ -+ /* check the open file to avoid races */ -+ if (fstat(fileno(f), &st) < 0) { -+ snprintf(err, errlen, "cannot stat file %s: %s", -+ buf, strerror(errno)); -+ return -1; -+ } -+ return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); -+} -+ - static FILE * - auth_openfile(const char *file, struct passwd *pw, int strict_modes, - int log_missing, char *file_type) -diff -up openssh-6.1p1/auth.h.akc openssh-6.1p1/auth.h ---- openssh-6.1p1/auth.h.akc 2012-11-28 17:12:43.239524381 +0100 -+++ openssh-6.1p1/auth.h 2012-11-28 17:12:43.263524297 +0100 -@@ -125,6 +125,10 @@ int auth_rhosts_rsa_key_allowed(struct - int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); - int user_key_allowed(struct passwd *, Key *); - -+struct stat; -+int auth_secure_path(const char *, struct stat *, const char *, uid_t, -+ char *, size_t); -+ - #ifdef KRB5 - int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); - int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); -diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c ---- openssh-6.1p1/servconf.c.akc 2012-11-28 17:12:43.198524521 +0100 -+++ openssh-6.1p1/servconf.c 2012-11-28 17:14:50.314005026 +0100 -@@ -137,6 +137,8 @@ initialize_server_options(ServerOptions - options->num_permitted_opens = -1; - options->adm_forced_command = NULL; - options->chroot_directory = NULL; -+ options->authorized_keys_command = NULL; -+ options->authorized_keys_command_user = NULL; - options->zero_knowledge_password_authentication = -1; - options->revoked_keys_file = NULL; - options->trusted_user_ca_keys = NULL; -@@ -331,6 +333,7 @@ typedef enum { - sZeroKnowledgePasswordAuthentication, sHostCertificate, - sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, - sKexAlgorithms, sIPQoS, sVersionAddendum, -+ sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, - sAuthenticationMethods, - sDeprecated, sUnsupported - } ServerOpCodes; -@@ -457,6 +460,9 @@ static struct { - { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, - { "ipqos", sIPQoS, SSHCFG_ALL }, - { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, -+ { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, -+ { "authorizedkeyscommandrunas", sAuthorizedKeysCommandUser, SSHCFG_ALL }, -+ { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, - { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, - { NULL, sBadOption, 0 } - }; -@@ -1520,6 +1526,26 @@ process_server_config_line(ServerOptions - } - return 0; - -+ case sAuthorizedKeysCommand: -+ len = strspn(cp, WHITESPACE); -+ if (*activep && options->authorized_keys_command == NULL) { -+ options->authorized_keys_command = xstrdup(cp + len); -+ if (*options->authorized_keys_command != '/') { -+ fatal("%.200s line %d: AuthorizedKeysCommand " -+ "must be an absolute path", -+ filename, linenum); -+ } -+ } -+ return 0; -+ -+ case sAuthorizedKeysCommandUser: -+ charptr = &options->authorized_keys_command_user; -+ -+ arg = strdelim(&cp); -+ if (*activep && *charptr == NULL) -+ *charptr = xstrdup(arg); -+ break; -+ - case sDeprecated: - logit("%s line %d: Deprecated option %s", - filename, linenum, arg); -@@ -1670,6 +1696,8 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(hostbased_uses_name_from_packet_only); - M_CP_INTOPT(kbd_interactive_authentication); - M_CP_INTOPT(zero_knowledge_password_authentication); -+ M_CP_STROPT(authorized_keys_command); -+ M_CP_STROPT(authorized_keys_command_user); - M_CP_INTOPT(permit_root_login); - M_CP_INTOPT(permit_empty_passwd); - -@@ -1930,6 +1958,8 @@ dump_config(ServerOptions *o) - dump_cfg_string(sAuthorizedPrincipalsFile, - o->authorized_principals_file); - dump_cfg_string(sVersionAddendum, o->version_addendum); -+ dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); -+ dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); - - /* string arguments requiring a lookup */ - dump_cfg_string(sLogLevel, log_level_name(o->log_level)); -diff -up openssh-6.1p1/servconf.h.akc openssh-6.1p1/servconf.h ---- openssh-6.1p1/servconf.h.akc 2012-11-28 17:12:43.000000000 +0100 -+++ openssh-6.1p1/servconf.h 2012-11-28 17:18:41.217055157 +0100 -@@ -167,6 +167,8 @@ typedef struct { - char *revoked_keys_file; - char *trusted_user_ca_keys; - char *authorized_principals_file; -+ char *authorized_keys_command; -+ char *authorized_keys_command_user; - - char *version_addendum; /* Appended to SSH banner */ - -diff -up openssh-6.1p1/sshd.c.akc openssh-6.1p1/sshd.c ---- openssh-6.1p1/sshd.c.akc 2012-11-28 17:12:43.245524360 +0100 -+++ openssh-6.1p1/sshd.c 2012-11-28 17:12:43.265524291 +0100 -@@ -366,9 +366,20 @@ main_sigchld_handler(int sig) - static void - grace_alarm_handler(int sig) - { -+ pid_t pgid; -+ - if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0) - kill(pmonitor->m_pid, SIGALRM); - -+ /* -+ * Try to kill any processes that we have spawned, E.g. authorized -+ * keys command helpers. -+ */ -+ if ((pgid = getpgid(0)) == getpid()) { -+ signal(SIGTERM, SIG_IGN); -+ killpg(pgid, SIGTERM); -+ } -+ - /* Log error and exit. */ - sigdie("Timeout before authentication for %s", get_remote_ipaddr()); - } -diff -up openssh-6.1p1/sshd_config.0.akc openssh-6.1p1/sshd_config.0 ---- openssh-6.1p1/sshd_config.0.akc 2012-08-29 02:53:04.000000000 +0200 -+++ openssh-6.1p1/sshd_config.0 2012-11-28 17:12:43.265524291 +0100 -@@ -71,6 +71,23 @@ DESCRIPTION - - See PATTERNS in ssh_config(5) for more information on patterns. - -+ AuthorizedKeysCommand -+ -+ Specifies a program to be used for lookup of the user's -+ public keys. The program will be invoked with its first -+ argument the name of the user being authorized, and should produce -+ on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS -+ in sshd(8)). By default (or when set to the empty string) there is no -+ AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully -+ authorize the user, authorization falls through to the -+ AuthorizedKeysFile. Note that this option has an effect -+ only with PubkeyAuthentication turned on. -+ -+ AuthorizedKeysCommandRunAs -+ Specifies the user under whose account the AuthorizedKeysCommand is run. -+ Empty string (the default value) means the user being authorized -+ is used. -+ - AuthorizedKeysFile - Specifies the file that contains the public keys that can be used - for user authentication. The format is described in the -@@ -402,7 +419,8 @@ DESCRIPTION - Only a subset of keywords may be used on the lines following a - Match keyword. Available keywords are AcceptEnv, - AllowAgentForwarding, AllowGroups, AllowTcpForwarding, -- AllowUsers, AuthorizedKeysFile, AuthorizedPrincipalsFile, Banner, -+ AllowUsers, AuthorizedKeysFile, AuthorizedKeysCommand, -+ AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile, Banner, - ChrootDirectory, DenyGroups, DenyUsers, ForceCommand, - GatewayPorts, GSSAPIAuthentication, HostbasedAuthentication, - HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication, -diff -up openssh-6.1p1/sshd_config.5.akc openssh-6.1p1/sshd_config.5 ---- openssh-6.1p1/sshd_config.5.akc 2012-11-28 17:12:43.199524517 +0100 -+++ openssh-6.1p1/sshd_config.5 2012-11-28 17:16:23.736624980 +0100 -@@ -173,6 +173,20 @@ Note that each authentication method lis - in the configuration. - The default is not to require multiple authentication; successful completion - of a single authentication method is sufficient. -+.It Cm AuthorizedKeysCommand -+Specifies a program to be used for lookup of the user's public keys. -+The program will be invoked with a single argument of the username -+being authenticated, and should produce on standard output zero or -+more lines of authorized_keys output (see AUTHORIZED_KEYS in -+.Xr sshd 8 ) -+If a key supplied by AuthorizedKeysCommand does not successfully authenticate -+and authorize the user then public key authentication continues using the usual -+.Cm AuthorizedKeysFile -+files. -+By default, no AuthorizedKeysCommand is run. -+.It Cm AuthorizedKeysCommandUser -+Specifies the user under whose account the AuthorizedKeysCommand is run. -+The default is the user being authenticated. - .It Cm AuthorizedKeysFile - Specifies the file that contains the public keys that can be used - for user authentication. -@@ -734,6 +748,8 @@ Available keywords are - .Cm AllowTcpForwarding , - .Cm AllowUsers , - .Cm AuthenticationMethods , -+.Cm AuthorizedKeysCommand , -+.Cm AuthorizedKeysCommandUser , - .Cm AuthorizedKeysFile , - .Cm AuthorizedPrincipalsFile , - .Cm Banner , -@@ -749,6 +765,7 @@ Available keywords are - .Cm KerberosAuthentication , - .Cm MaxAuthTries , - .Cm MaxSessions , -+.Cm PubkeyAuthentication , - .Cm PasswordAuthentication , - .Cm PermitEmptyPasswords , - .Cm PermitOpen , -diff -up openssh-6.1p1/sshd_config.akc openssh-6.1p1/sshd_config ---- openssh-6.1p1/sshd_config.akc 2012-07-31 04:21:34.000000000 +0200 -+++ openssh-6.1p1/sshd_config 2012-11-28 17:12:43.265524291 +0100 -@@ -49,6 +49,9 @@ - # but this is overridden so installations will only check .ssh/authorized_keys - AuthorizedKeysFile .ssh/authorized_keys - -+#AuthorizedKeysCommand none -+#AuthorizedKeysCommandUser nobody -+ - #AuthorizedPrincipalsFile none - - # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts diff --git a/openssh/patches/openssh-6.1p1-askpass-ld.patch b/openssh/patches/openssh-6.1p1-askpass-ld.patch deleted file mode 100644 index f7a7facb3..000000000 --- a/openssh/patches/openssh-6.1p1-askpass-ld.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -up openssh-6.1p1/contrib/Makefile.askpass-ld openssh-6.1p1/contrib/Makefile ---- openssh-6.1p1/contrib/Makefile.askpass-ld 2012-05-19 07:24:37.000000000 +0200 -+++ openssh-6.1p1/contrib/Makefile 2012-09-14 20:35:47.565704718 +0200 -@@ -4,12 +4,12 @@ all: - @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" - - gnome-ssh-askpass1: gnome-ssh-askpass1.c -- $(CC) `gnome-config --cflags gnome gnomeui` \ -+ $(CC) ${CFLAGS} `gnome-config --cflags gnome gnomeui` \ - gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \ - `gnome-config --libs gnome gnomeui` - - gnome-ssh-askpass2: gnome-ssh-askpass2.c -- $(CC) `$(PKG_CONFIG) --cflags gtk+-2.0` \ -+ $(CC) ${CFLAGS} `$(PKG_CONFIG) --cflags gtk+-2.0` \ - gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ - `$(PKG_CONFIG) --libs gtk+-2.0 x11` - diff --git a/openssh/patches/openssh-6.1p1-authenticationmethods.patch b/openssh/patches/openssh-6.1p1-authenticationmethods.patch deleted file mode 100644 index 7b5a06a34..000000000 --- a/openssh/patches/openssh-6.1p1-authenticationmethods.patch +++ /dev/null @@ -1,841 +0,0 @@ -diff --git a/auth.c b/auth.c -index ee0cb05..1b2fc2b 100644 ---- a/auth.c -+++ b/auth.c -@@ -251,7 +251,8 @@ allowed_user(struct passwd * pw) - } - - void --auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) -+auth_log(Authctxt *authctxt, int authenticated, int partial, -+ const char *method, const char *submethod, const char *info) - { - void (*authlog) (const char *fmt,...) = verbose; - char *authmsg; -@@ -268,12 +269,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) - - if (authctxt->postponed) - authmsg = "Postponed"; -+ else if (partial) -+ authmsg = "Partial"; - else - authmsg = authenticated ? "Accepted" : "Failed"; - -- authlog("%s %s for %s%.100s from %.200s port %d%s", -+ authlog("%s %s%s%s for %s%.100s from %.200s port %d%s", - authmsg, - method, -+ submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, - authctxt->valid ? "" : "invalid user ", - authctxt->user, - get_remote_ipaddr(), -@@ -303,7 +307,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) - * Check whether root logins are disallowed. - */ - int --auth_root_allowed(char *method) -+auth_root_allowed(const char *method) - { - switch (options.permit_root_login) { - case PERMIT_YES: -diff --git a/auth.h b/auth.h -index 0d786c4..29823bb 100644 ---- a/auth.h -+++ b/auth.h -@@ -64,6 +64,8 @@ struct Authctxt { - #ifdef BSD_AUTH - auth_session_t *as; - #endif -+ char **auth_methods; /* modified from server config */ -+ u_int num_auth_methods; - #ifdef KRB5 - krb5_context krb5_ctx; - krb5_ccache krb5_fwd_ccache; -@@ -142,12 +144,17 @@ void disable_forwarding(void); - void do_authentication(Authctxt *); - void do_authentication2(Authctxt *); - --void auth_log(Authctxt *, int, char *, char *); --void userauth_finish(Authctxt *, int, char *); -+void auth_log(Authctxt *, int, int, const char *, const char *, -+ const char *); -+void userauth_finish(Authctxt *, int, const char *, const char *); -+int auth_root_allowed(const char *); -+ - void userauth_send_banner(const char *); --int auth_root_allowed(char *); - - char *auth2_read_banner(void); -+int auth2_methods_valid(const char *, int); -+int auth2_update_methods_lists(Authctxt *, const char *); -+int auth2_setup_methods_lists(Authctxt *); - - void privsep_challenge_enable(void); - -diff --git a/auth1.c b/auth1.c -index cc85aec..458a110 100644 ---- a/auth1.c -+++ b/auth1.c -@@ -253,7 +253,8 @@ do_authloop(Authctxt *authctxt) - if (options.use_pam && (PRIVSEP(do_pam_account()))) - #endif - { -- auth_log(authctxt, 1, "without authentication", ""); -+ auth_log(authctxt, 1, 0, "without authentication", -+ NULL, ""); - return; - } - } -@@ -352,7 +353,8 @@ do_authloop(Authctxt *authctxt) - - skip: - /* Log before sending the reply */ -- auth_log(authctxt, authenticated, get_authname(type), info); -+ auth_log(authctxt, authenticated, 0, get_authname(type), -+ NULL, info); - - if (client_user != NULL) { - xfree(client_user); -@@ -406,6 +408,11 @@ do_authentication(Authctxt *authctxt) - authctxt->pw = fakepw(); - } - -+ /* Configuration may have changed as a result of Match */ -+ if (options.num_auth_methods != 0) -+ fatal("AuthenticationMethods is not supported with SSH " -+ "protocol 1"); -+ - setproctitle("%s%s", authctxt->valid ? user : "unknown", - use_privsep ? " [net]" : ""); - -diff --git a/auth2-chall.c b/auth2-chall.c -index e6dbffe..5f7ec6d 100644 ---- a/auth2-chall.c -+++ b/auth2-chall.c -@@ -283,7 +283,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) - KbdintAuthctxt *kbdintctxt; - int authenticated = 0, res; - u_int i, nresp; -- char **response = NULL, *method; -+ char *devicename = NULL, **response = NULL; - - if (authctxt == NULL) - fatal("input_userauth_info_response: no authctxt"); -@@ -329,9 +329,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) - /* Failure! */ - break; - } -- -- xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name); -- -+ devicename = kbdintctxt->device->name; - if (!authctxt->postponed) { - if (authenticated) { - auth2_challenge_stop(authctxt); -@@ -341,8 +339,8 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) - auth2_challenge_start(authctxt); - } - } -- userauth_finish(authctxt, authenticated, method); -- xfree(method); -+ userauth_finish(authctxt, authenticated, "keyboard-interactive", -+ devicename); - } - - void -diff --git a/auth2-gss.c b/auth2-gss.c -index 0d59b21..338c748 100644 ---- a/auth2-gss.c -+++ b/auth2-gss.c -@@ -163,7 +163,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt) - } - authctxt->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -- userauth_finish(authctxt, 0, "gssapi-with-mic"); -+ userauth_finish(authctxt, 0, "gssapi-with-mic", NULL); - } else { - if (send_tok.length != 0) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); -@@ -251,7 +251,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); -- userauth_finish(authctxt, authenticated, "gssapi-with-mic"); -+ userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); - } - - static void -@@ -291,7 +291,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); -- userauth_finish(authctxt, authenticated, "gssapi-with-mic"); -+ userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); - } - - Authmethod method_gssapi = { -diff --git a/auth2-jpake.c b/auth2-jpake.c -index a460e82..e4ba9aa 100644 ---- a/auth2-jpake.c -+++ b/auth2-jpake.c -@@ -556,7 +556,7 @@ input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt) - authctxt->postponed = 0; - jpake_free(authctxt->jpake_ctx); - authctxt->jpake_ctx = NULL; -- userauth_finish(authctxt, authenticated, method_jpake.name); -+ userauth_finish(authctxt, authenticated, method_jpake.name, NULL); - } - - #endif /* JPAKE */ -diff --git a/auth2.c b/auth2.c -index b66bef6..ea0fd92 100644 ---- a/auth2.c -+++ b/auth2.c -@@ -96,8 +96,10 @@ static void input_service_request(int, u_int32_t, void *); - static void input_userauth_request(int, u_int32_t, void *); - - /* helper */ --static Authmethod *authmethod_lookup(const char *); --static char *authmethods_get(void); -+static Authmethod *authmethod_lookup(Authctxt *, const char *); -+static char *authmethods_get(Authctxt *authctxt); -+static int method_allowed(Authctxt *, const char *); -+static int list_starts_with(const char *, const char *); - - char * - auth2_read_banner(void) -@@ -255,6 +257,8 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) - if (use_privsep) - mm_inform_authserv(service, style); - userauth_banner(); -+ if (auth2_setup_methods_lists(authctxt) != 0) -+ packet_disconnect("no authentication methods enabled"); - } else if (strcmp(user, authctxt->user) != 0 || - strcmp(service, authctxt->service) != 0) { - packet_disconnect("Change of username or service not allowed: " -@@ -277,12 +281,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) - authctxt->server_caused_failure = 0; - - /* try to authenticate user */ -- m = authmethod_lookup(method); -+ m = authmethod_lookup(authctxt, method); - if (m != NULL && authctxt->failures < options.max_authtries) { - debug2("input_userauth_request: try method %s", method); - authenticated = m->userauth(authctxt); - } -- userauth_finish(authctxt, authenticated, method); -+ userauth_finish(authctxt, authenticated, method, NULL); - - xfree(service); - xfree(user); -@@ -290,13 +294,17 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) - } - - void --userauth_finish(Authctxt *authctxt, int authenticated, char *method) -+userauth_finish(Authctxt *authctxt, int authenticated, const char *method, -+ const char *submethod) - { - char *methods; -+ int partial = 0; - - if (!authctxt->valid && authenticated) - fatal("INTERNAL ERROR: authenticated invalid user %s", - authctxt->user); -+ if (authenticated && authctxt->postponed) -+ fatal("INTERNAL ERROR: authenticated and postponed"); - - /* Special handling for root */ - if (authenticated && authctxt->pw->pw_uid == 0 && -@@ -307,6 +315,19 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) - #endif - } - -+ if (authenticated && options.num_auth_methods != 0) { -+ if (!auth2_update_methods_lists(authctxt, method)) { -+ authenticated = 0; -+ partial = 1; -+ } -+ } -+ -+ /* Log before sending the reply */ -+ auth_log(authctxt, authenticated, partial, method, submethod, " ssh2"); -+ -+ if (authctxt->postponed) -+ return; -+ - #ifdef USE_PAM - if (options.use_pam && authenticated) { - if (!PRIVSEP(do_pam_account())) { -@@ -325,17 +346,10 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) - #ifdef _UNICOS - if (authenticated && cray_access_denied(authctxt->user)) { - authenticated = 0; -- fatal("Access denied for user %s.",authctxt->user); -+ fatal("Access denied for user %s.", authctxt->user); - } - #endif /* _UNICOS */ - -- /* Log before sending the reply */ -- auth_log(authctxt, authenticated, method, " ssh2"); -- -- if (authctxt->postponed) -- return; -- -- /* XXX todo: check if multiple auth methods are needed */ - if (authenticated == 1) { - /* turn off userauth */ - dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); -@@ -348,7 +362,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) - - /* Allow initial try of "none" auth without failure penalty */ - if (!authctxt->server_caused_failure && -- (authctxt->attempt > 1 || strcmp(method, "none") != 0)) -+ (authctxt->attempt > 1 || strcmp(method, "none") != 0) && -+ partial == 0) - authctxt->failures++; - if (authctxt->failures >= options.max_authtries) { - #ifdef SSH_AUDIT_EVENTS -@@ -356,34 +371,61 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) - #endif - packet_disconnect(AUTH_FAIL_MSG, authctxt->user); - } -- methods = authmethods_get(); -+ methods = authmethods_get(authctxt); -+ debug3("%s: failure partial=%d next methods=\"%s\"", __func__, -+ partial, methods); - packet_start(SSH2_MSG_USERAUTH_FAILURE); - packet_put_cstring(methods); -- packet_put_char(0); /* XXX partial success, unused */ -+ packet_put_char(partial); - packet_send(); - packet_write_wait(); - xfree(methods); - } - } - -+/* -+ * Checks whether method is allowed by at least one AuthenticationMethods -+ * methods list. Returns 1 if allowed, or no methods lists configured. -+ * 0 otherwise. -+ */ -+static int -+method_allowed(Authctxt *authctxt, const char *method) -+{ -+ u_int i; -+ -+ /* -+ * NB. authctxt->num_auth_methods might be zero as a result of -+ * auth2_setup_methods_lists(), so check the configuration. -+ */ -+ if (options.num_auth_methods == 0) -+ return 1; -+ for (i = 0; i < authctxt->num_auth_methods; i++) { -+ if (list_starts_with(authctxt->auth_methods[i], method)) -+ return 1; -+ } -+ return 0; -+} -+ - static char * --authmethods_get(void) -+authmethods_get(Authctxt *authctxt) - { - Buffer b; - char *list; -- int i; -+ u_int i; - - buffer_init(&b); - for (i = 0; authmethods[i] != NULL; i++) { - if (strcmp(authmethods[i]->name, "none") == 0) - continue; -- if (authmethods[i]->enabled != NULL && -- *(authmethods[i]->enabled) != 0) { -- if (buffer_len(&b) > 0) -- buffer_append(&b, ",", 1); -- buffer_append(&b, authmethods[i]->name, -- strlen(authmethods[i]->name)); -- } -+ if (authmethods[i]->enabled == NULL || -+ *(authmethods[i]->enabled) == 0) -+ continue; -+ if (!method_allowed(authctxt, authmethods[i]->name)) -+ continue; -+ if (buffer_len(&b) > 0) -+ buffer_append(&b, ",", 1); -+ buffer_append(&b, authmethods[i]->name, -+ strlen(authmethods[i]->name)); - } - buffer_append(&b, "\0", 1); - list = xstrdup(buffer_ptr(&b)); -@@ -392,7 +434,7 @@ authmethods_get(void) - } - - static Authmethod * --authmethod_lookup(const char *name) -+authmethod_lookup(Authctxt *authctxt, const char *name) - { - int i; - -@@ -400,10 +442,152 @@ authmethod_lookup(const char *name) - for (i = 0; authmethods[i] != NULL; i++) - if (authmethods[i]->enabled != NULL && - *(authmethods[i]->enabled) != 0 && -- strcmp(name, authmethods[i]->name) == 0) -+ strcmp(name, authmethods[i]->name) == 0 && -+ method_allowed(authctxt, authmethods[i]->name)) - return authmethods[i]; - debug2("Unrecognized authentication method name: %s", - name ? name : "NULL"); - return NULL; - } - -+/* -+ * Check a comma-separated list of methods for validity. Is need_enable is -+ * non-zero, then also require that the methods are enabled. -+ * Returns 0 on success or -1 if the methods list is invalid. -+ */ -+int -+auth2_methods_valid(const char *_methods, int need_enable) -+{ -+ char *methods, *omethods, *method; -+ u_int i, found; -+ int ret = -1; -+ -+ if (*_methods == '\0') { -+ error("empty authentication method list"); -+ return -1; -+ } -+ omethods = methods = xstrdup(_methods); -+ while ((method = strsep(&methods, ",")) != NULL) { -+ for (found = i = 0; !found && authmethods[i] != NULL; i++) { -+ if (strcmp(method, authmethods[i]->name) != 0) -+ continue; -+ if (need_enable) { -+ if (authmethods[i]->enabled == NULL || -+ *(authmethods[i]->enabled) == 0) { -+ error("Disabled method \"%s\" in " -+ "AuthenticationMethods list \"%s\"", -+ method, _methods); -+ goto out; -+ } -+ } -+ found = 1; -+ break; -+ } -+ if (!found) { -+ error("Unknown authentication method \"%s\" in list", -+ method); -+ goto out; -+ } -+ } -+ ret = 0; -+ out: -+ free(omethods); -+ return ret; -+} -+ -+/* -+ * Prune the AuthenticationMethods supplied in the configuration, removing -+ * any methods lists that include disabled methods. Note that this might -+ * leave authctxt->num_auth_methods == 0, even when multiple required auth -+ * has been requested. For this reason, all tests for whether multiple is -+ * enabled should consult options.num_auth_methods directly. -+ */ -+int -+auth2_setup_methods_lists(Authctxt *authctxt) -+{ -+ u_int i; -+ -+ if (options.num_auth_methods == 0) -+ return 0; -+ debug3("%s: checking methods", __func__); -+ authctxt->auth_methods = xcalloc(options.num_auth_methods, -+ sizeof(*authctxt->auth_methods)); -+ authctxt->num_auth_methods = 0; -+ for (i = 0; i < options.num_auth_methods; i++) { -+ if (auth2_methods_valid(options.auth_methods[i], 1) != 0) { -+ logit("Authentication methods list \"%s\" contains " -+ "disabled method, skipping", -+ options.auth_methods[i]); -+ continue; -+ } -+ debug("authentication methods list %d: %s", -+ authctxt->num_auth_methods, options.auth_methods[i]); -+ authctxt->auth_methods[authctxt->num_auth_methods++] = -+ xstrdup(options.auth_methods[i]); -+ } -+ if (authctxt->num_auth_methods == 0) { -+ error("No AuthenticationMethods left after eliminating " -+ "disabled methods"); -+ return -1; -+ } -+ return 0; -+} -+ -+static int -+list_starts_with(const char *methods, const char *method) -+{ -+ size_t l = strlen(method); -+ -+ if (strncmp(methods, method, l) != 0) -+ return 0; -+ if (methods[l] != ',' && methods[l] != '\0') -+ return 0; -+ return 1; -+} -+ -+/* -+ * Remove method from the start of a comma-separated list of methods. -+ * Returns 0 if the list of methods did not start with that method or 1 -+ * if it did. -+ */ -+static int -+remove_method(char **methods, const char *method) -+{ -+ char *omethods = *methods; -+ size_t l = strlen(method); -+ -+ if (!list_starts_with(omethods, method)) -+ return 0; -+ *methods = xstrdup(omethods + l + (omethods[l] == ',' ? 1 : 0)); -+ free(omethods); -+ return 1; -+} -+ -+/* -+ * Called after successful authentication. Will remove the successful method -+ * from the start of each list in which it occurs. If it was the last method -+ * in any list, then authentication is deemed successful. -+ * Returns 1 if the method completed any authentication list or 0 otherwise. -+ */ -+int -+auth2_update_methods_lists(Authctxt *authctxt, const char *method) -+{ -+ u_int i, found = 0; -+ -+ debug3("%s: updating methods list after \"%s\"", __func__, method); -+ for (i = 0; i < authctxt->num_auth_methods; i++) { -+ if (!remove_method(&(authctxt->auth_methods[i]), method)) -+ continue; -+ found = 1; -+ if (*authctxt->auth_methods[i] == '\0') { -+ debug2("authentication methods list %d complete", i); -+ return 1; -+ } -+ debug3("authentication methods list %d remaining: \"%s\"", -+ i, authctxt->auth_methods[i]); -+ } -+ /* This should not happen, but would be bad if it did */ -+ if (!found) -+ fatal("%s: method not in AuthenticationMethods", __func__); -+ return 0; -+} -diff --git a/monitor.c b/monitor.c -index 1dc42f5..66f3eea 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -199,6 +199,7 @@ static int key_blobtype = MM_NOKEY; - static char *hostbased_cuser = NULL; - static char *hostbased_chost = NULL; - static char *auth_method = "unknown"; -+static char *auth_submethod = NULL; - static u_int session_id2_len = 0; - static u_char *session_id2 = NULL; - static pid_t monitor_child_pid; -@@ -352,7 +353,7 @@ void - monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) - { - struct mon_table *ent; -- int authenticated = 0; -+ int authenticated = 0, partial = 0; - - debug3("preauth child monitor started"); - -@@ -379,8 +380,26 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) - - /* The first few requests do not require asynchronous access */ - while (!authenticated) { -+ partial = 0; - auth_method = "unknown"; -+ auth_submethod = NULL; - authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); -+ -+ /* Special handling for multiple required authentications */ -+ if (options.num_auth_methods != 0) { -+ if (!compat20) -+ fatal("AuthenticationMethods is not supported" -+ "with SSH protocol 1"); -+ if (authenticated && -+ !auth2_update_methods_lists(authctxt, -+ auth_method)) { -+ debug3("%s: method %s: partial", __func__, -+ auth_method); -+ authenticated = 0; -+ partial = 1; -+ } -+ } -+ - if (authenticated) { - if (!(ent->flags & MON_AUTHDECIDE)) - fatal("%s: unexpected authentication from %d", -@@ -403,9 +422,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) - } - - if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { -- auth_log(authctxt, authenticated, auth_method, -+ auth_log(authctxt, authenticated, partial, -+ auth_method, auth_submethod, - compat20 ? " ssh2" : ""); -- if (!authenticated) -+ if (!authenticated && !partial) - authctxt->failures++; - } - #ifdef JPAKE -@@ -781,7 +801,17 @@ mm_answer_pwnamallow(int sock, Buffer *m) - COPY_MATCH_STRING_OPTS(); - #undef M_CP_STROPT - #undef M_CP_STRARRAYOPT -- -+ -+ /* Create valid auth method lists */ -+ if (compat20 && auth2_setup_methods_lists(authctxt) != 0) { -+ /* -+ * The monitor will continue long enough to let the child -+ * run to it's packet_disconnect(), but it must not allow any -+ * authentication to succeed. -+ */ -+ debug("%s: no valid authentication method lists", __func__); -+ } -+ - debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); - mm_request_send(sock, MONITOR_ANS_PWNAM, m); - -@@ -918,7 +948,11 @@ mm_answer_bsdauthrespond(int sock, Buffer *m) - debug3("%s: sending authenticated: %d", __func__, authok); - mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); - -- auth_method = "bsdauth"; -+ if (compat20) -+ auth_method = "keyboard-interactive"; /* XXX auth_submethod */ -+ else -+ auth_method = "bsdauth"; -+ - - return (authok != 0); - } -@@ -1057,7 +1091,9 @@ mm_answer_pam_query(int sock, Buffer *m) - xfree(prompts); - if (echo_on != NULL) - xfree(echo_on); -- auth_method = "keyboard-interactive/pam"; -+ auth_method = "keyboard-interactive"; -+ auth_submethod = "pam"; -+ - mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); - return (0); - } -@@ -1086,7 +1122,8 @@ mm_answer_pam_respond(int sock, Buffer *m) - buffer_clear(m); - buffer_put_int(m, ret); - mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); -- auth_method = "keyboard-interactive/pam"; -+ auth_method = "keyboard-interactive"; -+ auth_submethod= "pam"; - if (ret == 0) - sshpam_authok = sshpam_ctxt; - return (0); -@@ -1100,7 +1137,8 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) - (sshpam_device.free_ctx)(sshpam_ctxt); - buffer_clear(m); - mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); -- auth_method = "keyboard-interactive/pam"; -+ auth_method = "keyboard-interactive"; -+ auth_submethod = "pam"; - return (sshpam_authok == sshpam_ctxt); - } - #endif -@@ -1178,7 +1216,8 @@ mm_answer_keyallowed(int sock, Buffer *m) - hostbased_chost = chost; - } else { - /* Log failed attempt */ -- auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : ""); -+ auth_log(authctxt, 0, 0, auth_method, NULL, -+ compat20 ? " ssh2" : ""); - xfree(blob); - xfree(cuser); - xfree(chost); -diff --git a/servconf.c b/servconf.c -index 906778f..2c84993 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -48,6 +48,8 @@ - #include "groupaccess.h" - #include "canohost.h" - #include "packet.h" -+#include "hostfile.h" -+#include "auth.h" - - static void add_listen_addr(ServerOptions *, char *, int); - static void add_one_listen_addr(ServerOptions *, char *, int); -@@ -329,6 +331,7 @@ typedef enum { - sZeroKnowledgePasswordAuthentication, sHostCertificate, - sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, - sKexAlgorithms, sIPQoS, sVersionAddendum, -+ sAuthenticationMethods, - sDeprecated, sUnsupported - } ServerOpCodes; - -@@ -454,6 +457,7 @@ static struct { - { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, - { "ipqos", sIPQoS, SSHCFG_ALL }, - { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, -+ { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, - { NULL, sBadOption, 0 } - }; - -@@ -1498,6 +1502,24 @@ process_server_config_line(ServerOptions *options, char *line, - } - return 0; - -+ case sAuthenticationMethods: -+ if (*activep && options->num_auth_methods == 0) { -+ while ((arg = strdelim(&cp)) && *arg != '\0') { -+ if (options->num_auth_methods >= -+ MAX_AUTH_METHODS) -+ fatal("%s line %d: " -+ "too many authentication methods.", -+ filename, linenum); -+ if (auth2_methods_valid(arg, 0) != 0) -+ fatal("%s line %d: invalid " -+ "authentication method list.", -+ filename, linenum); -+ options->auth_methods[ -+ options->num_auth_methods++] = xstrdup(arg); -+ } -+ } -+ return 0; -+ - case sDeprecated: - logit("%s line %d: Deprecated option %s", - filename, linenum, arg); -@@ -1925,6 +1947,8 @@ dump_config(ServerOptions *o) - dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); - dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); - dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); -+ dump_cfg_strarray_oneline(sAuthenticationMethods, -+ o->num_auth_methods, o->auth_methods); - - /* other arguments */ - for (i = 0; i < o->num_subsystems; i++) -diff --git a/servconf.h b/servconf.h -index 096d596..ef80eef 100644 ---- a/servconf.h -+++ b/servconf.h -@@ -28,6 +28,7 @@ - #define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ - #define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */ - #define MAX_AUTHKEYS_FILES 256 /* Max # of authorized_keys files. */ -+#define MAX_AUTH_METHODS 256 /* Max # of AuthenticationMethods. */ - - /* permit_root_login */ - #define PERMIT_NOT_SET -1 -@@ -168,6 +169,9 @@ typedef struct { - char *authorized_principals_file; - - char *version_addendum; /* Appended to SSH banner */ -+ -+ u_int num_auth_methods; -+ char *auth_methods[MAX_AUTH_METHODS]; - } ServerOptions; - - /* Information about the incoming connection as used by Match */ -@@ -197,6 +201,7 @@ struct connection_info { - M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \ - M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \ - M_CP_STRARRAYOPT(accept_env, num_accept_env); \ -+ M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \ - } while (0) - - struct connection_info *get_connection_info(int, int); -diff --git a/sshd.c b/sshd.c -index d5ec4e6..cb4bdd3 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -1333,6 +1333,7 @@ main(int ac, char **av) - int remote_port; - char *line; - int config_s[2] = { -1 , -1 }; -+ u_int n; - u_int64_t ibytes, obytes; - mode_t new_umask; - Key *key; -@@ -1555,6 +1556,26 @@ main(int ac, char **av) - if (options.challenge_response_authentication) - options.kbd_interactive_authentication = 1; - -+ /* -+ * Check whether there is any path through configured auth methods. -+ * Unfortunately it is not possible to verify this generally before -+ * daemonisation in the presence of Match block, but this catches -+ * and warns for trivial misconfigurations that could break login. -+ */ -+ if (options.num_auth_methods != 0) { -+ if ((options.protocol & SSH_PROTO_1)) -+ fatal("AuthenticationMethods is not supported with " -+ "SSH protocol 1"); -+ for (n = 0; n < options.num_auth_methods; n++) { -+ if (auth2_methods_valid(options.auth_methods[n], -+ 1) == 0) -+ break; -+ } -+ if (n >= options.num_auth_methods) -+ fatal("AuthenticationMethods cannot be satisfied by " -+ "enabled authentication methods"); -+ } -+ - /* set default channel AF */ - channel_set_af(options.address_family); - -diff --git a/sshd_config.5 b/sshd_config.5 -index 314ecfb..ed81ac8 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -151,6 +151,28 @@ See - in - .Xr ssh_config 5 - for more information on patterns. -+.It Cm AuthenticationMethods -+Specifies the authentication methods that must be successfully completed -+for a user to be granted access. -+This option must be followed by one or more comma-separated lists of -+authentication method names. -+Successful authentication requires completion of every method in at least -+one of these lists. -+.Pp -+For example, an argument of -+.Dq publickey,password publickey,keyboard-interactive -+would require the user to complete public key authentication, followed by -+either password or keyboard interactive authentication. -+Only methods that are next in one or more lists are offered at each stage, -+so for this example, it would not be possible to attempt password or -+keyboard-interactive authentication before public key. -+.Pp -+This option is only available for SSH protocol 2 and will yield a fatal -+error if enabled if protocol 1 is also enabled. -+Note that each authentication method listed should also be explicitly enabled -+in the configuration. -+The default is not to require multiple authentication; successful completion -+of a single authentication method is sufficient. - .It Cm AuthorizedKeysFile - Specifies the file that contains the public keys that can be used - for user authentication. -@@ -711,6 +733,7 @@ Available keywords are - .Cm AllowGroups , - .Cm AllowTcpForwarding , - .Cm AllowUsers , -+.Cm AuthenticationMethods , - .Cm AuthorizedKeysFile , - .Cm AuthorizedPrincipalsFile , - .Cm Banner , diff --git a/openssh/patches/openssh-6.1p1-coverity.patch b/openssh/patches/openssh-6.1p1-coverity.patch deleted file mode 100644 index 0c8fb236c..000000000 --- a/openssh/patches/openssh-6.1p1-coverity.patch +++ /dev/null @@ -1,806 +0,0 @@ -diff -up openssh-6.1p1/auth-pam.c.coverity openssh-6.1p1/auth-pam.c ---- openssh-6.1p1/auth-pam.c.coverity 2009-07-12 14:07:21.000000000 +0200 -+++ openssh-6.1p1/auth-pam.c 2012-09-14 21:16:41.264906486 +0200 -@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void * - if (sshpam_thread_status != -1) - return (sshpam_thread_status); - signal(SIGCHLD, sshpam_oldsig); -- waitpid(thread, &status, 0); -+ while (waitpid(thread, &status, 0) < 0) { -+ if (errno == EINTR) -+ continue; -+ fatal("%s: waitpid: %s", __func__, -+ strerror(errno)); -+ } - return (status); - } - #endif -diff -up openssh-6.1p1/clientloop.c.coverity openssh-6.1p1/clientloop.c ---- openssh-6.1p1/clientloop.c.coverity 2012-06-20 14:31:27.000000000 +0200 -+++ openssh-6.1p1/clientloop.c 2012-09-14 21:16:41.267906501 +0200 -@@ -2006,14 +2006,15 @@ client_input_global_request(int type, u_ - char *rtype; - int want_reply; - int success = 0; -+/* success is still 0 the packet is allways SSH2_MSG_REQUEST_FAILURE, isn't it? */ - - rtype = packet_get_string(NULL); - want_reply = packet_get_char(); - debug("client_input_global_request: rtype %s want_reply %d", - rtype, want_reply); - if (want_reply) { -- packet_start(success ? -- SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); -+ packet_start(/*success ? -+ SSH2_MSG_REQUEST_SUCCESS :*/ SSH2_MSG_REQUEST_FAILURE); - packet_send(); - packet_write_wait(); - } -diff -up openssh-6.1p1/channels.c.coverity openssh-6.1p1/channels.c ---- openssh-6.1p1/channels.c.coverity 2012-04-23 10:21:05.000000000 +0200 -+++ openssh-6.1p1/channels.c 2012-09-14 21:16:41.272906528 +0200 -@@ -232,11 +232,11 @@ channel_register_fds(Channel *c, int rfd - channel_max_fd = MAX(channel_max_fd, wfd); - channel_max_fd = MAX(channel_max_fd, efd); - -- if (rfd != -1) -+ if (rfd >= 0) - fcntl(rfd, F_SETFD, FD_CLOEXEC); -- if (wfd != -1 && wfd != rfd) -+ if (wfd >= 0 && wfd != rfd) - fcntl(wfd, F_SETFD, FD_CLOEXEC); -- if (efd != -1 && efd != rfd && efd != wfd) -+ if (efd >= 0 && efd != rfd && efd != wfd) - fcntl(efd, F_SETFD, FD_CLOEXEC); - - c->rfd = rfd; -@@ -251,11 +251,11 @@ channel_register_fds(Channel *c, int rfd - - /* enable nonblocking mode */ - if (nonblock) { -- if (rfd != -1) -+ if (rfd >= 0) - set_nonblock(rfd); -- if (wfd != -1) -+ if (wfd >= 0) - set_nonblock(wfd); -- if (efd != -1) -+ if (efd >= 0) - set_nonblock(efd); - } - } -diff -up openssh-6.1p1/key.c.coverity openssh-6.1p1/key.c ---- openssh-6.1p1/key.c.coverity 2012-06-30 12:05:02.000000000 +0200 -+++ openssh-6.1p1/key.c 2012-09-14 21:16:41.274906537 +0200 -@@ -808,8 +808,10 @@ key_read(Key *ret, char **cpp) - success = 1; - /*XXXX*/ - key_free(k); -+/*XXXX - if (success != 1) - break; -+XXXX*/ - /* advance cp: skip whitespace and data */ - while (*cp == ' ' || *cp == '\t') - cp++; -diff -up openssh-6.1p1/monitor.c.coverity openssh-6.1p1/monitor.c ---- openssh-6.1p1/monitor.c.coverity 2012-06-30 00:33:17.000000000 +0200 -+++ openssh-6.1p1/monitor.c 2012-09-14 21:16:41.277906552 +0200 -@@ -420,7 +420,7 @@ monitor_child_preauth(Authctxt *_authctx - } - - /* Drain any buffered messages from the child */ -- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) -+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) - ; - - if (!authctxt->valid) -@@ -1159,6 +1159,10 @@ mm_answer_keyallowed(int sock, Buffer *m - break; - } - } -+ -+ debug3("%s: key %p is %s", -+ __func__, key, allowed ? "allowed" : "not allowed"); -+ - if (key != NULL) - key_free(key); - -@@ -1180,9 +1184,6 @@ mm_answer_keyallowed(int sock, Buffer *m - xfree(chost); - } - -- debug3("%s: key %p is %s", -- __func__, key, allowed ? "allowed" : "not allowed"); -- - buffer_clear(m); - buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); -diff -up openssh-6.1p1/monitor_wrap.c.coverity openssh-6.1p1/monitor_wrap.c ---- openssh-6.1p1/monitor_wrap.c.coverity 2011-06-20 06:42:23.000000000 +0200 -+++ openssh-6.1p1/monitor_wrap.c 2012-09-14 21:16:41.280906568 +0200 -@@ -707,10 +707,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, - if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || - (tmp2 = dup(pmonitor->m_recvfd)) == -1) { - error("%s: cannot allocate fds for pty", __func__); -- if (tmp1 > 0) -+ if (tmp1 >= 0) - close(tmp1); -- if (tmp2 > 0) -- close(tmp2); -+ /*DEAD CODE if (tmp2 >= 0) -+ close(tmp2);*/ - return 0; - } - close(tmp1); -diff -up openssh-6.1p1/openbsd-compat/bindresvport.c.coverity openssh-6.1p1/openbsd-compat/bindresvport.c ---- openssh-6.1p1/openbsd-compat/bindresvport.c.coverity 2010-12-03 00:50:26.000000000 +0100 -+++ openssh-6.1p1/openbsd-compat/bindresvport.c 2012-09-14 21:16:41.281906573 +0200 -@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr - struct sockaddr_in6 *in6; - u_int16_t *portp; - u_int16_t port; -- socklen_t salen; -+ socklen_t salen = sizeof(struct sockaddr_storage); - int i; - - if (sa == NULL) { -diff -up openssh-6.1p1/packet.c.coverity openssh-6.1p1/packet.c ---- openssh-6.1p1/packet.c.coverity 2012-03-09 00:28:07.000000000 +0100 -+++ openssh-6.1p1/packet.c 2012-09-14 21:16:41.284906588 +0200 -@@ -1177,6 +1177,7 @@ packet_read_poll1(void) - case DEATTACK_DETECTED: - packet_disconnect("crc32 compensation attack: " - "network attack detected"); -+ break; - case DEATTACK_DOS_DETECTED: - packet_disconnect("deattack denial of " - "service detected"); -@@ -1678,7 +1679,7 @@ void - packet_write_wait(void) - { - fd_set *setp; -- int ret, ms_remain; -+ int ret, ms_remain = 0; - struct timeval start, timeout, *timeoutp = NULL; - - setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, -diff -up openssh-6.1p1/progressmeter.c.coverity openssh-6.1p1/progressmeter.c ---- openssh-6.1p1/progressmeter.c.coverity 2006-08-05 04:39:40.000000000 +0200 -+++ openssh-6.1p1/progressmeter.c 2012-09-14 21:16:41.285906593 +0200 -@@ -65,7 +65,7 @@ static void update_progress_meter(int); - - static time_t start; /* start progress */ - static time_t last_update; /* last progress update */ --static char *file; /* name of the file being transferred */ -+static const char *file; /* name of the file being transferred */ - static off_t end_pos; /* ending position of transfer */ - static off_t cur_pos; /* transfer position as of last refresh */ - static volatile off_t *counter; /* progress counter */ -@@ -247,7 +247,7 @@ update_progress_meter(int ignore) - } - - void --start_progress_meter(char *f, off_t filesize, off_t *ctr) -+start_progress_meter(const char *f, off_t filesize, off_t *ctr) - { - start = last_update = time(NULL); - file = f; -diff -up openssh-6.1p1/progressmeter.h.coverity openssh-6.1p1/progressmeter.h ---- openssh-6.1p1/progressmeter.h.coverity 2006-03-26 05:30:02.000000000 +0200 -+++ openssh-6.1p1/progressmeter.h 2012-09-14 21:16:41.286906598 +0200 -@@ -23,5 +23,5 @@ - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - --void start_progress_meter(char *, off_t, off_t *); -+void start_progress_meter(const char *, off_t, off_t *); - void stop_progress_meter(void); -diff -up openssh-6.1p1/scp.c.coverity openssh-6.1p1/scp.c ---- openssh-6.1p1/scp.c.coverity 2011-09-22 13:38:01.000000000 +0200 -+++ openssh-6.1p1/scp.c 2012-09-14 21:16:41.288906608 +0200 -@@ -155,7 +155,7 @@ killchild(int signo) - { - if (do_cmd_pid > 1) { - kill(do_cmd_pid, signo ? signo : SIGTERM); -- waitpid(do_cmd_pid, NULL, 0); -+ (void) waitpid(do_cmd_pid, NULL, 0); - } - - if (signo) -diff -up openssh-6.1p1/servconf.c.coverity openssh-6.1p1/servconf.c ---- openssh-6.1p1/servconf.c.coverity 2012-07-31 04:22:38.000000000 +0200 -+++ openssh-6.1p1/servconf.c 2012-09-14 21:16:41.291906623 +0200 -@@ -1249,7 +1249,7 @@ process_server_config_line(ServerOptions - fatal("%s line %d: Missing subsystem name.", - filename, linenum); - if (!*activep) { -- arg = strdelim(&cp); -+ /*arg =*/ (void) strdelim(&cp); - break; - } - for (i = 0; i < options->num_subsystems; i++) -@@ -1340,8 +1340,9 @@ process_server_config_line(ServerOptions - if (*activep && *charptr == NULL) { - *charptr = tilde_expand_filename(arg, getuid()); - /* increase optional counter */ -- if (intptr != NULL) -- *intptr = *intptr + 1; -+ /* DEAD CODE intptr is still NULL ;) -+ if (intptr != NULL) -+ *intptr = *intptr + 1; */ - } - break; - -diff -up openssh-6.1p1/serverloop.c.coverity openssh-6.1p1/serverloop.c ---- openssh-6.1p1/serverloop.c.coverity 2012-06-20 14:31:27.000000000 +0200 -+++ openssh-6.1p1/serverloop.c 2012-09-14 21:16:41.294906638 +0200 -@@ -147,13 +147,13 @@ notify_setup(void) - static void - notify_parent(void) - { -- if (notify_pipe[1] != -1) -+ if (notify_pipe[1] >= 0) - write(notify_pipe[1], "", 1); - } - static void - notify_prepare(fd_set *readset) - { -- if (notify_pipe[0] != -1) -+ if (notify_pipe[0] >= 0) - FD_SET(notify_pipe[0], readset); - } - static void -@@ -161,8 +161,8 @@ notify_done(fd_set *readset) - { - char c; - -- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) -- while (read(notify_pipe[0], &c, 1) != -1) -+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) -+ while (read(notify_pipe[0], &c, 1) >= 0) - debug2("notify_done: reading"); - } - -@@ -336,7 +336,7 @@ wait_until_can_do_something(fd_set **rea - * If we have buffered data, try to write some of that data - * to the program. - */ -- if (fdin != -1 && buffer_len(&stdin_buffer) > 0) -+ if (fdin >= 0 && buffer_len(&stdin_buffer) > 0) - FD_SET(fdin, *writesetp); - } - notify_prepare(*readsetp); -@@ -476,7 +476,7 @@ process_output(fd_set *writeset) - int len; - - /* Write buffered data to program stdin. */ -- if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { -+ if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) { - data = buffer_ptr(&stdin_buffer); - dlen = buffer_len(&stdin_buffer); - len = write(fdin, data, dlen); -@@ -589,7 +589,7 @@ server_loop(pid_t pid, int fdin_arg, int - set_nonblock(fdin); - set_nonblock(fdout); - /* we don't have stderr for interactive terminal sessions, see below */ -- if (fderr != -1) -+ if (fderr >= 0) - set_nonblock(fderr); - - if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) -@@ -613,7 +613,7 @@ server_loop(pid_t pid, int fdin_arg, int - max_fd = MAX(connection_in, connection_out); - max_fd = MAX(max_fd, fdin); - max_fd = MAX(max_fd, fdout); -- if (fderr != -1) -+ if (fderr >= 0) - max_fd = MAX(max_fd, fderr); - #endif - -@@ -643,7 +643,7 @@ server_loop(pid_t pid, int fdin_arg, int - * If we have received eof, and there is no more pending - * input data, cause a real eof by closing fdin. - */ -- if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { -+ if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) { - if (fdin != fdout) - close(fdin); - else -@@ -741,15 +741,15 @@ server_loop(pid_t pid, int fdin_arg, int - buffer_free(&stderr_buffer); - - /* Close the file descriptors. */ -- if (fdout != -1) -+ if (fdout >= 0) - close(fdout); - fdout = -1; - fdout_eof = 1; -- if (fderr != -1) -+ if (fderr >= 0) - close(fderr); - fderr = -1; - fderr_eof = 1; -- if (fdin != -1) -+ if (fdin >= 0) - close(fdin); - fdin = -1; - -@@ -943,7 +943,7 @@ server_input_window_size(int type, u_int - - debug("Window change received."); - packet_check_eom(); -- if (fdin != -1) -+ if (fdin >= 0) - pty_change_window_size(fdin, row, col, xpixel, ypixel); - } - -@@ -996,7 +996,7 @@ server_request_tun(void) - } - - tun = packet_get_int(); -- if (forced_tun_device != -1) { -+ if (forced_tun_device >= 0) { - if (tun != SSH_TUNID_ANY && forced_tun_device != tun) - goto done; - tun = forced_tun_device; -diff -up openssh-6.1p1/sftp.c.coverity openssh-6.1p1/sftp.c ---- openssh-6.1p1/sftp.c.coverity 2012-06-30 00:33:32.000000000 +0200 -+++ openssh-6.1p1/sftp.c 2012-09-14 21:16:41.297906653 +0200 -@@ -206,7 +206,7 @@ killchild(int signo) - { - if (sshpid > 1) { - kill(sshpid, SIGTERM); -- waitpid(sshpid, NULL, 0); -+ (void) waitpid(sshpid, NULL, 0); - } - - _exit(1); -@@ -316,7 +316,7 @@ local_do_ls(const char *args) - - /* Strip one path (usually the pwd) from the start of another */ - static char * --path_strip(char *path, char *strip) -+path_strip(const char *path, const char *strip) - { - size_t len; - -@@ -334,7 +334,7 @@ path_strip(char *path, char *strip) - } - - static char * --make_absolute(char *p, char *pwd) -+make_absolute(char *p, const char *pwd) - { - char *abs_str; - -@@ -482,7 +482,7 @@ parse_df_flags(const char *cmd, char **a - } - - static int --is_dir(char *path) -+is_dir(const char *path) - { - struct stat sb; - -@@ -494,7 +494,7 @@ is_dir(char *path) - } - - static int --remote_is_dir(struct sftp_conn *conn, char *path) -+remote_is_dir(struct sftp_conn *conn, const char *path) - { - Attrib *a; - -@@ -508,7 +508,7 @@ remote_is_dir(struct sftp_conn *conn, ch - - /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ - static int --pathname_is_dir(char *pathname) -+pathname_is_dir(const char *pathname) - { - size_t l = strlen(pathname); - -@@ -516,7 +516,7 @@ pathname_is_dir(char *pathname) - } - - static int --process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, -+process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, - int pflag, int rflag) - { - char *abs_src = NULL; -@@ -590,7 +590,7 @@ out: - } - - static int --process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, -+process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, - int pflag, int rflag) - { - char *tmp_dst = NULL; -@@ -695,7 +695,7 @@ sdirent_comp(const void *aa, const void - - /* sftp ls.1 replacement for directories */ - static int --do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) -+do_ls_dir(struct sftp_conn *conn, const char *path, const char *strip_path, int lflag) - { - int n; - u_int c = 1, colspace = 0, columns = 1; -@@ -780,7 +780,7 @@ do_ls_dir(struct sftp_conn *conn, char * - - /* sftp ls.1 replacement which handles path globs */ - static int --do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, -+do_globbed_ls(struct sftp_conn *conn, const char *path, const char *strip_path, - int lflag) - { - char *fname, *lname; -@@ -861,7 +861,7 @@ do_globbed_ls(struct sftp_conn *conn, ch - } - - static int --do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) -+do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) - { - struct sftp_statvfs st; - char s_used[FMT_SCALED_STRSIZE]; -diff -up openssh-6.1p1/sftp-client.c.coverity openssh-6.1p1/sftp-client.c ---- openssh-6.1p1/sftp-client.c.coverity 2012-07-02 14:15:39.000000000 +0200 -+++ openssh-6.1p1/sftp-client.c 2012-09-14 21:18:16.891332281 +0200 -@@ -149,7 +149,7 @@ get_msg(struct sftp_conn *conn, Buffer * - } - - static void --send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, -+send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s, - u_int len) - { - Buffer msg; -@@ -165,7 +165,7 @@ send_string_request(struct sftp_conn *co - - static void - send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, -- char *s, u_int len, Attrib *a) -+ const char *s, u_int len, Attrib *a) - { - Buffer msg; - -@@ -422,7 +422,7 @@ sftp_proto_version(struct sftp_conn *con - } - - int --do_close(struct sftp_conn *conn, char *handle, u_int handle_len) -+do_close(struct sftp_conn *conn, const char *handle, u_int handle_len) - { - u_int id, status; - Buffer msg; -@@ -447,7 +447,7 @@ do_close(struct sftp_conn *conn, char *h - - - static int --do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, -+do_lsreaddir(struct sftp_conn *conn, const char *path, int printflag, - SFTP_DIRENT ***dir) - { - Buffer msg; -@@ -572,7 +572,7 @@ do_lsreaddir(struct sftp_conn *conn, cha - } - - int --do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir) -+do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir) - { - return(do_lsreaddir(conn, path, 0, dir)); - } -@@ -590,7 +590,7 @@ void free_sftp_dirents(SFTP_DIRENT **s) - } - - int --do_rm(struct sftp_conn *conn, char *path) -+do_rm(struct sftp_conn *conn, const char *path) - { - u_int status, id; - -@@ -605,7 +605,7 @@ do_rm(struct sftp_conn *conn, char *path - } - - int --do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) -+do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int printflag) - { - u_int status, id; - -@@ -621,7 +621,7 @@ do_mkdir(struct sftp_conn *conn, char *p - } - - int --do_rmdir(struct sftp_conn *conn, char *path) -+do_rmdir(struct sftp_conn *conn, const char *path) - { - u_int status, id; - -@@ -637,7 +637,7 @@ do_rmdir(struct sftp_conn *conn, char *p - } - - Attrib * --do_stat(struct sftp_conn *conn, char *path, int quiet) -+do_stat(struct sftp_conn *conn, const char *path, int quiet) - { - u_int id; - -@@ -651,7 +651,7 @@ do_stat(struct sftp_conn *conn, char *pa - } - - Attrib * --do_lstat(struct sftp_conn *conn, char *path, int quiet) -+do_lstat(struct sftp_conn *conn, const char *path, int quiet) - { - u_int id; - -@@ -685,7 +685,7 @@ do_fstat(struct sftp_conn *conn, char *h - #endif - - int --do_setstat(struct sftp_conn *conn, char *path, Attrib *a) -+do_setstat(struct sftp_conn *conn, const char *path, Attrib *a) - { - u_int status, id; - -@@ -702,7 +702,7 @@ do_setstat(struct sftp_conn *conn, char - } - - int --do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, -+do_fsetstat(struct sftp_conn *conn, const char *handle, u_int handle_len, - Attrib *a) - { - u_int status, id; -@@ -719,7 +719,7 @@ do_fsetstat(struct sftp_conn *conn, char - } - - char * --do_realpath(struct sftp_conn *conn, char *path) -+do_realpath(struct sftp_conn *conn, const char *path) - { - Buffer msg; - u_int type, expected_id, count, id; -@@ -768,7 +768,7 @@ do_realpath(struct sftp_conn *conn, char - } - - int --do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -802,7 +802,7 @@ do_rename(struct sftp_conn *conn, char * - } - - int --do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -835,7 +835,7 @@ do_hardlink(struct sftp_conn *conn, char - } - - int --do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -987,7 +987,7 @@ send_read_request(struct sftp_conn *conn - } - - int --do_download(struct sftp_conn *conn, char *remote_path, char *local_path, -+do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path, - Attrib *a, int pflag) - { - Attrib junk; -@@ -1226,7 +1226,7 @@ do_download(struct sftp_conn *conn, char - } - - static int --download_dir_internal(struct sftp_conn *conn, char *src, char *dst, -+download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, - Attrib *dirattrib, int pflag, int printflag, int depth) - { - int i, ret = 0; -@@ -1316,7 +1316,7 @@ download_dir_internal(struct sftp_conn * - } - - int --download_dir(struct sftp_conn *conn, char *src, char *dst, -+download_dir(struct sftp_conn *conn, const char *src, const char *dst, - Attrib *dirattrib, int pflag, int printflag) - { - char *src_canon; -@@ -1334,7 +1334,7 @@ download_dir(struct sftp_conn *conn, cha - } - - int --do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, -+do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path, - int pflag) - { - int local_fd; -@@ -1517,7 +1517,7 @@ do_upload(struct sftp_conn *conn, char * - } - - static int --upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, -+upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, - int pflag, int printflag, int depth) - { - int ret = 0, status; -@@ -1608,7 +1608,7 @@ upload_dir_internal(struct sftp_conn *co - } - - int --upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag, -+upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int printflag, - int pflag) - { - char *dst_canon; -@@ -1625,7 +1625,7 @@ upload_dir(struct sftp_conn *conn, char - } - - char * --path_append(char *p1, char *p2) -+path_append(const char *p1, const char *p2) - { - char *ret; - size_t len = strlen(p1) + strlen(p2) + 2; -diff -up openssh-6.1p1/sftp-client.h.coverity openssh-6.1p1/sftp-client.h ---- openssh-6.1p1/sftp-client.h.coverity 2010-12-04 23:02:48.000000000 +0100 -+++ openssh-6.1p1/sftp-client.h 2012-09-14 21:16:41.301906674 +0200 -@@ -56,49 +56,49 @@ struct sftp_conn *do_init(int, int, u_in - u_int sftp_proto_version(struct sftp_conn *); - - /* Close file referred to by 'handle' */ --int do_close(struct sftp_conn *, char *, u_int); -+int do_close(struct sftp_conn *, const char *, u_int); - - /* Read contents of 'path' to NULL-terminated array 'dir' */ --int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***); -+int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***); - - /* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */ - void free_sftp_dirents(SFTP_DIRENT **); - - /* Delete file 'path' */ --int do_rm(struct sftp_conn *, char *); -+int do_rm(struct sftp_conn *, const char *); - - /* Create directory 'path' */ --int do_mkdir(struct sftp_conn *, char *, Attrib *, int); -+int do_mkdir(struct sftp_conn *, const char *, Attrib *, int); - - /* Remove directory 'path' */ --int do_rmdir(struct sftp_conn *, char *); -+int do_rmdir(struct sftp_conn *, const char *); - - /* Get file attributes of 'path' (follows symlinks) */ --Attrib *do_stat(struct sftp_conn *, char *, int); -+Attrib *do_stat(struct sftp_conn *, const char *, int); - - /* Get file attributes of 'path' (does not follow symlinks) */ --Attrib *do_lstat(struct sftp_conn *, char *, int); -+Attrib *do_lstat(struct sftp_conn *, const char *, int); - - /* Set file attributes of 'path' */ --int do_setstat(struct sftp_conn *, char *, Attrib *); -+int do_setstat(struct sftp_conn *, const char *, Attrib *); - - /* Set file attributes of open file 'handle' */ --int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); -+int do_fsetstat(struct sftp_conn *, const char *, u_int, Attrib *); - - /* Canonicalise 'path' - caller must free result */ --char *do_realpath(struct sftp_conn *, char *); -+char *do_realpath(struct sftp_conn *, const char *); - - /* Get statistics for filesystem hosting file at "path" */ - int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); - - /* Rename 'oldpath' to 'newpath' */ --int do_rename(struct sftp_conn *, char *, char *); -+int do_rename(struct sftp_conn *, const char *, const char *); - - /* Link 'oldpath' to 'newpath' */ --int do_hardlink(struct sftp_conn *, char *, char *); -+int do_hardlink(struct sftp_conn *, const char *, const char *); - --/* Rename 'oldpath' to 'newpath' */ --int do_symlink(struct sftp_conn *, char *, char *); -+/* Symlink 'oldpath' to 'newpath' */ -+int do_symlink(struct sftp_conn *, const char *, const char *); - - /* XXX: add callbacks to do_download/do_upload so we can do progress meter */ - -@@ -106,27 +106,27 @@ int do_symlink(struct sftp_conn *, char - * Download 'remote_path' to 'local_path'. Preserve permissions and times - * if 'pflag' is set - */ --int do_download(struct sftp_conn *, char *, char *, Attrib *, int); -+int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int); - - /* - * Recursively download 'remote_directory' to 'local_directory'. Preserve - * times if 'pflag' is set - */ --int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int); -+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, int); - - /* - * Upload 'local_path' to 'remote_path'. Preserve permissions and times - * if 'pflag' is set - */ --int do_upload(struct sftp_conn *, char *, char *, int); -+int do_upload(struct sftp_conn *, const char *, const char *, int); - - /* - * Recursively upload 'local_directory' to 'remote_directory'. Preserve - * times if 'pflag' is set - */ --int upload_dir(struct sftp_conn *, char *, char *, int, int); -+int upload_dir(struct sftp_conn *, const char *, const char *, int, int); - - /* Concatenate paths, taking care of slashes. Caller must free result. */ --char *path_append(char *, char *); -+char *path_append(const char *, const char *); - - #endif -diff -up openssh-6.1p1/ssh-agent.c.coverity openssh-6.1p1/ssh-agent.c ---- openssh-6.1p1/ssh-agent.c.coverity 2011-06-03 06:14:16.000000000 +0200 -+++ openssh-6.1p1/ssh-agent.c 2012-09-14 21:16:41.303906683 +0200 -@@ -1147,8 +1147,8 @@ main(int ac, char **av) - sanitise_stdfd(); - - /* drop */ -- setegid(getgid()); -- setgid(getgid()); -+ (void) setegid(getgid()); -+ (void) setgid(getgid()); - - #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) - /* Disable ptrace on Linux without sgid bit */ -diff -up openssh-6.1p1/sshd.c.coverity openssh-6.1p1/sshd.c ---- openssh-6.1p1/sshd.c.coverity 2012-07-31 04:21:34.000000000 +0200 -+++ openssh-6.1p1/sshd.c 2012-09-14 21:16:41.307906705 +0200 -@@ -682,8 +682,10 @@ privsep_preauth(Authctxt *authctxt) - if (getuid() == 0 || geteuid() == 0) - privsep_preauth_child(); - setproctitle("%s", "[net]"); -- if (box != NULL) -+ if (box != NULL) { - ssh_sandbox_child(box); -+ xfree(box); -+ } - - return 0; - } -@@ -1311,6 +1313,9 @@ server_accept_loop(int *sock_in, int *so - if (num_listen_socks < 0) - break; - } -+ -+ if (fdset != NULL) -+ xfree(fdset); - } - - -@@ -1768,7 +1773,7 @@ main(int ac, char **av) - - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ -- chdir("/"); -+ (void) chdir("/"); - - /* ignore SIGPIPE */ - signal(SIGPIPE, SIG_IGN); diff --git a/openssh/patches/openssh-6.1p1-kuserok.patch b/openssh/patches/openssh-6.1p1-kuserok.patch deleted file mode 100644 index 7b695e0b3..000000000 --- a/openssh/patches/openssh-6.1p1-kuserok.patch +++ /dev/null @@ -1,167 +0,0 @@ -diff -up openssh-6.1p1/auth-krb5.c.kuserok openssh-6.1p1/auth-krb5.c ---- openssh-6.1p1/auth-krb5.c.kuserok 2012-09-14 21:08:16.941496194 +0200 -+++ openssh-6.1p1/auth-krb5.c 2012-09-14 21:08:17.063496896 +0200 -@@ -55,6 +55,20 @@ - - extern ServerOptions options; - -+int -+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client) -+{ -+ if (options.use_kuserok) -+ return krb5_kuserok(krb5_ctx, krb5_user, client); -+ else { -+ char kuser[65]; -+ -+ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) -+ return 0; -+ return strcmp(kuser, client) == 0; -+ } -+} -+ - static int - krb5_init(void *context) - { -@@ -147,7 +161,7 @@ auth_krb5_password(Authctxt *authctxt, c - if (problem) - goto out; - -- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { -+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { - problem = -1; - goto out; - } -diff -up openssh-6.1p1/gss-serv-krb5.c.kuserok openssh-6.1p1/gss-serv-krb5.c ---- openssh-6.1p1/gss-serv-krb5.c.kuserok 2012-09-14 21:08:17.019496642 +0200 -+++ openssh-6.1p1/gss-serv-krb5.c 2012-09-14 21:08:17.065496906 +0200 -@@ -68,6 +68,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr - int); - - static krb5_context krb_context = NULL; -+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *); - - /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ - -@@ -115,7 +116,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - /* NOTE: .k5login and .k5users must opened as root, not the user, - * because if they are on a krb5-protected filesystem, user credentials - * to access these files aren't available yet. */ -- if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) { -+ if (ssh_krb5_kuserok(krb_context, princ, luser) && k5login_exists) { - retval = 1; - logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", - luser, (char *)client->displayname.value); -diff -up openssh-6.1p1/servconf.c.kuserok openssh-6.1p1/servconf.c ---- openssh-6.1p1/servconf.c.kuserok 2012-09-14 21:08:16.989496471 +0200 -+++ openssh-6.1p1/servconf.c 2012-09-14 21:09:30.864868698 +0200 -@@ -152,6 +152,7 @@ initialize_server_options(ServerOptions - options->ip_qos_interactive = -1; - options->ip_qos_bulk = -1; - options->version_addendum = NULL; -+ options->use_kuserok = -1; - } - - void -@@ -301,6 +302,8 @@ fill_default_server_options(ServerOption - options->version_addendum = xstrdup(""); - if (options->show_patchlevel == -1) - options->show_patchlevel = 0; -+ if (options->use_kuserok == -1) -+ options->use_kuserok = 1; - - /* Turn privilege separation on by default */ - if (use_privsep == -1) -@@ -327,7 +330,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, -+ sKerberosGetAFSToken, sKerberosUseKuserok, - sKerberosTgtPassing, sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, -@@ -399,11 +402,13 @@ static struct { - #else - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, - #endif -+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, - #else - { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, - { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, -+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, - #endif - { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, - { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1486,6 +1491,10 @@ process_server_config_line(ServerOptions - *activep = value; - break; - -+ case sKerberosUseKuserok: -+ intptr = &options->use_kuserok; -+ goto parse_flag; -+ - case sPermitOpen: - arg = strdelim(&cp); - if (!arg || *arg == '\0') -@@ -1769,6 +1778,7 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(max_authtries); - M_CP_INTOPT(ip_qos_interactive); - M_CP_INTOPT(ip_qos_bulk); -+ M_CP_INTOPT(use_kuserok); - - /* See comment in servconf.h */ - COPY_MATCH_STRING_OPTS(); -@@ -2005,6 +2015,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); -+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-6.1p1/servconf.h.kuserok openssh-6.1p1/servconf.h ---- openssh-6.1p1/servconf.h.kuserok 2012-09-14 21:08:16.990496476 +0200 -+++ openssh-6.1p1/servconf.h 2012-09-14 21:08:17.071496942 +0200 -@@ -169,6 +169,7 @@ typedef struct { - - int num_permitted_opens; - -+ int use_kuserok; - char *chroot_directory; - char *revoked_keys_file; - char *trusted_user_ca_keys; -diff -up openssh-6.1p1/sshd_config.kuserok openssh-6.1p1/sshd_config ---- openssh-6.1p1/sshd_config.kuserok 2012-09-14 21:08:17.002496545 +0200 -+++ openssh-6.1p1/sshd_config 2012-09-14 21:08:17.074496957 +0200 -@@ -79,6 +79,7 @@ ChallengeResponseAuthentication no - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok yes - - # GSSAPI options - #GSSAPIAuthentication no -diff -up openssh-6.1p1/sshd_config.5.kuserok openssh-6.1p1/sshd_config.5 ---- openssh-6.1p1/sshd_config.5.kuserok 2012-09-14 21:08:17.004496556 +0200 -+++ openssh-6.1p1/sshd_config.5 2012-09-14 21:08:17.073496952 +0200 -@@ -618,6 +618,10 @@ Specifies whether to automatically destr - file on logout. - The default is - .Dq yes . -+.It Cm KerberosUseKuserok -+Specifies whether to look at .k5login file for user's aliases. -+The default is -+.Dq yes . - .It Cm KexAlgorithms - Specifies the available KEX (Key Exchange) algorithms. - Multiple algorithms must be comma-separated. -@@ -767,6 +771,7 @@ Available keywords are - .Cm HostbasedUsesNameFromPacketOnly , - .Cm KbdInteractiveAuthentication , - .Cm KerberosAuthentication , -+.Cm KerberosUseKuserok , - .Cm MaxAuthTries , - .Cm MaxSessions , - .Cm PubkeyAuthentication , diff --git a/openssh/patches/openssh-6.1p1-required-authentications.patch b/openssh/patches/openssh-6.1p1-required-authentications.patch deleted file mode 100644 index bfc28eed8..000000000 --- a/openssh/patches/openssh-6.1p1-required-authentications.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff -up openssh-6.1p1/servconf.c.required-authentication openssh-6.1p1/servconf.c ---- openssh-6.1p1/servconf.c.required-authentication 2012-11-30 21:13:14.375382453 +0100 -+++ openssh-6.1p1/servconf.c 2012-11-30 21:33:56.972017545 +0100 -@@ -495,6 +495,8 @@ static struct { - { "authorizedkeyscommandrunas", sAuthorizedKeysCommandUser, SSHCFG_ALL }, - { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, - { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, -+ { "requiredauthentications1", sAuthenticationMethods, SSHCFG_ALL }, -+ { "requiredauthentications2", sAuthenticationMethods, SSHCFG_ALL }, - { NULL, sBadOption, 0 } - }; - -@@ -1560,6 +1562,9 @@ process_server_config_line(ServerOptions - return 0; - - case sAuthenticationMethods: -+ if (strncasecmp(arg, "requiredauthentications", 23) == 0) -+ logit("%s line %d: Option %s is obsolete. Please use AuthenticationMethods", -+ filename, linenum, arg); - if (*activep && options->num_auth_methods == 0) { - while ((arg = strdelim(&cp)) && *arg != '\0') { - if (options->num_auth_methods >= diff --git a/openssh/patches/openssh-6.1p1-role-mls.patch b/openssh/patches/openssh-6.1p1-role-mls.patch deleted file mode 100644 index 4de3dae94..000000000 --- a/openssh/patches/openssh-6.1p1-role-mls.patch +++ /dev/null @@ -1,934 +0,0 @@ -diff -up openssh-6.1p1/auth1.c.role-mls openssh-6.1p1/auth1.c ---- openssh-6.1p1/auth1.c.role-mls 2012-11-28 17:06:43.657990103 +0100 -+++ openssh-6.1p1/auth1.c 2012-11-28 17:06:43.699989959 +0100 -@@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt) - { - u_int ulen; - char *user, *style = NULL; -+#ifdef WITH_SELINUX -+ char *role=NULL; -+#endif - - /* Get the name of the user that we wish to log in as. */ - packet_read_expect(SSH_CMSG_USER); -@@ -392,11 +395,24 @@ do_authentication(Authctxt *authctxt) - user = packet_get_cstring(&ulen); - packet_check_eom(); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = '\0'; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = '\0'; -+#ifdef WITH_SELINUX -+ else -+ if (role && (style = strchr(role, ':')) != NULL) -+ *style++ = '\0'; -+#endif - - authctxt->user = user; - authctxt->style = style; -+#ifdef WITH_SELINUX -+ authctxt->role = role; -+#endif - - /* Verify that the user is a valid user. */ - if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) -diff -up openssh-6.1p1/auth2.c.role-mls openssh-6.1p1/auth2.c ---- openssh-6.1p1/auth2.c.role-mls 2012-11-28 17:06:43.661990089 +0100 -+++ openssh-6.1p1/auth2.c 2012-11-28 17:11:09.058916613 +0100 -@@ -218,6 +218,9 @@ input_userauth_request(int type, u_int32 - Authctxt *authctxt = ctxt; - Authmethod *m = NULL; - char *user, *service, *method, *style = NULL; -+#ifdef WITH_SELINUX -+ char *role = NULL; -+#endif - int authenticated = 0; - - if (authctxt == NULL) -@@ -229,6 +232,11 @@ input_userauth_request(int type, u_int32 - debug("userauth-request for user %s service %s method %s", user, service, method); - debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = 0; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = 0; - -@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32 - use_privsep ? " [net]" : ""); - authctxt->service = xstrdup(service); - authctxt->style = style ? xstrdup(style) : NULL; -- if (use_privsep) -+#ifdef WITH_SELINUX -+ authctxt->role = role ? xstrdup(role) : NULL; -+#endif -+ if (use_privsep) { - mm_inform_authserv(service, style); -+#ifdef WITH_SELINUX -+ mm_inform_authrole(role); -+#endif -+ } - userauth_banner(); - if (auth2_setup_methods_lists(authctxt) != 0) - packet_disconnect("no authentication methods enabled"); -diff -up openssh-6.1p1/auth2-gss.c.role-mls openssh-6.1p1/auth2-gss.c ---- openssh-6.1p1/auth2-gss.c.role-mls 2011-05-05 06:04:11.000000000 +0200 -+++ openssh-6.1p1/auth2-gss.c 2012-11-28 17:06:43.700989956 +0100 -@@ -260,6 +260,7 @@ input_gssapi_mic(int type, u_int32_t ple - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - int authenticated = 0; -+ char *micuser; - Buffer b; - gss_buffer_desc mic, gssbuf; - u_int len; -@@ -272,7 +273,13 @@ input_gssapi_mic(int type, u_int32_t ple - mic.value = packet_get_string(&len); - mic.length = len; - -- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, -+#ifdef WITH_SELINUX -+ if (authctxt->role && (strlen(authctxt->role) > 0)) -+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); -+ else -+#endif -+ micuser = authctxt->user; -+ ssh_gssapi_buildmic(&b, micuser, authctxt->service, - "gssapi-with-mic"); - - gssbuf.value = buffer_ptr(&b); -@@ -284,6 +291,8 @@ input_gssapi_mic(int type, u_int32_t ple - logit("GSSAPI MIC check failed"); - - buffer_free(&b); -+ if (micuser != authctxt->user) -+ xfree(micuser); - xfree(mic.value); - - authctxt->postponed = 0; -diff -up openssh-6.1p1/auth2-hostbased.c.role-mls openssh-6.1p1/auth2-hostbased.c ---- openssh-6.1p1/auth2-hostbased.c.role-mls 2012-11-28 17:06:43.669990062 +0100 -+++ openssh-6.1p1/auth2-hostbased.c 2012-11-28 17:06:43.700989956 +0100 -@@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt) - buffer_put_string(&b, session_id2, session_id2_len); - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); -+#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 -+#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, "hostbased"); - buffer_put_string(&b, pkalg, alen); -diff -up openssh-6.1p1/auth2-pubkey.c.role-mls openssh-6.1p1/auth2-pubkey.c ---- openssh-6.1p1/auth2-pubkey.c.role-mls 2012-11-28 17:06:43.669990062 +0100 -+++ openssh-6.1p1/auth2-pubkey.c 2012-11-28 17:06:43.700989956 +0100 -@@ -121,7 +121,15 @@ userauth_pubkey(Authctxt *authctxt) - } - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); -+#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 -+#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, - datafellows & SSH_BUG_PKSERVICE ? - "ssh-userauth" : -diff -up openssh-6.1p1/auth.h.role-mls openssh-6.1p1/auth.h ---- openssh-6.1p1/auth.h.role-mls 2012-11-28 17:06:43.669990062 +0100 -+++ openssh-6.1p1/auth.h 2012-11-28 17:06:43.699989959 +0100 -@@ -59,6 +59,9 @@ struct Authctxt { - char *service; - struct passwd *pw; /* set if 'valid' */ - char *style; -+#ifdef WITH_SELINUX -+ char *role; -+#endif - void *kbdintctxt; - void *jpake_ctx; - #ifdef BSD_AUTH -diff -up openssh-6.1p1/auth-pam.c.role-mls openssh-6.1p1/auth-pam.c ---- openssh-6.1p1/auth-pam.c.role-mls 2012-11-28 17:06:43.638990168 +0100 -+++ openssh-6.1p1/auth-pam.c 2012-11-28 17:06:43.699989959 +0100 -@@ -1074,7 +1074,7 @@ is_pam_session_open(void) - * during the ssh authentication process. - */ - int --do_pam_putenv(char *name, char *value) -+do_pam_putenv(char *name, const char *value) - { - int ret = 1; - #ifdef HAVE_PAM_PUTENV -diff -up openssh-6.1p1/auth-pam.h.role-mls openssh-6.1p1/auth-pam.h ---- openssh-6.1p1/auth-pam.h.role-mls 2004-09-11 14:17:26.000000000 +0200 -+++ openssh-6.1p1/auth-pam.h 2012-11-28 17:06:43.699989959 +0100 -@@ -38,7 +38,7 @@ void do_pam_session(void); - void do_pam_set_tty(const char *); - void do_pam_setcred(int ); - void do_pam_chauthtok(void); --int do_pam_putenv(char *, char *); -+int do_pam_putenv(char *, const char *); - char ** fetch_pam_environment(void); - char ** fetch_pam_child_environment(void); - void free_pam_environment(char **); -diff -up openssh-6.1p1/misc.c.role-mls openssh-6.1p1/misc.c ---- openssh-6.1p1/misc.c.role-mls 2011-09-22 13:34:36.000000000 +0200 -+++ openssh-6.1p1/misc.c 2012-11-28 17:06:43.701989952 +0100 -@@ -427,6 +427,7 @@ char * - colon(char *cp) - { - int flag = 0; -+ int start = 1; - - if (*cp == ':') /* Leading colon is part of file name. */ - return NULL; -@@ -442,6 +443,13 @@ colon(char *cp) - return (cp); - if (*cp == '/') - return NULL; -+ if (start) { -+ /* Slash on beginning or after dots only denotes file name. */ -+ if (*cp == '/') -+ return (0); -+ if (*cp != '.') -+ start = 0; -+ } - } - return NULL; - } -diff -up openssh-6.1p1/monitor.c.role-mls openssh-6.1p1/monitor.c ---- openssh-6.1p1/monitor.c.role-mls 2012-11-28 17:06:43.686990004 +0100 -+++ openssh-6.1p1/monitor.c 2012-11-28 17:06:43.701989952 +0100 -@@ -148,6 +148,9 @@ int mm_answer_sign(int, Buffer *); - int mm_answer_pwnamallow(int, Buffer *); - int mm_answer_auth2_read_banner(int, Buffer *); - int mm_answer_authserv(int, Buffer *); -+#ifdef WITH_SELINUX -+int mm_answer_authrole(int, Buffer *); -+#endif - int mm_answer_authpassword(int, Buffer *); - int mm_answer_bsdauthquery(int, Buffer *); - int mm_answer_bsdauthrespond(int, Buffer *); -@@ -231,6 +234,9 @@ struct mon_table mon_dispatch_proto20[] - {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, - {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, - {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, -+#ifdef WITH_SELINUX -+ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -+#endif - {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, - {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, - #ifdef USE_PAM -@@ -838,6 +844,9 @@ mm_answer_pwnamallow(int sock, Buffer *m - else { - /* Allow service/style information on the auth context */ - monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); -+#ifdef WITH_SELINUX -+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); -+#endif - monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); - } - #ifdef USE_PAM -@@ -881,6 +890,25 @@ mm_answer_authserv(int sock, Buffer *m) - return (0); - } - -+#ifdef WITH_SELINUX -+int -+mm_answer_authrole(int sock, Buffer *m) -+{ -+ monitor_permit_authentications(1); -+ -+ authctxt->role = buffer_get_string(m, NULL); -+ debug3("%s: role=%s", -+ __func__, authctxt->role); -+ -+ if (strlen(authctxt->role) == 0) { -+ xfree(authctxt->role); -+ authctxt->role = NULL; -+ } -+ -+ return (0); -+} -+#endif -+ - int - mm_answer_authpassword(int sock, Buffer *m) - { -@@ -1251,7 +1279,7 @@ static int - monitor_valid_userblob(u_char *data, u_int datalen) - { - Buffer b; -- char *p; -+ char *p, *r; - u_int len; - int fail = 0; - -@@ -1277,6 +1305,8 @@ monitor_valid_userblob(u_char *data, u_i - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) - fail++; - p = buffer_get_string(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) -+ *r = '\0'; - if (strcmp(authctxt->user, p) != 0) { - logit("wrong user name passed to monitor: expected %s != %.100s", - authctxt->user, p); -@@ -1308,7 +1338,7 @@ monitor_valid_hostbasedblob(u_char *data - char *chost) - { - Buffer b; -- char *p; -+ char *p, *r; - u_int len; - int fail = 0; - -@@ -1325,6 +1355,8 @@ monitor_valid_hostbasedblob(u_char *data - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) - fail++; - p = buffer_get_string(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) -+ *r = '\0'; - if (strcmp(authctxt->user, p) != 0) { - logit("wrong user name passed to monitor: expected %s != %.100s", - authctxt->user, p); -diff -up openssh-6.1p1/monitor.h.role-mls openssh-6.1p1/monitor.h ---- openssh-6.1p1/monitor.h.role-mls 2012-11-28 17:06:43.686990004 +0100 -+++ openssh-6.1p1/monitor.h 2012-11-28 17:06:43.701989952 +0100 -@@ -31,6 +31,9 @@ - enum monitor_reqtype { - MONITOR_REQ_MODULI, MONITOR_ANS_MODULI, - MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, -+#ifdef WITH_SELINUX -+ MONITOR_REQ_AUTHROLE, -+#endif - MONITOR_REQ_SIGN, MONITOR_ANS_SIGN, - MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM, - MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER, -diff -up openssh-6.1p1/monitor_wrap.c.role-mls openssh-6.1p1/monitor_wrap.c ---- openssh-6.1p1/monitor_wrap.c.role-mls 2012-11-28 17:06:43.686990004 +0100 -+++ openssh-6.1p1/monitor_wrap.c 2012-11-28 17:06:43.702989948 +0100 -@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char * - buffer_free(&m); - } - -+/* Inform the privileged process about role */ -+ -+#ifdef WITH_SELINUX -+void -+mm_inform_authrole(char *role) -+{ -+ Buffer m; -+ -+ debug3("%s entering", __func__); -+ -+ buffer_init(&m); -+ buffer_put_cstring(&m, role ? role : ""); -+ -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); -+ -+ buffer_free(&m); -+} -+#endif -+ - /* Do the password authentication */ - int - mm_auth_password(Authctxt *authctxt, char *password) -diff -up openssh-6.1p1/monitor_wrap.h.role-mls openssh-6.1p1/monitor_wrap.h ---- openssh-6.1p1/monitor_wrap.h.role-mls 2012-11-28 17:06:43.686990004 +0100 -+++ openssh-6.1p1/monitor_wrap.h 2012-11-28 17:06:43.702989948 +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 *, u_char *, u_int); - void mm_inform_authserv(char *, char *); -+#ifdef WITH_SELINUX -+void mm_inform_authrole(char *); -+#endif - struct passwd *mm_getpwnamallow(const char *); - char *mm_auth2_read_banner(void); - int mm_auth_password(struct Authctxt *, char *); -diff -up openssh-6.1p1/openbsd-compat/Makefile.in.role-mls openssh-6.1p1/openbsd-compat/Makefile.in ---- openssh-6.1p1/openbsd-compat/Makefile.in.role-mls 2011-11-04 01:25:25.000000000 +0100 -+++ openssh-6.1p1/openbsd-compat/Makefile.in 2012-11-28 17:06:43.702989948 +0100 -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport - - COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.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_part_2.o port-solaris.o port-tun.o port-uw.o - - .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff -up openssh-6.1p1/openbsd-compat/port-linux.c.role-mls openssh-6.1p1/openbsd-compat/port-linux.c ---- openssh-6.1p1/openbsd-compat/port-linux.c.role-mls 2012-03-09 00:25:18.000000000 +0100 -+++ openssh-6.1p1/openbsd-compat/port-linux.c 2012-11-28 17:06:43.702989948 +0100 -@@ -31,68 +31,271 @@ - - #include "log.h" - #include "xmalloc.h" -+#include "servconf.h" - #include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" - - #ifdef WITH_SELINUX - #include - #include -+#include - #include -+#include -+#include -+ -+#ifdef HAVE_LINUX_AUDIT -+#include -+#include -+#endif - - #ifndef SSH_SELINUX_UNCONFINED_TYPE - # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" - #endif - --/* Wrapper around is_selinux_enabled() to log its return value once only */ --int --ssh_selinux_enabled(void) -+extern ServerOptions options; -+extern Authctxt *the_authctxt; -+extern int inetd_flag; -+extern int rexeced_flag; -+ -+/* Send audit message */ -+static int -+send_audit_message(int success, security_context_t default_context, -+ security_context_t selected_context) -+{ -+ int rc=0; -+#ifdef HAVE_LINUX_AUDIT -+ char *msg = NULL; -+ int audit_fd = audit_open(); -+ security_context_t default_raw=NULL; -+ security_context_t selected_raw=NULL; -+ rc = -1; -+ if (audit_fd < 0) { -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || -+ errno == EAFNOSUPPORT) -+ return 0; /* No audit support in kernel */ -+ error("Error connecting to audit system."); -+ return rc; -+ } -+ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { -+ error("Error translating default context."); -+ default_raw = NULL; -+ } -+ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { -+ error("Error translating selected context."); -+ selected_raw = NULL; -+ } -+ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s", -+ default_raw ? default_raw : (default_context ? default_context: "?"), -+ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) { -+ error("Error allocating memory."); -+ goto out; -+ } -+ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, -+ msg, NULL, NULL, NULL, success) <= 0) { -+ error("Error sending audit message."); -+ goto out; -+ } -+ rc = 0; -+ out: -+ free(msg); -+ freecon(default_raw); -+ freecon(selected_raw); -+ close(audit_fd); -+#endif -+ return rc; -+} -+ -+static int -+mls_range_allowed(security_context_t src, security_context_t dst) - { -- static int enabled = -1; -+ struct av_decision avd; -+ int retval; -+ unsigned int bit = CONTEXT__CONTAINS; -+ -+ debug("%s: src:%s dst:%s", __func__, src, dst); -+ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); -+ if (retval || ((bit & avd.allowed) != bit)) -+ return 0; -+ -+ return 1; -+} -+ -+static int -+get_user_context(const char *sename, const char *role, const char *lvl, -+ security_context_t *sc) { -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) { -+ /* User may have requested a level completely outside of his -+ allowed range. We get a context just for auditing as the -+ range check below will certainly fail for default context. */ -+#endif -+ if (get_default_context(sename, NULL, sc) != 0) { -+ *sc = NULL; -+ return -1; -+ } -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ } -+#endif -+ if (role != NULL && role[0]) { -+ context_t con; -+ char *type=NULL; -+ if (get_default_type(role, &type) != 0) { -+ error("get_default_type: failed to get default type for '%s'", -+ role); -+ goto out; -+ } -+ con = context_new(*sc); -+ if (!con) { -+ goto out; -+ } -+ context_role_set(con, role); -+ context_type_set(con, type); -+ freecon(*sc); -+ *sc = strdup(context_str(con)); -+ context_free(con); -+ if (!*sc) -+ return -1; -+ } -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ if (lvl != NULL && lvl[0]) { -+ /* verify that the requested range is obtained */ -+ context_t con; -+ security_context_t obtained_raw; -+ security_context_t requested_raw; -+ con = context_new(*sc); -+ if (!con) { -+ goto out; -+ } -+ context_range_set(con, lvl); -+ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) { -+ context_free(con); -+ goto out; -+ } -+ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) { -+ freecon(obtained_raw); -+ context_free(con); -+ goto out; -+ } - -- if (enabled == -1) { -- enabled = (is_selinux_enabled() == 1); -- debug("SELinux support %s", enabled ? "enabled" : "disabled"); -+ debug("get_user_context: obtained context '%s' requested context '%s'", -+ obtained_raw, requested_raw); -+ if (strcmp(obtained_raw, requested_raw)) { -+ /* set the context to the real requested one but fail */ -+ freecon(requested_raw); -+ freecon(obtained_raw); -+ freecon(*sc); -+ *sc = strdup(context_str(con)); -+ context_free(con); -+ return -1; -+ } -+ freecon(requested_raw); -+ freecon(obtained_raw); -+ context_free(con); - } -+#endif -+ return 0; -+ out: -+ freecon(*sc); -+ *sc = NULL; -+ return -1; -+} - -- return (enabled); -+static void -+ssh_selinux_get_role_level(char **role, const char **level) -+{ -+ *role = NULL; -+ *level = NULL; -+ if (the_authctxt) { -+ if (the_authctxt->role != NULL) { -+ char *slash; -+ *role = xstrdup(the_authctxt->role); -+ if ((slash = strchr(*role, '/')) != NULL) { -+ *slash = '\0'; -+ *level = slash + 1; -+ } -+ } -+ } - } - - /* Return the default security context for the given username */ - static security_context_t --ssh_selinux_getctxbyname(char *pwname) -+ssh_selinux_getctxbyname(char *pwname, -+ security_context_t *default_sc, security_context_t *user_sc) - { -- security_context_t sc = NULL; -- char *sename = NULL, *lvl = NULL; -- int r; -+ char *sename, *lvl; -+ char *role; -+ const char *reqlvl; -+ int r = 0; -+ context_t con = NULL; -+ -+ ssh_selinux_get_role_level(&role, &reqlvl); - - #ifdef HAVE_GETSEUSERBYNAME -- if (getseuserbyname(pwname, &sename, &lvl) != 0) -- return NULL; -+ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { -+ sename = NULL; -+ lvl = NULL; -+ } - #else - sename = pwname; -- lvl = NULL; -+ lvl = ""; - #endif - -+ if (r == 0) { - #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -- r = get_default_context_with_level(sename, lvl, NULL, &sc); -+ r = get_default_context_with_level(sename, lvl, NULL, default_sc); - #else -- r = get_default_context(sename, NULL, &sc); -+ r = get_default_context(sename, NULL, default_sc); - #endif -+ } -+ -+ if (r == 0) { -+ /* If launched from xinetd, we must use current level */ -+ if (inetd_flag && !rexeced_flag) { -+ security_context_t sshdsc=NULL; -+ -+ if (getcon_raw(&sshdsc) < 0) -+ fatal("failed to allocate security context"); -+ -+ if ((con=context_new(sshdsc)) == NULL) -+ fatal("failed to allocate selinux context"); -+ reqlvl = context_range_get(con); -+ freecon(sshdsc); -+ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0) -+ /* we actually don't change level */ -+ reqlvl = ""; -+ -+ debug("%s: current connection level '%s'", __func__, reqlvl); - -- if (r != 0) { -- switch (security_getenforce()) { -- case -1: -- fatal("%s: ssh_selinux_getctxbyname: " -- "security_getenforce() failed", __func__); -- case 0: -- error("%s: Failed to get default SELinux security " -- "context for %s", __func__, pwname); -- sc = NULL; -- break; -- default: -- fatal("%s: Failed to get default SELinux security " -- "context for %s (in enforcing mode)", -- __func__, pwname); - } -+ -+ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { -+ r = get_user_context(sename, role, reqlvl, user_sc); -+ -+ if (r == 0 && reqlvl != NULL && reqlvl[0]) { -+ security_context_t default_level_sc = *default_sc; -+ if (role != NULL && role[0]) { -+ if (get_user_context(sename, role, lvl, &default_level_sc) < 0) -+ default_level_sc = *default_sc; -+ } -+ /* verify that the requested range is contained in the user range */ -+ if (mls_range_allowed(default_level_sc, *user_sc)) { -+ logit("permit MLS level %s (user range %s)", reqlvl, lvl); -+ } else { -+ r = -1; -+ error("deny MLS level %s (user range %s)", reqlvl, lvl); -+ } -+ if (default_level_sc != *default_sc) -+ freecon(default_level_sc); -+ } -+ } else { -+ *user_sc = *default_sc; -+ } -+ } -+ if (r != 0) { -+ error("%s: Failed to get default SELinux security " -+ "context for %s", __func__, pwname); - } - - #ifdef HAVE_GETSEUSERBYNAME -@@ -102,7 +305,42 @@ ssh_selinux_getctxbyname(char *pwname) - xfree(lvl); - #endif - -- return sc; -+ if (role != NULL) -+ xfree(role); -+ if (con) -+ context_free(con); -+ -+ return (r); -+} -+ -+/* Setup environment variables for pam_selinux */ -+static int -+ssh_selinux_setup_pam_variables(void) -+{ -+ const char *reqlvl; -+ char *role; -+ char *use_current; -+ int rv; -+ -+ debug3("%s: setting execution context", __func__); -+ -+ ssh_selinux_get_role_level(&role, &reqlvl); -+ -+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); -+ -+ if (inetd_flag && !rexeced_flag) { -+ use_current = "1"; -+ } else { -+ use_current = ""; -+ rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); -+ } -+ -+ rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); -+ -+ if (role != NULL) -+ xfree(role); -+ -+ return rv; - } - - /* Set the execution context to the default for the specified user */ -@@ -110,28 +348,71 @@ void - ssh_selinux_setup_exec_context(char *pwname) - { - security_context_t user_ctx = NULL; -+ int r = 0; -+ security_context_t default_ctx = NULL; - - if (!ssh_selinux_enabled()) - return; - -+ if (options.use_pam) { -+ /* do not compute context, just setup environment for pam_selinux */ -+ if (ssh_selinux_setup_pam_variables()) { -+ switch (security_getenforce()) { -+ case -1: -+ fatal("%s: security_getenforce() failed", __func__); -+ case 0: -+ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", -+ __func__); -+ break; -+ default: -+ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", -+ __func__); -+ } -+ } -+ return; -+ } -+ - debug3("%s: setting execution context", __func__); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -- if (setexeccon(user_ctx) != 0) { -+ r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); -+ if (r >= 0) { -+ r = setexeccon(user_ctx); -+ if (r < 0) { -+ error("%s: Failed to set SELinux execution context %s for %s", -+ __func__, user_ctx, pwname); -+ } -+#ifdef HAVE_SETKEYCREATECON -+ else if (setkeycreatecon(user_ctx) < 0) { -+ error("%s: Failed to set SELinux keyring creation context %s for %s", -+ __func__, user_ctx, pwname); -+ } -+#endif -+ } -+ if (user_ctx == NULL) { -+ user_ctx = default_ctx; -+ } -+ if (r < 0 || user_ctx != default_ctx) { -+ /* audit just the case when user changed a role or there was -+ a failure */ -+ send_audit_message(r >= 0, default_ctx, user_ctx); -+ } -+ if (r < 0) { - switch (security_getenforce()) { - case -1: - fatal("%s: security_getenforce() failed", __func__); - case 0: -- error("%s: Failed to set SELinux execution " -- "context for %s", __func__, pwname); -+ error("%s: SELinux failure. Continuing in permissive mode.", -+ __func__); - break; - default: -- fatal("%s: Failed to set SELinux execution context " -- "for %s (in enforcing mode)", __func__, pwname); -+ fatal("%s: SELinux failure. Aborting connection.", -+ __func__); - } - } -- if (user_ctx != NULL) -+ if (user_ctx != NULL && user_ctx != default_ctx) - freecon(user_ctx); -+ if (default_ctx != NULL) -+ freecon(default_ctx); - - debug3("%s: done", __func__); - } -@@ -149,7 +430,10 @@ ssh_selinux_setup_pty(char *pwname, cons - - debug3("%s: setting TTY context on %s", __func__, tty); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -+ if (getexeccon(&user_ctx) < 0) { -+ error("%s: getexeccon: %s", __func__, strerror(errno)); -+ goto out; -+ } - - /* XXX: should these calls fatal() upon failure in enforcing mode? */ - -@@ -221,21 +505,6 @@ ssh_selinux_change_context(const char *n - xfree(newctx); - } - --void --ssh_selinux_setfscreatecon(const char *path) --{ -- security_context_t context; -- -- if (!ssh_selinux_enabled()) -- return; -- if (path == NULL) { -- setfscreatecon(NULL); -- return; -- } -- if (matchpathcon(path, 0700, &context) == 0) -- setfscreatecon(context); --} -- - #endif /* WITH_SELINUX */ - - #ifdef LINUX_OOM_ADJUST -diff -up openssh-6.1p1/openbsd-compat/port-linux_part_2.c.role-mls openssh-6.1p1/openbsd-compat/port-linux_part_2.c ---- openssh-6.1p1/openbsd-compat/port-linux_part_2.c.role-mls 2012-11-28 17:06:43.703989944 +0100 -+++ openssh-6.1p1/openbsd-compat/port-linux_part_2.c 2012-11-28 17:06:43.703989944 +0100 -@@ -0,0 +1,75 @@ -+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ -+ -+/* -+ * Copyright (c) 2005 Daniel Walsh -+ * Copyright (c) 2006 Damien Miller -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/* -+ * Linux-specific portability code - just SELinux support at present -+ */ -+ -+#include "includes.h" -+ -+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) -+#include -+#include -+#include -+#include -+ -+#include "log.h" -+#include "xmalloc.h" -+#include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" -+ -+#ifdef WITH_SELINUX -+#include -+#include -+#include -+ -+/* Wrapper around is_selinux_enabled() to log its return value once only */ -+int -+ssh_selinux_enabled(void) -+{ -+ static int enabled = -1; -+ -+ if (enabled == -1) { -+ enabled = (is_selinux_enabled() == 1); -+ debug("SELinux support %s", enabled ? "enabled" : "disabled"); -+ } -+ -+ return (enabled); -+} -+ -+void -+ssh_selinux_setfscreatecon(const char *path) -+{ -+ security_context_t context; -+ -+ if (!ssh_selinux_enabled()) -+ return; -+ if (path == NULL) { -+ setfscreatecon(NULL); -+ return; -+ } -+ if (matchpathcon(path, 0700, &context) == 0) -+ setfscreatecon(context); -+} -+ -+#endif /* WITH_SELINUX */ -+ -+#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ -diff -up openssh-6.1p1/sshd.c.role-mls openssh-6.1p1/sshd.c ---- openssh-6.1p1/sshd.c.role-mls 2012-11-28 17:06:43.688989996 +0100 -+++ openssh-6.1p1/sshd.c 2012-11-28 17:06:43.703989944 +0100 -@@ -2101,6 +2101,9 @@ main(int ac, char **av) - restore_uid(); - } - #endif -+#ifdef WITH_SELINUX -+ ssh_selinux_setup_exec_context(authctxt->pw->pw_name); -+#endif - #ifdef USE_PAM - if (options.use_pam) { - do_pam_setcred(1); diff --git a/openssh/patches/openssh-6.1p1-vendor.patch b/openssh/patches/openssh-6.1p1-vendor.patch deleted file mode 100644 index 9cb326d39..000000000 --- a/openssh/patches/openssh-6.1p1-vendor.patch +++ /dev/null @@ -1,158 +0,0 @@ -diff -up openssh-6.1p1/configure.ac.vendor openssh-6.1p1/configure.ac ---- openssh-6.1p1/configure.ac.vendor 2012-09-14 20:36:49.153085211 +0200 -+++ openssh-6.1p1/configure.ac 2012-09-14 20:36:49.559088133 +0200 -@@ -4303,6 +4303,12 @@ AC_ARG_WITH([lastlog], - fi - ] - ) -+AC_ARG_ENABLE(vendor-patchlevel, -+ [ --enable-vendor-patchlevel=TAG specify a vendor patch level], -+ [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.]) -+ SSH_VENDOR_PATCHLEVEL="$enableval"], -+ [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.]) -+ SSH_VENDOR_PATCHLEVEL=none]) - - dnl lastlog, [uw]tmpx? detection - dnl NOTE: set the paths in the platform section to avoid the -@@ -4529,6 +4535,7 @@ echo " Translate v4 in v6 hack - echo " BSD Auth support: $BSD_AUTH_MSG" - echo " Random number source: $RAND_MSG" - echo " Privsep sandbox style: $SANDBOX_STYLE" -+echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL" - - echo "" - -diff -up openssh-6.1p1/servconf.c.vendor openssh-6.1p1/servconf.c ---- openssh-6.1p1/servconf.c.vendor 2012-09-14 20:36:49.124085002 +0200 -+++ openssh-6.1p1/servconf.c 2012-09-14 20:50:34.995972516 +0200 -@@ -128,6 +128,7 @@ initialize_server_options(ServerOptions - options->max_authtries = -1; - options->max_sessions = -1; - options->banner = NULL; -+ options->show_patchlevel = -1; - options->use_dns = -1; - options->client_alive_interval = -1; - options->client_alive_count_max = -1; -@@ -289,6 +290,9 @@ fill_default_server_options(ServerOption - options->ip_qos_bulk = IPTOS_THROUGHPUT; - if (options->version_addendum == NULL) - options->version_addendum = xstrdup(""); -+ if (options->show_patchlevel == -1) -+ options->show_patchlevel = 0; -+ - /* Turn privilege separation on by default */ - if (use_privsep == -1) - use_privsep = PRIVSEP_NOSANDBOX; -@@ -326,7 +330,7 @@ typedef enum { - sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, - sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, - sMaxStartups, sMaxAuthTries, sMaxSessions, -- sBanner, sUseDNS, sHostbasedAuthentication, -+ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, -@@ -441,6 +445,7 @@ static struct { - { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, - { "maxsessions", sMaxSessions, SSHCFG_ALL }, - { "banner", sBanner, SSHCFG_ALL }, -+ { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL }, - { "usedns", sUseDNS, SSHCFG_GLOBAL }, - { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, - { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, -@@ -1162,6 +1167,10 @@ process_server_config_line(ServerOptions - multistate_ptr = multistate_privsep; - goto parse_multistate; - -+ case sShowPatchLevel: -+ intptr = &options->show_patchlevel; -+ goto parse_flag; -+ - case sAllowUsers: - while ((arg = strdelim(&cp)) && *arg != '\0') { - if (options->num_allow_users >= MAX_ALLOW_USERS) -@@ -1956,6 +1965,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUseLogin, o->use_login); - dump_cfg_fmtint(sCompression, o->compression); - dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); -+ dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); -diff -up openssh-6.1p1/servconf.h.vendor openssh-6.1p1/servconf.h ---- openssh-6.1p1/servconf.h.vendor 2012-09-14 20:36:49.125085009 +0200 -+++ openssh-6.1p1/servconf.h 2012-09-14 20:36:49.564088168 +0200 -@@ -140,6 +140,7 @@ typedef struct { - int max_authtries; - int max_sessions; - char *banner; /* SSH-2 banner message */ -+ int show_patchlevel; /* Show vendor patch level to clients */ - int use_dns; - int client_alive_interval; /* - * poke the client this often to -diff -up openssh-6.1p1/sshd_config.vendor openssh-6.1p1/sshd_config ---- openssh-6.1p1/sshd_config.vendor 2012-09-14 20:36:49.507087759 +0200 -+++ openssh-6.1p1/sshd_config 2012-09-14 20:36:49.565088175 +0200 -@@ -114,6 +114,7 @@ UsePrivilegeSeparation sandbox # Defaul - #Compression delayed - #ClientAliveInterval 0 - #ClientAliveCountMax 3 -+#ShowPatchLevel no - #UseDNS yes - #PidFile /var/run/sshd.pid - #MaxStartups 10 -diff -up openssh-6.1p1/sshd_config.0.vendor openssh-6.1p1/sshd_config.0 ---- openssh-6.1p1/sshd_config.0.vendor 2012-09-14 20:36:49.510087780 +0200 -+++ openssh-6.1p1/sshd_config.0 2012-09-14 20:36:49.567088190 +0200 -@@ -558,6 +558,11 @@ DESCRIPTION - Defines the number of bits in the ephemeral protocol version 1 - server key. The minimum value is 512, and the default is 1024. - -+ ShowPatchLevel -+ Specifies whether sshd will display the specific patch level of -+ the binary in the server identification string. The patch level -+ is set at compile-time. The default is M-bM-^@M-^\noM-bM-^@M-^]. -+ - StrictModes - Specifies whether sshd(8) should check file modes and ownership - of the user's files and home directory before accepting login. -diff -up openssh-6.1p1/sshd_config.5.vendor openssh-6.1p1/sshd_config.5 ---- openssh-6.1p1/sshd_config.5.vendor 2012-09-14 20:36:49.512087794 +0200 -+++ openssh-6.1p1/sshd_config.5 2012-09-14 20:36:49.568088198 +0200 -@@ -978,6 +978,14 @@ This option applies to protocol version - .It Cm ServerKeyBits - Defines the number of bits in the ephemeral protocol version 1 server key. - The minimum value is 512, and the default is 1024. -+.It Cm ShowPatchLevel -+Specifies whether -+.Nm sshd -+will display the patch level of the binary in the identification string. -+The patch level is set at compile-time. -+The default is -+.Dq no . -+This option applies to protocol version 1 only. - .It Cm StrictModes - Specifies whether - .Xr sshd 8 -diff -up openssh-6.1p1/sshd.c.vendor openssh-6.1p1/sshd.c ---- openssh-6.1p1/sshd.c.vendor 2012-09-14 20:36:49.399086981 +0200 -+++ openssh-6.1p1/sshd.c 2012-09-14 20:47:30.696088744 +0200 -@@ -433,7 +433,7 @@ sshd_exchange_identification(int sock_in - } - - xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", -- major, minor, SSH_VERSION, -+ major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, - *options.version_addendum == '\0' ? "" : " ", - options.version_addendum, newline); - -@@ -1635,7 +1635,8 @@ main(int ac, char **av) - exit(1); - } - -- debug("sshd version %.100s", SSH_RELEASE); -+ debug("sshd version %.100s", -+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_RELEASE); - - /* Store privilege separation user for later use if required. */ - if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { diff --git a/openssh/patches/openssh-5.8p1-keyperm.patch b/openssh/patches/openssh-6.6p1-keyperm.patch similarity index 54% rename from openssh/patches/openssh-5.8p1-keyperm.patch rename to openssh/patches/openssh-6.6p1-keyperm.patch index 6167c149d..fbe33b0e1 100644 --- a/openssh/patches/openssh-5.8p1-keyperm.patch +++ b/openssh/patches/openssh-6.6p1-keyperm.patch @@ -1,15 +1,16 @@ -diff -up openssh-5.8p1/authfile.c.keyperm openssh-5.8p1/authfile.c ---- openssh-5.8p1/authfile.c.keyperm 2010-12-01 02:03:39.000000000 +0100 -+++ openssh-5.8p1/authfile.c 2011-04-21 16:43:36.859648916 +0200 -@@ -57,6 +57,7 @@ - #include - #include - #include -+#include +diff --git a/authfile.c b/authfile.c +index e93d867..4fc5b3d 100644 +--- a/authfile.c ++++ b/authfile.c +@@ -32,6 +32,7 @@ - #include "xmalloc.h" - #include "cipher.h" -@@ -600,6 +612,13 @@ key_perm_ok(int fd, const char *filename + #include + #include ++#include + #include + #include + #include +@@ -207,6 +208,13 @@ sshkey_perm_ok(int fd, const char *filename) #ifdef HAVE_CYGWIN if (check_ntsec(filename)) #endif diff --git a/openssh/patches/openssh-6.7p1-audit.patch b/openssh/patches/openssh-6.7p1-audit.patch new file mode 100644 index 000000000..213ca6716 --- /dev/null +++ b/openssh/patches/openssh-6.7p1-audit.patch @@ -0,0 +1,2332 @@ +diff -up openssh-6.8p1/Makefile.in.audit openssh-6.8p1/Makefile.in +--- openssh-6.8p1/Makefile.in.audit 2015-03-20 13:41:15.065883826 +0100 ++++ openssh-6.8p1/Makefile.in 2015-03-20 13:41:15.100883769 +0100 +@@ -98,7 +98,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ +- kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o ++ kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o auditstub.o + + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ + sshconnect.o sshconnect1.o sshconnect2.o mux.o \ +diff -up openssh-6.8p1/audit-bsm.c.audit openssh-6.8p1/audit-bsm.c +--- openssh-6.8p1/audit-bsm.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/audit-bsm.c 2015-03-20 13:41:15.092883782 +0100 +@@ -375,10 +375,23 @@ audit_connection_from(const char *host, + #endif + } + +-void ++int + audit_run_command(const char *command) + { + /* not implemented */ ++ return 0; ++} ++ ++void ++audit_end_command(int handle, const char *command) ++{ ++ /* not implemented */ ++} ++ ++void ++audit_count_session_open(void) ++{ ++ /* not necessary */ + } + + void +@@ -393,6 +406,12 @@ audit_session_close(struct logininfo *li) + /* not implemented */ + } + ++int ++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) ++{ ++ /* not implemented */ ++} ++ + void + audit_event(ssh_audit_event_t event) + { +@@ -454,4 +473,40 @@ audit_event(ssh_audit_event_t event) + debug("%s: unhandled event %d", __func__, event); + } + } ++ ++void ++audit_unsupported_body(int what) ++{ ++ /* not implemented */ ++} ++ ++void ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) ++{ ++ /* not implemented */ ++} ++ ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ /* not implemented */ ++} ++ ++void ++audit_destroy_sensitive_data(const char *fp) ++{ ++ /* not implemented */ ++} ++ ++void ++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++{ ++ /* not implemented */ ++} ++ ++void ++audit_generate_ephemeral_server_key(const char *fp) ++{ ++ /* not implemented */ ++} + #endif /* BSM */ +diff -up openssh-6.8p1/audit-linux.c.audit openssh-6.8p1/audit-linux.c +--- openssh-6.8p1/audit-linux.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/audit-linux.c 2015-03-20 13:41:15.093883780 +0100 +@@ -35,13 +35,25 @@ + + #include "log.h" + #include "audit.h" ++#include "key.h" ++#include "hostfile.h" ++#include "auth.h" ++#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ ++#include "servconf.h" + #include "canohost.h" ++#include "packet.h" ++#include "cipher.h" + ++#define AUDIT_LOG_SIZE 256 ++ ++extern ServerOptions options; ++extern Authctxt *the_authctxt; ++extern u_int utmp_len; + const char* audit_username(void); + +-int +-linux_audit_record_event(int uid, const char *username, +- const char *hostname, const char *ip, const char *ttyn, int success) ++static void ++linux_audit_user_logxxx(int uid, const char *username, ++ const char *hostname, const char *ip, const char *ttyn, int success, int event) + { + int audit_fd, rc, saved_errno; + +@@ -49,11 +61,11 @@ linux_audit_record_event(int uid, const char *username, + if (audit_fd < 0) { + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) +- return 1; /* No audit support in kernel */ ++ return; /* No audit support in kernel */ + else +- return 0; /* Must prevent login */ ++ goto fatal_report; /* Must prevent login */ + } +- rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, ++ rc = audit_log_acct_message(audit_fd, event, + NULL, "login", username ? username : "(unknown)", + username == NULL ? uid : -1, hostname, ip, ttyn, success); + saved_errno = errno; +@@ -65,35 +77,154 @@ linux_audit_record_event(int uid, const char *username, + if ((rc == -EPERM) && (geteuid() != 0)) + rc = 0; + errno = saved_errno; +- return (rc >= 0); ++ if (rc < 0) { ++fatal_report: ++ fatal("linux_audit_write_entry failed: %s", strerror(errno)); ++ } + } + ++static void ++linux_audit_user_auth(int uid, const char *username, ++ const char *hostname, const char *ip, const char *ttyn, int success, int event) ++{ ++ int audit_fd, rc, saved_errno; ++ static const char *event_name[] = { ++ "maxtries exceeded", ++ "root denied", ++ "success", ++ "none", ++ "password", ++ "challenge-response", ++ "pubkey", ++ "hostbased", ++ "gssapi", ++ "invalid user", ++ "nologin", ++ "connection closed", ++ "connection abandoned", ++ "unknown" ++ }; ++ ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return; /* No audit support in kernel */ ++ else ++ goto fatal_report; /* Must prevent login */ ++ } ++ ++ if ((event < 0) || (event > SSH_AUDIT_UNKNOWN)) ++ event = SSH_AUDIT_UNKNOWN; ++ ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, ++ NULL, event_name[event], username ? username : "(unknown)", ++ username == NULL ? uid : -1, hostname, ip, ttyn, success); ++ saved_errno = errno; ++ close(audit_fd); ++ /* ++ * Do not report error if the error is EPERM and sshd is run as non ++ * root user. ++ */ ++ if ((rc == -EPERM) && (geteuid() != 0)) ++ rc = 0; ++ errno = saved_errno; ++ if (rc < 0) { ++fatal_report: ++ fatal("linux_audit_write_entry failed: %s", strerror(errno)); ++ } ++} ++ ++int ++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, rc, saved_errno; ++ ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return 1; /* No audit support in kernel */ ++ else ++ return 0; /* Must prevent login */ ++ } ++ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port()); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); ++ if ((rc < 0) && ((rc != -1) || (getuid() == 0))) ++ goto out; ++ /* is the fingerprint_prefix() still needed? ++ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s rport=%d", ++ type, bits, sshkey_fingerprint_prefix(), fp, get_remote_port()); ++ */ ++ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d", ++ type, bits, fp, get_remote_port()); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); ++out: ++ saved_errno = errno; ++ audit_close(audit_fd); ++ errno = saved_errno; ++ /* do not report error if the error is EPERM and sshd is run as non root user */ ++ return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0)); ++} ++ ++static int user_login_count = 0; ++ + /* Below is the sshd audit API code */ + + void + audit_connection_from(const char *host, int port) + { +-} + /* not implemented */ ++} + +-void ++int + audit_run_command(const char *command) + { +- /* not implemented */ ++ if (!user_login_count++) ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_LOGIN); ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_START); ++ return 0; ++} ++ ++void ++audit_end_command(int handle, const char *command) ++{ ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_END); ++ if (user_login_count && !--user_login_count) ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_LOGOUT); ++} ++ ++void ++audit_count_session_open(void) ++{ ++ user_login_count++; + } + + void + audit_session_open(struct logininfo *li) + { +- if (linux_audit_record_event(li->uid, NULL, li->hostname, +- NULL, li->line, 1) == 0) +- fatal("linux_audit_write_entry failed: %s", strerror(errno)); ++ if (!user_login_count++) ++ linux_audit_user_logxxx(li->uid, NULL, li->hostname, ++ NULL, li->line, 1, AUDIT_USER_LOGIN); ++ linux_audit_user_logxxx(li->uid, NULL, li->hostname, ++ NULL, li->line, 1, AUDIT_USER_START); + } + + void + audit_session_close(struct logininfo *li) + { +- /* not implemented */ ++ linux_audit_user_logxxx(li->uid, NULL, li->hostname, ++ NULL, li->line, 1, AUDIT_USER_END); ++ if (user_login_count && !--user_login_count) ++ linux_audit_user_logxxx(li->uid, NULL, li->hostname, ++ NULL, li->line, 1, AUDIT_USER_LOGOUT); + } + + void +@@ -101,21 +232,43 @@ audit_event(ssh_audit_event_t event) + { + switch(event) { + case SSH_AUTH_SUCCESS: +- case SSH_CONNECTION_CLOSE: ++ linux_audit_user_auth(-1, audit_username(), NULL, ++ get_remote_ipaddr(), "ssh", 1, event); ++ break; ++ + case SSH_NOLOGIN: +- case SSH_LOGIN_EXCEED_MAXTRIES: + case SSH_LOGIN_ROOT_DENIED: ++ linux_audit_user_auth(-1, audit_username(), NULL, ++ get_remote_ipaddr(), "ssh", 0, event); ++ linux_audit_user_logxxx(-1, audit_username(), NULL, ++ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); + break; + ++ case SSH_LOGIN_EXCEED_MAXTRIES: + case SSH_AUTH_FAIL_NONE: + case SSH_AUTH_FAIL_PASSWD: + case SSH_AUTH_FAIL_KBDINT: + case SSH_AUTH_FAIL_PUBKEY: + case SSH_AUTH_FAIL_HOSTBASED: + case SSH_AUTH_FAIL_GSSAPI: ++ linux_audit_user_auth(-1, audit_username(), NULL, ++ get_remote_ipaddr(), "ssh", 0, event); ++ break; ++ ++ case SSH_CONNECTION_CLOSE: ++ if (user_login_count) { ++ while (user_login_count--) ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_END); ++ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns), ++ NULL, "ssh", 1, AUDIT_USER_LOGOUT); ++ } ++ break; ++ ++ case SSH_CONNECTION_ABANDON: + case SSH_INVALID_USER: +- linux_audit_record_event(-1, audit_username(), NULL, +- get_remote_ipaddr(), "sshd", 0); ++ linux_audit_user_logxxx(-1, audit_username(), NULL, ++ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN); + break; + + default: +@@ -123,4 +276,135 @@ audit_event(ssh_audit_event_t event) + } + } + ++void ++audit_unsupported_body(int what) ++{ ++#ifdef AUDIT_CRYPTO_SESSION ++ char buf[AUDIT_LOG_SIZE]; ++ const static char *name[] = { "cipher", "mac", "comp" }; ++ char *s; ++ int audit_fd; ++ ++ snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ", ++ name[what], get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), ++ get_local_port()); ++ free(s); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) ++ /* no problem, the next instruction will be fatal() */ ++ return; ++ audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, ++ buf, NULL, get_remote_ipaddr(), NULL, 0); ++ audit_close(audit_fd); ++#endif ++} ++ ++const static char *direction[] = { "from-server", "from-client", "both" }; ++ ++void ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, ++ uid_t uid) ++{ ++#ifdef AUDIT_CRYPTO_SESSION ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ const Cipher *cipher = cipher_by_name(enc); ++ char *s; ++ ++ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", ++ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, ++ (intmax_t)pid, (intmax_t)uid, ++ get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port()); ++ free(s); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return; /* No audit support in kernel */ ++ else ++ fatal("cannot open audit"); /* Must prevent login */ ++ } ++ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION, ++ buf, NULL, get_remote_ipaddr(), NULL, 1); ++ audit_close(audit_fd); ++ /* do not abort if the error is EPERM and sshd is run as non root user */ ++ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) ++ fatal("cannot write into audit"); /* Must prevent login */ ++#endif ++} ++ ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ char *s; ++ ++ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", ++ direction[ctos], (intmax_t)pid, (intmax_t)uid, ++ get_remote_port(), ++ (s = get_local_ipaddr(packet_get_connection_in())), ++ get_local_port()); ++ free(s); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno != EINVAL && errno != EPROTONOSUPPORT && ++ errno != EAFNOSUPPORT) ++ error("cannot open audit"); ++ return; ++ } ++ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, ++ buf, NULL, get_remote_ipaddr(), NULL, 1); ++ audit_close(audit_fd); ++ /* do not abort if the error is EPERM and sshd is run as non root user */ ++ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) ++ error("cannot write into audit"); ++} ++ ++void ++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ ++ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ", ++ fp, (intmax_t)pid, (intmax_t)uid); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno != EINVAL && errno != EPROTONOSUPPORT && ++ errno != EAFNOSUPPORT) ++ error("cannot open audit"); ++ return; ++ } ++ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, ++ buf, NULL, ++ listening_for_clients() ? get_remote_ipaddr() : NULL, ++ NULL, 1); ++ audit_close(audit_fd); ++ /* do not abort if the error is EPERM and sshd is run as non root user */ ++ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) ++ error("cannot write into audit"); ++} ++ ++void ++audit_generate_ephemeral_server_key(const char *fp) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ ++ snprintf(buf, sizeof(buf), "op=create kind=server fp=%s direction=? ", fp); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno != EINVAL && errno != EPROTONOSUPPORT && ++ errno != EAFNOSUPPORT) ++ error("cannot open audit"); ++ return; ++ } ++ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, ++ buf, NULL, 0, NULL, 1); ++ audit_close(audit_fd); ++ /* do not abort if the error is EPERM and sshd is run as non root user */ ++ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) ++ error("cannot write into audit"); ++} + #endif /* USE_LINUX_AUDIT */ +diff -up openssh-6.8p1/audit.c.audit openssh-6.8p1/audit.c +--- openssh-6.8p1/audit.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/audit.c 2015-03-20 13:41:15.093883780 +0100 +@@ -28,6 +28,7 @@ + + #include + #include ++#include + + #ifdef SSH_AUDIT_EVENTS + +@@ -36,6 +37,11 @@ + #include "key.h" + #include "hostfile.h" + #include "auth.h" ++#include "ssh-gss.h" ++#include "monitor_wrap.h" ++#include "xmalloc.h" ++#include "misc.h" ++#include "servconf.h" + + /* + * Care must be taken when using this since it WILL NOT be initialized when +@@ -43,6 +49,7 @@ + * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. + */ + extern Authctxt *the_authctxt; ++extern ServerOptions options; + + /* Maybe add the audit class to struct Authmethod? */ + ssh_audit_event_t +@@ -71,13 +78,10 @@ audit_classify_auth(const char *method) + const char * + audit_username(void) + { +- static const char unknownuser[] = "(unknown user)"; +- static const char invaliduser[] = "(invalid user)"; ++ static const char unknownuser[] = "(unknown)"; + +- if (the_authctxt == NULL || the_authctxt->user == NULL) ++ if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid) + return (unknownuser); +- if (!the_authctxt->valid) +- return (invaliduser); + return (the_authctxt->user); + } + +@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev) + return(event_lookup[i].name); + } + ++void ++audit_key(int host_user, int *rv, const Key *key) ++{ ++ char *fp; ++ const char *crypto_name; ++ ++ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (key->type == KEY_RSA1) ++ crypto_name = "ssh-rsa1"; ++ else ++ crypto_name = key_ssh_name(key); ++ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0) ++ *rv = 0; ++ free(fp); ++} ++ ++void ++audit_unsupported(int what) ++{ ++ PRIVSEP(audit_unsupported_body(what)); ++} ++ ++void ++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) ++{ ++ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); ++} ++ ++void ++audit_session_key_free(int ctos) ++{ ++ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); ++} ++ + # ifndef CUSTOM_SSH_AUDIT_EVENTS + /* + * Null implementations of audit functions. +@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event) + } + + /* ++ * Called when a child process has called, or will soon call, ++ * audit_session_open. ++ */ ++void ++audit_count_session_open(void) ++{ ++ debug("audit count session open euid %d user %s", geteuid(), ++ audit_username()); ++} ++ ++/* + * Called when a user session is started. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * +@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li) + /* + * This will be called when a user runs a non-interactive command. Note that + * it may be called multiple times for a single connection since SSH2 allows +- * multiple sessions within a single connection. ++ * multiple sessions within a single connection. Returns a "handle" for ++ * audit_end_command. + */ +-void ++int + audit_run_command(const char *command) + { + debug("audit run command euid %d user %s command '%.200s'", geteuid(), + audit_username(), command); ++ return 0; ++} ++ ++/* ++ * This will be called when the non-interactive command finishes. Note that ++ * it may be called multiple times for a single connection since SSH2 allows ++ * multiple sessions within a single connection. "handle" should come from ++ * the corresponding audit_run_command. ++ */ ++void ++audit_end_command(int handle, const char *command) ++{ ++ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(), ++ audit_username(), command); ++} ++ ++/* ++ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key. ++ * ++ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. ++ */ ++int ++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv) ++{ ++ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d", ++ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits, ++ sshkey_fingerprint_prefix(), fp, rv); ++} ++ ++/* ++ * This will be called when the protocol negotiation fails. ++ */ ++void ++audit_unsupported_body(int what) ++{ ++ debug("audit unsupported protocol euid %d type %d", geteuid(), what); ++} ++ ++/* ++ * This will be called on succesfull protocol negotiation. ++ */ ++void ++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, ++ uid_t uid) ++{ ++ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, ++ (unsigned)uid); ++} ++ ++/* ++ * This will be called on succesfull session key discard ++ */ ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ debug("audit session key discard euid %u direction %d from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); ++} ++ ++/* ++ * This will be called on destroy private part of the server key ++ */ ++void ++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++{ ++ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", ++ geteuid(), fp, (long)pid, (unsigned)uid); ++} ++ ++/* ++ * This will be called on generation of the ephemeral server key ++ */ ++void ++audit_generate_ephemeral_server_key(const char *) ++{ ++ debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp); + } + # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ + #endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-6.8p1/audit.h.audit openssh-6.8p1/audit.h +--- openssh-6.8p1/audit.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/audit.h 2015-03-20 13:41:15.093883780 +0100 +@@ -28,6 +28,7 @@ + # define _SSH_AUDIT_H + + #include "loginrec.h" ++#include "key.h" + + enum ssh_audit_event_type { + SSH_LOGIN_EXCEED_MAXTRIES, +@@ -47,11 +48,25 @@ enum ssh_audit_event_type { + }; + typedef enum ssh_audit_event_type ssh_audit_event_t; + ++int listening_for_clients(void); ++ + void audit_connection_from(const char *, int); + void audit_event(ssh_audit_event_t); ++void audit_count_session_open(void); + void audit_session_open(struct logininfo *); + void audit_session_close(struct logininfo *); +-void audit_run_command(const char *); ++int audit_run_command(const char *); ++void audit_end_command(int, const char *); + ssh_audit_event_t audit_classify_auth(const char *); ++int audit_keyusage(int, const char *, unsigned, char *, int); ++void audit_key(int, int *, const Key *); ++void audit_unsupported(int); ++void audit_kex(int, char *, char *, char *, char *); ++void audit_unsupported_body(int); ++void audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); ++void audit_session_key_free(int ctos); ++void audit_session_key_free_body(int ctos, pid_t, uid_t); ++void audit_destroy_sensitive_data(const char *, pid_t, uid_t); ++void audit_generate_ephemeral_server_key(const char *); + + #endif /* _SSH_AUDIT_H */ +diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c +--- openssh-6.8p1/auditstub.c.audit 2015-03-20 13:41:15.093883780 +0100 ++++ openssh-6.8p1/auditstub.c 2015-03-20 13:41:15.093883780 +0100 +@@ -0,0 +1,50 @@ ++/* $Id: auditstub.c,v 1.1 jfch Exp $ */ ++ ++/* ++ * Copyright 2010 Red Hat, Inc. All rights reserved. ++ * Use is subject to license terms. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * Red Hat author: Jan F. Chadima ++ */ ++ ++#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-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c +--- openssh-6.8p1/auth-rsa.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth-rsa.c 2015-03-20 13:41:15.094883779 +0100 +@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) + { + u_char buf[32], mdbuf[16]; + struct ssh_digest_ctx *md; +- int len; ++ int len, rv; ++#ifdef SSH_AUDIT_EVENTS ++ char *fp; ++#endif + + /* don't allow short keys */ + if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { +@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) + ssh_digest_free(md); + + /* Verify that the response is the original challenge. */ +- if (timingsafe_bcmp(response, mdbuf, 16) != 0) { +- /* Wrong answer. */ +- return (0); ++ rv = timingsafe_bcmp(response, mdbuf, 16) == 0; ++ ++#ifdef SSH_AUDIT_EVENTS ++ fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX); ++ if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) { ++ debug("unsuccessful audit"); ++ rv = 0; + } +- /* Correct answer. */ +- return (1); ++ free(fp); ++#endif ++ ++ return rv; + } + + /* +diff -up openssh-6.8p1/auth.c.audit openssh-6.8p1/auth.c +--- openssh-6.8p1/auth.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/auth.c 2015-03-20 13:41:15.094883779 +0100 +@@ -644,9 +644,6 @@ getpwnamallow(const char *user) + record_failed_login(user, + get_canonical_hostname(options.use_dns), "ssh"); + #endif +-#ifdef SSH_AUDIT_EVENTS +- audit_event(SSH_INVALID_USER); +-#endif /* SSH_AUDIT_EVENTS */ + return (NULL); + } + if (!allowed_user(pw)) +diff -up openssh-6.8p1/auth.h.audit openssh-6.8p1/auth.h +--- openssh-6.8p1/auth.h.audit 2015-03-20 13:41:15.002883927 +0100 ++++ openssh-6.8p1/auth.h 2015-03-20 13:41:15.094883779 +0100 +@@ -195,6 +195,7 @@ void abandon_challenge_response(Authctxt + + char *expand_authorized_keys(const char *, struct passwd *pw); + char *authorized_principals_file(struct passwd *); ++int user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); + + FILE *auth_openkeyfile(const char *, struct passwd *, int); + FILE *auth_openprincipals(const char *, struct passwd *, int); +@@ -213,6 +214,7 @@ int get_hostkey_index(Key *, int, struc + int ssh1_session_key(BIGNUM *); + int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, + const u_char *, size_t, u_int); ++int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); + + /* debug messages during authentication */ + void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); +diff -up openssh-6.8p1/auth2-hostbased.c.audit openssh-6.8p1/auth2-hostbased.c +--- openssh-6.8p1/auth2-hostbased.c.audit 2015-03-20 13:41:15.002883927 +0100 ++++ openssh-6.8p1/auth2-hostbased.c 2015-03-20 13:41:15.093883780 +0100 +@@ -147,7 +147,7 @@ userauth_hostbased(Authctxt *authctxt) + /* test for allowed key and correct signature */ + authenticated = 0; + if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && +- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), ++ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b), + buffer_len(&b))) == 1) + authenticated = 1; + +@@ -164,6 +164,18 @@ done: + return authenticated; + } + ++int ++hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) ++{ ++ int rv; ++ ++ rv = key_verify(key, sig, slen, data, datalen); ++#ifdef SSH_AUDIT_EVENTS ++ audit_key(0, &rv, key); ++#endif ++ return rv; ++} ++ + /* return 1 if given hostkey is allowed */ + int + hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, +diff -up openssh-6.8p1/auth2-pubkey.c.audit openssh-6.8p1/auth2-pubkey.c +--- openssh-6.8p1/auth2-pubkey.c.audit 2015-03-20 13:41:15.013883910 +0100 ++++ openssh-6.8p1/auth2-pubkey.c 2015-03-20 13:41:15.094883779 +0100 +@@ -172,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt) + /* test for correct signature */ + authenticated = 0; + if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && +- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), ++ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b), + buffer_len(&b))) == 1) { + authenticated = 1; + /* Record the successful key to prevent reuse */ +@@ -250,6 +250,18 @@ pubkey_auth_info(Authctxt *authctxt, con + free(extra); + } + ++int ++user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) ++{ ++ int rv; ++ ++ rv = key_verify(key, sig, slen, data, datalen); ++#ifdef SSH_AUDIT_EVENTS ++ audit_key(1, &rv, key); ++#endif ++ return rv; ++} ++ + static int + match_principals_option(const char *principal_list, struct sshkey_cert *cert) + { +diff -up openssh-6.8p1/auth2.c.audit openssh-6.8p1/auth2.c +--- openssh-6.8p1/auth2.c.audit 2015-03-20 13:41:15.044883860 +0100 ++++ openssh-6.8p1/auth2.c 2015-03-20 13:41:15.093883780 +0100 +@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32 + } else { + logit("input_userauth_request: invalid user %s", user); + authctxt->pw = fakepw(); +-#ifdef SSH_AUDIT_EVENTS +- PRIVSEP(audit_event(SSH_INVALID_USER)); +-#endif + } + #ifdef USE_PAM + if (options.use_pam) +diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c +--- openssh-6.8p1/cipher.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/cipher.c 2015-03-20 13:41:15.101883767 +0100 +@@ -57,26 +59,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v + extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); + #endif + +-struct sshcipher { +- char *name; +- int number; /* for ssh1 only */ +- u_int block_size; +- u_int key_len; +- u_int iv_len; /* defaults to block_size */ +- u_int auth_len; +- u_int discard_len; +- u_int flags; +-#define CFLAG_CBC (1<<0) +-#define CFLAG_CHACHAPOLY (1<<1) +-#define CFLAG_AESCTR (1<<2) +-#define CFLAG_NONE (1<<3) +-#ifdef WITH_OPENSSL +- const EVP_CIPHER *(*evptype)(void); +-#else +- void *ignored; +-#endif +-}; +- + static const struct sshcipher ciphers[] = { + #ifdef WITH_SSH1 + { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, +diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h +--- openssh-6.8p1/cipher.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/cipher.h 2015-03-20 13:41:15.094883779 +0100 +@@ -62,7 +62,26 @@ + #define CIPHER_ENCRYPT 1 + #define CIPHER_DECRYPT 0 + +-struct sshcipher; ++struct sshcipher { ++ char *name; ++ int number; /* for ssh1 only */ ++ u_int block_size; ++ u_int key_len; ++ u_int iv_len; /* defaults to block_size */ ++ u_int auth_len; ++ u_int discard_len; ++ u_int flags; ++#define CFLAG_CBC (1<<0) ++#define CFLAG_CHACHAPOLY (1<<1) ++#define CFLAG_AESCTR (1<<2) ++#define CFLAG_NONE (1<<3) ++#ifdef WITH_OPENSSL ++ const EVP_CIPHER *(*evptype)(void); ++#else ++ void *ignored; ++#endif ++}; ++ + struct sshcipher_ctx { + int plaintext; + int encrypt; +diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c +--- openssh-6.8p1/kex.c.audit 2015-03-20 13:41:15.046883856 +0100 ++++ openssh-6.8p1/kex.c 2015-03-20 13:41:15.101883767 +0100 +@@ -54,6 +55,7 @@ + #include "ssherr.h" + #include "sshbuf.h" + #include "digest.h" ++#include "audit.h" + + #ifdef GSSAPI + #include "ssh-gss.h" +@@ -484,8 +508,12 @@ choose_enc(struct sshenc *enc, char *cli + { + char *name = match_list(client, server, NULL); + +- if (name == NULL) ++ if (name == NULL) { ++#ifdef SSH_AUDIT_EVENTS ++ audit_unsupported(0); ++#endif + return SSH_ERR_NO_CIPHER_ALG_MATCH; ++ } + if ((enc->cipher = cipher_by_name(name)) == NULL) + return SSH_ERR_INTERNAL_ERROR; + enc->name = name; +@@ -503,8 +531,12 @@ choose_mac(struct ssh *ssh, struct sshma + { + char *name = match_list(client, server, NULL); + +- if (name == NULL) ++ if (name == NULL) { ++#ifdef SSH_AUDIT_EVENTS ++ audit_unsupported(1); ++#endif + return SSH_ERR_NO_MAC_ALG_MATCH; ++ } + if (mac_setup(mac, name) < 0) + return SSH_ERR_INTERNAL_ERROR; + /* truncate the key */ +@@ -521,8 +553,12 @@ choose_comp(struct sshcomp *comp, char * + { + char *name = match_list(client, server, NULL); + +- if (name == NULL) ++ if (name == NULL) { ++#ifdef SSH_AUDIT_EVENTS ++ audit_unsupported(2); ++#endif + return SSH_ERR_NO_COMPRESS_ALG_MATCH; ++ } + if (strcmp(name, "zlib@openssh.com") == 0) { + comp->type = COMP_DELAYED; + } else if (strcmp(name, "zlib") == 0) { +@@ -672,6 +708,10 @@ kex_choose_conf(struct ssh *ssh) + dh_need = MAX(dh_need, newkeys->enc.block_size); + dh_need = MAX(dh_need, newkeys->enc.iv_len); + dh_need = MAX(dh_need, newkeys->mac.key_len); ++ debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need); ++#ifdef SSH_AUDIT_EVENTS ++ audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); ++#endif + } + /* XXX need runden? */ + kex->we_need = need; +@@ -847,3 +887,34 @@ dump_digest(char *msg, u_char *digest, i + sshbuf_dump_data(digest, len, stderr); + } + #endif ++ ++static void ++enc_destroy(struct sshenc *enc) ++{ ++ if (enc == NULL) ++ return; ++ ++ if (enc->key) { ++ memset(enc->key, 0, enc->key_len); ++ free(enc->key); ++ } ++ ++ if (enc->iv) { ++ memset(enc->iv, 0, enc->block_size); ++ free(enc->iv); ++ } ++ ++ memset(enc, 0, sizeof(*enc)); ++} ++ ++void ++newkeys_destroy(struct newkeys *newkeys) ++{ ++ if (newkeys == NULL) ++ return; ++ ++ enc_destroy(&newkeys->enc); ++ mac_destroy(&newkeys->mac); ++ memset(&newkeys->comp, 0, sizeof(newkeys->comp)); ++} ++ +diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h +--- openssh-6.8p1/kex.h.audit 2015-03-20 13:41:15.046883856 +0100 ++++ openssh-6.8p1/kex.h 2015-03-20 13:41:15.095883777 +0100 +@@ -199,6 +199,8 @@ int kexgss_client(struct ssh *); + int kexgss_server(struct ssh *); + #endif + ++void newkeys_destroy(struct newkeys *newkeys); ++ + int kex_dh_hash(const char *, const char *, + const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, + const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); +diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h +--- openssh-6.8p1/key.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/key.h 2015-03-20 13:41:15.095883777 +0100 +@@ -50,6 +50,7 @@ typedef struct sshkey Key; + #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid + #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid + #define key_is_cert sshkey_is_cert ++#define key_is_private sshkey_is_private + #define key_type_plain sshkey_type_plain + #define key_cert_is_legacy sshkey_cert_is_legacy + #define key_curve_name_to_nid sshkey_curve_name_to_nid +diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c +--- openssh-6.8p1/mac.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/mac.c 2015-03-20 13:41:15.102883766 +0100 +@@ -226,6 +246,20 @@ mac_clear(struct sshmac *mac) + mac->umac_ctx = NULL; + } + ++void ++mac_destroy(struct sshmac *mac) ++{ ++ if (mac == NULL) ++ return; ++ ++ if (mac->key) { ++ memset(mac->key, 0, mac->key_len); ++ free(mac->key); ++ } ++ ++ memset(mac, 0, sizeof(*mac)); ++} ++ + /* XXX copied from ciphers_valid */ + #define MAC_SEP "," + int +diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h +--- openssh-6.8p1/mac.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/mac.h 2015-03-20 13:41:15.095883777 +0100 +@@ -47,5 +47,6 @@ int mac_init(struct sshmac *); + int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, + u_char *, size_t); + void mac_clear(struct sshmac *); ++void mac_destroy(struct sshmac *); + + #endif /* SSHMAC_H */ +diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c +--- openssh-6.8p1/monitor.c.audit 2015-03-20 13:41:15.072883814 +0100 ++++ openssh-6.8p1/monitor.c 2015-03-20 13:41:15.107883758 +0100 +@@ -102,6 +102,7 @@ + #include "ssh2.h" + #include "roaming.h" + #include "authfd.h" ++#include "audit.h" + #include "match.h" + #include "ssherr.h" + +@@ -117,6 +118,8 @@ extern Buffer auth_debug; + extern int auth_debug_init; + extern Buffer loginmsg; + ++extern void destroy_sensitive_data(int); ++ + /* State exported from the child */ + static struct sshbuf *child_state; + +@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe + #ifdef SSH_AUDIT_EVENTS + int mm_answer_audit_event(int, Buffer *); + int mm_answer_audit_command(int, Buffer *); ++int mm_answer_audit_end_command(int, Buffer *); ++int mm_answer_audit_unsupported_body(int, Buffer *); ++int mm_answer_audit_kex_body(int, Buffer *); ++int mm_answer_audit_session_key_free_body(int, Buffer *); ++int mm_answer_audit_server_key_free(int, Buffer *); + #endif + + static int monitor_read_log(struct monitor *); +@@ -226,6 +234,10 @@ struct mon_table mon_dispatch_proto20[] + #endif + #ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, ++ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, ++ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, ++ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, ++ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, + #endif + #ifdef BSD_AUTH + {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, +@@ -264,6 +276,11 @@ struct mon_table mon_dispatch_postauth20 + #ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, ++ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command}, ++ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, ++ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, ++ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, ++ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, + #endif + {0, 0, NULL} + }; +@@ -296,6 +313,10 @@ struct mon_table mon_dispatch_proto15[] + #endif + #ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, ++ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, ++ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, ++ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, ++ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, + #endif + #endif /* WITH_SSH1 */ + {0, 0, NULL} +@@ -309,6 +330,11 @@ struct mon_table mon_dispatch_postauth15 + #ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, ++ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command}, ++ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, ++ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, ++ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, ++ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, + #endif + #endif /* WITH_SSH1 */ + {0, 0, NULL} +@@ -1466,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m) + Key *key; + u_char *signature, *data, *blob; + u_int signaturelen, datalen, bloblen; ++ int type = 0; + int verified = 0; + int valid_data = 0; + ++ type = buffer_get_int(m); + blob = buffer_get_string(m, &bloblen); + signature = buffer_get_string(m, &signaturelen); + data = buffer_get_string(m, &datalen); +@@ -1476,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m) + if (hostbased_cuser == NULL || hostbased_chost == NULL || + !monitor_allowed_key(blob, bloblen)) + fatal("%s: bad key, not previously allowed", __func__); ++ if (type != key_blobtype) ++ fatal("%s: bad key type", __func__); + + key = key_from_blob(blob, bloblen); + if (key == NULL) +@@ -1496,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m) + if (!valid_data) + fatal("%s: bad signature data blob", __func__); + +- verified = key_verify(key, signature, signaturelen, data, datalen); ++ switch (key_blobtype) { ++ case MM_USERKEY: ++ verified = user_key_verify(key, signature, signaturelen, data, datalen); ++ break; ++ case MM_HOSTKEY: ++ verified = hostbased_key_verify(key, signature, signaturelen, data, datalen); ++ break; ++ default: ++ verified = 0; ++ break; ++ } + debug3("%s: key %p signature %s", + __func__, key, (verified == 1) ? "verified" : "unverified"); + +@@ -1554,6 +1595,12 @@ mm_session_close(Session *s) + debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); + session_pty_cleanup2(s); + } ++#ifdef SSH_AUDIT_EVENTS ++ if (s->command != NULL) { ++ debug3("%s: command %d", __func__, s->command_handle); ++ session_end_command2(s); ++ } ++#endif + session_unused(s->self); + } + +@@ -1836,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req) + sshpam_cleanup(); + #endif + ++ destroy_sensitive_data(0); ++ + while (waitpid(pmonitor->m_pid, &status, 0) == -1) + if (errno != EINTR) + exit(1); +@@ -1878,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff + { + u_int len; + char *cmd; ++ Session *s; + + debug3("%s entering", __func__); + cmd = buffer_get_string(m, &len); ++ + /* sanity check command, if so how? */ +- audit_run_command(cmd); ++ s = session_new(); ++ if (s == NULL) ++ fatal("%s: error allocating a session", __func__); ++ s->command = cmd; ++ s->command_handle = audit_run_command(cmd); ++ ++ buffer_clear(m); ++ buffer_put_int(m, s->self); ++ ++ mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m); ++ ++ return (0); ++} ++ ++int ++mm_answer_audit_end_command(int socket, Buffer *m) ++{ ++ int handle; ++ u_int len; ++ char *cmd; ++ Session *s; ++ ++ debug3("%s entering", __func__); ++ handle = buffer_get_int(m); ++ cmd = buffer_get_string(m, &len); ++ ++ s = session_by_id(handle); ++ if (s == NULL || s->ttyfd != -1 || s->command == NULL || ++ strcmp(s->command, cmd) != 0) ++ fatal("%s: invalid handle", __func__); ++ mm_session_close(s); + free(cmd); + return (0); + } +@@ -1936,6 +2017,7 @@ + void + mm_get_keystate(struct monitor *pmonitor) + { ++ Buffer m; + debug3("%s: Waiting for new keys", __func__); + + if ((child_state = sshbuf_new()) == NULL) +@@ -1946,6 +2027,21 @@ mm_get_keystate(struct monitor *pmonitor + mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, + child_state); + debug3("%s: GOT new keys", __func__); ++ ++#ifdef SSH_AUDIT_EVENTS ++ if (compat20) { ++ buffer_init(&m); ++ mm_request_receive_expect(pmonitor->m_sendfd, ++ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); ++ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m); ++ buffer_free(&m); ++ } ++#endif ++ ++ /* Drain any buffered messages from the child */ ++ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) ++ ; ++ + } + + +@@ -2212,3 +2308,87 @@ mm_answer_gss_updatecreds(int socket, Bu + + #endif /* GSSAPI */ + ++#ifdef SSH_AUDIT_EVENTS ++int ++mm_answer_audit_unsupported_body(int sock, Buffer *m) ++{ ++ int what; ++ ++ what = buffer_get_int(m); ++ ++ audit_unsupported_body(what); ++ ++ buffer_clear(m); ++ ++ mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m); ++ return 0; ++} ++ ++int ++mm_answer_audit_kex_body(int sock, Buffer *m) ++{ ++ int ctos, len; ++ char *cipher, *mac, *compress, *pfs; ++ pid_t pid; ++ uid_t uid; ++ ++ ctos = buffer_get_int(m); ++ cipher = buffer_get_string(m, &len); ++ mac = buffer_get_string(m, &len); ++ compress = buffer_get_string(m, &len); ++ pfs = buffer_get_string(m, &len); ++ pid = buffer_get_int64(m); ++ uid = buffer_get_int64(m); ++ ++ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); ++ ++ free(cipher); ++ free(mac); ++ free(compress); ++ free(pfs); ++ buffer_clear(m); ++ ++ mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); ++ return 0; ++} ++ ++int ++mm_answer_audit_session_key_free_body(int sock, Buffer *m) ++{ ++ int ctos; ++ pid_t pid; ++ uid_t uid; ++ ++ ctos = buffer_get_int(m); ++ pid = buffer_get_int64(m); ++ uid = buffer_get_int64(m); ++ ++ audit_session_key_free_body(ctos, pid, uid); ++ ++ buffer_clear(m); ++ ++ mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m); ++ return 0; ++} ++ ++int ++mm_answer_audit_server_key_free(int sock, Buffer *m) ++{ ++ int len; ++ char *fp; ++ pid_t pid; ++ uid_t uid; ++ ++ fp = buffer_get_string(m, &len); ++ pid = buffer_get_int64(m); ++ uid = buffer_get_int64(m); ++ ++ audit_destroy_sensitive_data(fp, pid, uid); ++ ++ free(fp); ++ buffer_clear(m); ++ ++ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m); ++ return 0; ++} ++#endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h +--- openssh-6.8p1/monitor.h.audit 2015-03-20 13:41:15.072883814 +0100 ++++ openssh-6.8p1/monitor.h 2015-03-20 13:41:15.096883775 +0100 +@@ -69,7 +69,13 @@ enum monitor_reqtype { + MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, + MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, + MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, +- MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, ++ MONITOR_REQ_AUDIT_EVENT = 112, ++ MONITOR_REQ_AUDIT_COMMAND = 114, MONITOR_ANS_AUDIT_COMMAND = 115, ++ MONITOR_REQ_AUDIT_END_COMMAND = 116, ++ MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119, ++ MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121, ++ MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123, ++ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125 + + }; + +diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c +--- openssh-6.8p1/monitor_wrap.c.audit 2015-03-20 13:41:15.047883855 +0100 ++++ openssh-6.8p1/monitor_wrap.c 2015-03-20 13:41:15.108883756 +0100 +@@ -461,7 +461,7 @@ mm_key_allowed(enum mm_keytype type, cha + */ + + int +-mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) ++mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) + { + Buffer m; + u_char *blob; +@@ -475,6 +475,7 @@ mm_key_verify(Key *key, u_char *sig, u_i + return (0); + + buffer_init(&m); ++ buffer_put_int(&m, type); + buffer_put_string(&m, blob, len); + buffer_put_string(&m, sig, siglen); + buffer_put_string(&m, data, datalen); +@@ -492,6 +493,18 @@ mm_key_verify(Key *key, u_char *sig, u_i + return (verified); + } + ++int ++mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) ++{ ++ return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, datalen); ++} ++ ++int ++mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) ++{ ++ return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen); ++} ++ + void + mm_send_keystate(struct monitor *monitor) + { +@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event) + buffer_free(&m); + } + +-void ++int + mm_audit_run_command(const char *command) + { + Buffer m; ++ int handle; + + debug3("%s entering command %s", __func__, command); + +@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command + buffer_put_cstring(&m, command); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, &m); ++ ++ handle = buffer_get_int(&m); ++ buffer_free(&m); ++ ++ return (handle); ++} ++ ++void ++mm_audit_end_command(int handle, const char *command) ++{ ++ Buffer m; ++ ++ debug3("%s entering command %s", __func__, command); ++ ++ buffer_init(&m); ++ buffer_put_int(&m, handle); ++ buffer_put_cstring(&m, command); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, &m); + buffer_free(&m); + } + #endif /* SSH_AUDIT_EVENTS */ +@@ -1151,3 +1185,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc + + #endif /* GSSAPI */ + ++#ifdef SSH_AUDIT_EVENTS ++void ++mm_audit_unsupported_body(int what) ++{ ++ Buffer m; ++ ++ buffer_init(&m); ++ buffer_put_int(&m, what); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, &m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED, ++ &m); ++ ++ buffer_free(&m); ++} ++ ++void ++mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, ++ uid_t uid) ++{ ++ Buffer m; ++ ++ buffer_init(&m); ++ buffer_put_int(&m, ctos); ++ buffer_put_cstring(&m, cipher); ++ buffer_put_cstring(&m, (mac ? mac : "")); ++ buffer_put_cstring(&m, compress); ++ buffer_put_cstring(&m, fps); ++ buffer_put_int64(&m, pid); ++ buffer_put_int64(&m, uid); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX, ++ &m); ++ ++ buffer_free(&m); ++} ++ ++void ++mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ Buffer m; ++ ++ buffer_init(&m); ++ buffer_put_int(&m, ctos); ++ buffer_put_int64(&m, pid); ++ buffer_put_int64(&m, uid); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, ++ &m); ++ buffer_free(&m); ++} ++ ++void ++mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) ++{ ++ Buffer m; ++ ++ buffer_init(&m); ++ buffer_put_cstring(&m, fp); ++ buffer_put_int64(&m, pid); ++ buffer_put_int64(&m, uid); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, ++ &m); ++ buffer_free(&m); ++} ++#endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-6.8p1/monitor_wrap.h.audit openssh-6.8p1/monitor_wrap.h +--- openssh-6.8p1/monitor_wrap.h.audit 2015-03-20 13:41:15.048883853 +0100 ++++ openssh-6.8p1/monitor_wrap.h 2015-03-20 13:41:15.096883775 +0100 +@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char + int mm_user_key_allowed(struct passwd *, Key *); + int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *); + int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); +-int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); ++int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int); ++int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int); + int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); + int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); + BIGNUM *mm_auth_rsa_generate_challenge(Key *); +@@ -79,7 +80,12 @@ void mm_sshpam_free_ctx(void *); + #ifdef SSH_AUDIT_EVENTS + #include "audit.h" + void mm_audit_event(ssh_audit_event_t); +-void mm_audit_run_command(const char *); ++int mm_audit_run_command(const char *); ++void mm_audit_end_command(int, const char *); ++void mm_audit_unsupported_body(int); ++void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t); ++void mm_audit_session_key_free_body(int, pid_t, uid_t); ++void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); + #endif + + struct Session; +diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c +--- openssh-6.8p1/packet.c.audit 2015-03-20 13:41:14.990883947 +0100 ++++ openssh-6.8p1/packet.c 2015-03-20 13:41:15.097883774 +0100 +@@ -67,6 +67,7 @@ + #include "key.h" /* typedefs XXX */ + + #include "xmalloc.h" ++#include "audit.h" + #include "crc32.h" + #include "deattack.h" + #include "compat.h" +@@ -448,6 +449,13 @@ ssh_packet_get_connection_out(struct ssh + return ssh->state->connection_out; + } + ++static int ++packet_state_has_keys (const struct session_state *state) ++{ ++ return state != NULL && ++ (state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL); ++} ++ + /* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. +@@ -478,13 +486,6 @@ ssh_packet_close(struct ssh *ssh) + if (!state->initialized) + return; + state->initialized = 0; +- if (state->connection_in == state->connection_out) { +- shutdown(state->connection_out, SHUT_RDWR); +- close(state->connection_out); +- } else { +- close(state->connection_in); +- close(state->connection_out); +- } + sshbuf_free(state->input); + sshbuf_free(state->output); + sshbuf_free(state->outgoing_packet); +@@ -516,14 +517,24 @@ ssh_packet_close(struct ssh *ssh) + inflateEnd(stream); + } + } +- if ((r = cipher_cleanup(&state->send_context)) != 0) +- error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); +- if ((r = cipher_cleanup(&state->receive_context)) != 0) +- error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); ++ if (packet_state_has_keys(state)) { ++ if ((r = cipher_cleanup(&state->send_context)) != 0) ++ error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); ++ if ((r = cipher_cleanup(&state->receive_context)) != 0) ++ error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); ++ audit_session_key_free(2); ++ } + if (ssh->remote_ipaddr) { + free(ssh->remote_ipaddr); + ssh->remote_ipaddr = NULL; + } ++ if (state->connection_in == state->connection_out) { ++ shutdown(state->connection_out, SHUT_RDWR); ++ close(state->connection_out); ++ } else { ++ close(state->connection_in); ++ close(state->connection_out); ++ } + free(ssh->state); + ssh->state = NULL; + } +@@ -941,6 +952,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod + } + if (state->newkeys[mode] != NULL) { + debug("set_newkeys: rekeying"); ++ audit_session_key_free(mode); + if ((r = cipher_cleanup(cc)) != 0) + return r; + enc = &state->newkeys[mode]->enc; +@@ -2263,6 +2275,75 @@ ssh_packet_get_output(struct ssh *ssh) + return (void *)ssh->state->output; + } + ++static void ++newkeys_destroy_and_free(struct newkeys *newkeys) ++{ ++ if (newkeys == NULL) ++ return; ++ ++ free(newkeys->enc.name); ++ ++ if (newkeys->mac.enabled) { ++ mac_clear(&newkeys->mac); ++ free(newkeys->mac.name); ++ } ++ ++ free(newkeys->comp.name); ++ ++ newkeys_destroy(newkeys); ++ free(newkeys); ++} ++ ++static void ++packet_destroy_state(struct session_state *state) ++{ ++ if (state == NULL) ++ return; ++ ++ cipher_cleanup(&state->receive_context); ++ cipher_cleanup(&state->send_context); ++ ++ buffer_free(state->input); ++ state->input = NULL; ++ buffer_free(state->output); ++ state->output = NULL; ++ buffer_free(state->outgoing_packet); ++ state->outgoing_packet = NULL; ++ buffer_free(state->incoming_packet); ++ state->incoming_packet = NULL; ++ if( state->compression_buffer ) { ++ buffer_free(state->compression_buffer); ++ state->compression_buffer = NULL; ++ } ++ newkeys_destroy_and_free(state->newkeys[MODE_IN]); ++ state->newkeys[MODE_IN] = NULL; ++ newkeys_destroy_and_free(state->newkeys[MODE_OUT]); ++ state->newkeys[MODE_OUT] = NULL; ++ mac_destroy(state->packet_discard_mac); ++// TAILQ_HEAD(, packet) outgoing; ++// memset(state, 0, sizeof(state)); ++} ++ ++void ++packet_destroy_all(int audit_it, int privsep) ++{ ++ if (audit_it) ++ audit_it = (active_state != NULL && packet_state_has_keys(active_state->state)) ++ || (backup_state != NULL && packet_state_has_keys(backup_state->state)); ++ if (active_state != NULL) ++ packet_destroy_state(active_state->state); ++ if (backup_state != NULL) ++ packet_destroy_state(backup_state->state); ++ if (audit_it) { ++#ifdef SSH_AUDIT_EVENTS ++ if (privsep) ++ audit_session_key_free(2); ++ else ++ audit_session_key_free_body(2, getpid(), getuid()); ++#endif ++ } ++} ++ + /* XXX TODO update roaming to new API (does not work anyway) */ + /* + * Save the state for the real connection, and use a separate state when +@@ -2272,18 +2373,12 @@ void + ssh_packet_backup_state(struct ssh *ssh, + struct ssh *backup_state) + { +- struct ssh *tmp; +- + close(ssh->state->connection_in); + ssh->state->connection_in = -1; + close(ssh->state->connection_out); + ssh->state->connection_out = -1; +- if (backup_state) +- tmp = backup_state; +- else +- tmp = ssh_alloc_session_state(); + backup_state = ssh; +- ssh = tmp; ++ ssh = ssh_alloc_session_state(); + } + + /* XXX FIXME FIXME FIXME */ +@@ -2302,9 +2397,7 @@ ssh_packet_restore_state(struct ssh *ssh + backup_state = ssh; + ssh = tmp; + ssh->state->connection_in = backup_state->state->connection_in; +- backup_state->state->connection_in = -1; + ssh->state->connection_out = backup_state->state->connection_out; +- backup_state->state->connection_out = -1; + len = sshbuf_len(backup_state->state->input); + if (len > 0) { + if ((r = sshbuf_putb(ssh->state->input, +@@ -2313,6 +2406,11 @@ ssh_packet_restore_state(struct ssh *ssh + sshbuf_reset(backup_state->state->input); + add_recv_bytes(len); + } ++ backup_state->state->connection_in = -1; ++ backup_state->state->connection_out = -1; ++ packet_destroy_state(backup_state->state); ++ free(backup_state); ++ backup_state = NULL; + } + + /* Reset after_authentication and reset compression in post-auth privsep */ +diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h +--- openssh-6.8p1/packet.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/packet.h 2015-03-20 13:41:15.097883774 +0100 +@@ -189,7 +189,7 @@ int sshpkt_get_end(struct ssh *ssh); + const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); + + /* OLD API */ +-extern struct ssh *active_state; ++extern struct ssh *active_state, *backup_state; + #include "opacket.h" + + #if !defined(WITH_OPENSSL) +@@ -203,4 +203,5 @@ extern struct ssh *active_state; + # undef EC_POINT + #endif + ++void packet_destroy_all(int, int); + #endif /* PACKET_H */ +diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c +--- openssh-6.8p1/session.c.audit 2015-03-20 13:41:15.073883813 +0100 ++++ openssh-6.8p1/session.c 2015-03-20 13:41:15.097883774 +0100 +@@ -139,7 +139,7 @@ extern int log_stderr; + extern int debug_flag; + extern u_int utmp_len; + extern int startup_pipe; +-extern void destroy_sensitive_data(void); ++extern void destroy_sensitive_data(int); + extern Buffer loginmsg; + + /* original command from peer. */ +@@ -731,6 +731,14 @@ do_exec_pty(Session *s, const char *comm + /* Parent. Close the slave side of the pseudo tty. */ + close(ttyfd); + ++#ifndef HAVE_OSF_SIA ++ /* do_login in the child did not affect state in this process, ++ compensate. From an architectural standpoint, this is extremely ++ ugly. */ ++ if (!(options.use_login && command == NULL)) ++ audit_count_session_open(); ++#endif ++ + /* Enter interactive session. */ + s->ptymaster = ptymaster; + packet_set_interactive(1, +@@ -853,15 +861,19 @@ do_exec(Session *s, const char *command) + get_remote_port()); + + #ifdef SSH_AUDIT_EVENTS ++ if (s->command != NULL || s->command_handle != -1) ++ fatal("do_exec: command already set"); + if (command != NULL) +- PRIVSEP(audit_run_command(command)); ++ s->command = xstrdup(command); + else if (s->ttyfd == -1) { + char *shell = s->pw->pw_shell; + + if (shell[0] == '\0') /* empty shell means /bin/sh */ + shell =_PATH_BSHELL; +- PRIVSEP(audit_run_command(shell)); ++ s->command = xstrdup(shell); + } ++ if (s->command != NULL && s->ptyfd == -1) ++ s->command_handle = PRIVSEP(audit_run_command(s->command)); + #endif + if (s->ttyfd != -1) + ret = do_exec_pty(s, command); +@@ -1704,7 +1716,10 @@ do_child(Session *s, const char *command + int r = 0; + + /* remove hostkey from the child's memory */ +- destroy_sensitive_data(); ++ destroy_sensitive_data(1); ++ /* Don't audit this - both us and the parent would be talking to the ++ monitor over a single socket, with no synchronization. */ ++ packet_destroy_all(0, 1); + + /* Force a password change */ + if (s->authctxt->force_pwchange) { +@@ -1934,6 +1949,7 @@ session_unused(int id) + sessions[id].ttyfd = -1; + sessions[id].ptymaster = -1; + sessions[id].x11_chanids = NULL; ++ sessions[id].command_handle = -1; + sessions[id].next_unused = sessions_first_unused; + sessions_first_unused = id; + } +@@ -2016,6 +2032,19 @@ session_open(Authctxt *authctxt, int cha + } + + Session * ++session_by_id(int id) ++{ ++ if (id >= 0 && id < sessions_nalloc) { ++ Session *s = &sessions[id]; ++ if (s->used) ++ return s; ++ } ++ debug("session_by_id: unknown id %d", id); ++ session_dump(); ++ return NULL; ++} ++ ++Session * + session_by_tty(char *tty) + { + int i; +@@ -2532,6 +2561,32 @@ session_exit_message(Session *s, int sta + chan_write_failed(c); + } + ++#ifdef SSH_AUDIT_EVENTS ++void ++session_end_command2(Session *s) ++{ ++ if (s->command != NULL) { ++ if (s->command_handle != -1) ++ audit_end_command(s->command_handle, s->command); ++ free(s->command); ++ s->command = NULL; ++ s->command_handle = -1; ++ } ++} ++ ++static void ++session_end_command(Session *s) ++{ ++ if (s->command != NULL) { ++ if (s->command_handle != -1) ++ PRIVSEP(audit_end_command(s->command_handle, s->command)); ++ free(s->command); ++ s->command = NULL; ++ s->command_handle = -1; ++ } ++} ++#endif ++ + void + session_close(Session *s) + { +@@ -2540,6 +2593,10 @@ session_close(Session *s) + debug("session_close: session %d pid %ld", s->self, (long)s->pid); + if (s->ttyfd != -1) + session_pty_cleanup(s); ++#ifdef SSH_AUDIT_EVENTS ++ if (s->command) ++ session_end_command(s); ++#endif + free(s->term); + free(s->display); + free(s->x11_chanids); +@@ -2754,6 +2811,15 @@ do_authenticated2(Authctxt *authctxt) + server_loop2(authctxt); + } + ++static void ++do_cleanup_one_session(Session *s) ++{ ++ session_pty_cleanup2(s); ++#ifdef SSH_AUDIT_EVENTS ++ session_end_command2(s); ++#endif ++} ++ + void + do_cleanup(Authctxt *authctxt) + { +@@ -2802,5 +2868,5 @@ do_cleanup(Authctxt *authctxt) + * or if running in monitor. + */ + if (!use_privsep || mm_is_monitor()) +- session_destroy_all(session_pty_cleanup2); ++ session_destroy_all(do_cleanup_one_session); + } +diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h +--- openssh-6.8p1/session.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/session.h 2015-03-20 13:41:15.097883774 +0100 +@@ -61,6 +61,12 @@ struct Session { + char *name; + char *val; + } *env; ++ ++ /* exec */ ++#ifdef SSH_AUDIT_EVENTS ++ int command_handle; ++ char *command; ++#endif + }; + + void do_authenticated(Authctxt *); +@@ -73,8 +79,10 @@ void session_close_by_pid(pid_t, int); + void session_close_by_channel(int, void *); + void session_destroy_all(void (*)(Session *)); + void session_pty_cleanup2(Session *); ++void session_end_command2(Session *); + + Session *session_new(void); ++Session *session_by_id(int); + Session *session_by_tty(char *); + void session_close(Session *); + void do_setusercontext(struct passwd *); +diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c +--- openssh-6.8p1/sshd.c.audit 2015-03-20 13:41:15.083883796 +0100 ++++ openssh-6.8p1/sshd.c 2015-03-20 13:41:15.110883753 +0100 +@@ -121,6 +124,7 @@ + #endif + #include "monitor_wrap.h" + #include "roaming.h" ++#include "audit.h" + #include "ssh-sandbox.h" + #include "version.h" + #include "ssherr.h" +@@ -260,7 +264,7 @@ Buffer loginmsg; + struct passwd *privsep_pw = NULL; + + /* Prototypes for various functions defined later in this file. */ +-void destroy_sensitive_data(void); ++void destroy_sensitive_data(int); + void demote_sensitive_data(void); + + #ifdef WITH_SSH1 +@@ -281,6 +285,15 @@ close_listen_socks(void) + num_listen_socks = -1; + } + ++/* ++ * Is this process listening for clients (i.e. not specific to any specific ++ * client connection?) ++ */ ++int listening_for_clients(void) ++{ ++ return num_listen_socks > 0; ++} ++ + static void + close_startup_pipes(void) + { +@@ -560,22 +573,45 @@ sshd_exchange_identification(int sock_in + } + } + +-/* Destroy the host and server keys. They will no longer be needed. */ ++/* ++ * Destroy the host and server keys. They will no longer be needed. Careful, ++ * this can be called from cleanup_exit() - i.e. from just about anywhere. ++ */ + void +-destroy_sensitive_data(void) ++destroy_sensitive_data(int privsep) + { + int i; ++ pid_t pid; ++ uid_t uid; + + if (sensitive_data.server_key) { + key_free(sensitive_data.server_key); + sensitive_data.server_key = NULL; + } ++ pid = getpid(); ++ uid = getuid(); + for (i = 0; i < options.num_host_key_files; i++) { + if (sensitive_data.host_keys[i]) { ++ char *fp; ++ ++ if (key_is_private(sensitive_data.host_keys[i])) ++ fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX); ++ else ++ fp = NULL; + key_free(sensitive_data.host_keys[i]); + sensitive_data.host_keys[i] = NULL; ++ if (fp != NULL) { ++ if (privsep) ++ PRIVSEP(audit_destroy_sensitive_data(fp, ++ pid, uid)); ++ else ++ audit_destroy_sensitive_data(fp, ++ pid, uid); ++ free(fp); ++ } + } +- if (sensitive_data.host_certificates[i]) { ++ if (sensitive_data.host_certificates ++ && sensitive_data.host_certificates[i]) { + key_free(sensitive_data.host_certificates[i]); + sensitive_data.host_certificates[i] = NULL; + } +@@ -589,6 +625,8 @@ void + demote_sensitive_data(void) + { + Key *tmp; ++ pid_t pid; ++ uid_t uid; + int i; + + if (sensitive_data.server_key) { +@@ -597,13 +635,25 @@ demote_sensitive_data(void) + sensitive_data.server_key = tmp; + } + ++ pid = getpid(); ++ uid = getuid(); + for (i = 0; i < options.num_host_key_files; i++) { + if (sensitive_data.host_keys[i]) { ++ char *fp; ++ ++ if (key_is_private(sensitive_data.host_keys[i])) ++ fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX); ++ else ++ fp = NULL; + tmp = key_demote(sensitive_data.host_keys[i]); + key_free(sensitive_data.host_keys[i]); + sensitive_data.host_keys[i] = tmp; + if (tmp->type == KEY_RSA1) + sensitive_data.ssh1_host_key = tmp; ++ if (fp != NULL) { ++ audit_destroy_sensitive_data(fp, pid, uid); ++ free(fp); ++ } + } + /* Certs do not need demotion */ + } +@@ -675,7 +725,7 @@ privsep_preauth(Authctxt *authctxt) + + if (use_privsep == PRIVSEP_ON) + box = ssh_sandbox_init(pmonitor); +- pid = fork(); ++ pmonitor->m_pid = pid = fork(); + if (pid == -1) { + fatal("fork of unprivileged child failed"); + } else if (pid != 0) { +@@ -759,6 +811,12 @@ privsep_postauth(Authctxt *authctxt) + else if (pmonitor->m_pid != 0) { + verbose("User child is on pid %ld", (long)pmonitor->m_pid); + buffer_clear(&loginmsg); ++ if (*pmonitor->m_pkex != NULL ){ ++ newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]); ++ newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_IN]); ++ audit_session_key_free_body(2, getpid(), getuid()); ++ packet_destroy_all(0, 0); ++ } + monitor_child_postauth(pmonitor); + + /* NEVERREACHED */ +@@ -1286,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so + if (received_sigterm) { + logit("Received signal %d; terminating.", + (int) received_sigterm); ++ destroy_sensitive_data(0); + close_listen_socks(); + if (options.pid_file != NULL) + unlink(options.pid_file); +@@ -2242,6 +2321,7 @@ main(int ac, char **av) + */ + if (use_privsep) { + mm_send_keystate(pmonitor); ++ packet_destroy_all(1, 1); + exit(0); + } + +@@ -2287,7 +2367,7 @@ main(int ac, char **av) + privsep_postauth(authctxt); + /* the monitor process [priv] will not return */ + if (!compat20) +- destroy_sensitive_data(); ++ destroy_sensitive_data(0); + } + + packet_set_timeout(options.client_alive_interval, +@@ -2301,6 +2381,9 @@ main(int ac, char **av) + do_authenticated(authctxt); + + /* The connection has been terminated. */ ++ packet_destroy_all(1, 1); ++ destroy_sensitive_data(1); ++ + packet_get_bytes(&ibytes, &obytes); + verbose("Transferred: sent %llu, received %llu bytes", + (unsigned long long)obytes, (unsigned long long)ibytes); +@@ -2461,6 +2544,10 @@ do_ssh1_kex(void) + if (cookie[i] != packet_get_char()) + packet_disconnect("IP Spoofing check bytes do not match."); + ++#ifdef SSH_AUDIT_EVENTS ++ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); ++#endif ++ + debug("Encryption type: %.200s", cipher_name(cipher_type)); + + /* Get the encrypted integer. */ +@@ -2520,7 +2607,7 @@ do_ssh1_kex(void) + } + + /* Destroy the private and public keys. No longer. */ +- destroy_sensitive_data(); ++ destroy_sensitive_data(1); + + if (use_privsep) + mm_ssh1_session_id(session_id); +@@ -2703,6 +2802,16 @@ do_ssh2_kex(void) + void + cleanup_exit(int i) + { ++ static int in_cleanup = 0; ++ int is_privsep_child; ++ ++ /* cleanup_exit can be called at the very least from the privsep ++ wrappers used for auditing. Make sure we don't recurse ++ indefinitely. */ ++ if (in_cleanup) ++ _exit(i); ++ in_cleanup = 1; ++ + if (the_authctxt) { + do_cleanup(the_authctxt); + if (use_privsep && privsep_is_preauth && +@@ -2714,9 +2823,14 @@ cleanup_exit(int i) + pmonitor->m_pid, strerror(errno)); + } + } ++ is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0; ++ if (sensitive_data.host_keys != NULL) ++ destroy_sensitive_data(is_privsep_child); ++ packet_destroy_all(1, is_privsep_child); + #ifdef SSH_AUDIT_EVENTS + /* done after do_cleanup so it can cancel the PAM auth 'thread' */ +- if (!use_privsep || mm_is_monitor()) ++ if ((the_authctxt == NULL || !the_authctxt->authenticated) && ++ (!use_privsep || mm_is_monitor())) + audit_event(SSH_CONNECTION_ABANDON); + #endif + _exit(i); +diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c +--- openssh-6.8p1/sshkey.c.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sshkey.c 2015-03-20 13:41:15.111883751 +0100 +@@ -317,6 +319,33 @@ sshkey_type_is_valid_ca(int type) + } + + int ++sshkey_is_private(const struct sshkey *k) ++{ ++ switch (k->type) { ++ case KEY_RSA_CERT_V00: ++ case KEY_RSA_CERT: ++ case KEY_RSA1: ++ case KEY_RSA: ++ return k->rsa->d != NULL; ++ case KEY_DSA_CERT_V00: ++ case KEY_DSA_CERT: ++ case KEY_DSA: ++ return k->dsa->priv_key != NULL; ++#ifdef OPENSSL_HAS_ECC ++ case KEY_ECDSA_CERT: ++ case KEY_ECDSA: ++ return EC_KEY_get0_private_key(k->ecdsa) != NULL; ++#endif ++ case KEY_ED25519_CERT: ++ case KEY_ED25519: ++ return (k->ed25519_pk != NULL); ++ default: ++ /* fatal("key_is_private: bad key type %d", k->type); */ ++ return 0; ++ } ++} ++ ++int + sshkey_is_cert(const struct sshkey *k) + { + if (k == NULL) +diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h +--- openssh-6.8p1/sshkey.h.audit 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sshkey.h 2015-03-20 13:41:15.098883772 +0100 +@@ -134,6 +134,7 @@ u_int sshkey_size(const struct sshkey + int sshkey_generate(int type, u_int bits, struct sshkey **keyp); + int sshkey_from_private(const struct sshkey *, struct sshkey **); + int sshkey_type_from_name(const char *); ++int sshkey_is_private(const struct sshkey *); + int sshkey_is_cert(const struct sshkey *); + int sshkey_type_is_cert(int); + int sshkey_type_plain(int); +diff -up openssh-6.8p1/sandbox-seccomp-filter.c.audit openssh-6.8p1/sandbox-seccomp-filter.c +--- openssh-6.8p1/sandbox-seccomp-filter.c.audit 2015-03-20 13:41:15.088883788 +0100 ++++ openssh-6.8p1/sandbox-seccomp-filter.c 2015-03-20 13:41:15.097883774 +0100 +@@ -110,6 +110,12 @@ static const struct sock_filter preauth_ + #ifdef __NR_time /* not defined on EABI ARM */ + SC_ALLOW(time), + #endif ++#ifdef SSH_AUDIT_EVENTS ++ SC_ALLOW(getuid), ++#ifdef __NR_getuid32 /* not defined on x86_64 */ ++ SC_ALLOW(getuid32), ++#endif ++#endif + SC_ALLOW(read), + SC_ALLOW(write), + SC_ALLOW(close), diff --git a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch b/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch new file mode 100644 index 000000000..4285bd9c8 --- /dev/null +++ b/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch @@ -0,0 +1,66 @@ +diff --git a/configure.ac b/configure.ac +index 4065d0e..d59ad44 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -764,9 +764,12 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + i*86-*) + seccomp_audit_arch=AUDIT_ARCH_I386 + ;; +- arm*-*) ++ aarch64*-*) ++ seccomp_audit_arch=AUDIT_ARCH_AARCH64 ++ ;; ++ arm*-*) + seccomp_audit_arch=AUDIT_ARCH_ARM +- ;; ++ ;; + esac + if test "x$seccomp_audit_arch" != "x" ; then + AC_MSG_RESULT(["$seccomp_audit_arch"]) +diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c +index 095b04a..52f6810 100644 +--- a/sandbox-seccomp-filter.c ++++ b/sandbox-seccomp-filter.c +@@ -90,8 +90,20 @@ static const struct sock_filter preauth_insns[] = { + /* Load the syscall number for checking. */ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, + offsetof(struct seccomp_data, nr)), +- SC_DENY(open, EACCES), +- SC_DENY(stat, EACCES), ++ SC_DENY(openat, EACCES), ++#ifdef __NR_open ++ SC_DENY(open, EACCES), /* not on AArch64 */ ++#endif ++#ifdef __NR_fstat ++ SC_DENY(fstat, EACCES), /* x86_64, Aarch64 */ ++#endif ++#if defined(__NR_stat64) && defined(__NR_fstat64) ++ SC_DENY(stat64, EACCES), /* ix86, arm */ ++ SC_DENY(fstat64, EACCES), ++#endif ++#ifdef __NR_newfstatat ++ SC_DENY(newfstatat, EACCES), /* Aarch64 */ ++#endif + SC_ALLOW(getpid), + SC_ALLOW(gettimeofday), + SC_ALLOW(clock_gettime), +@@ -111,12 +123,19 @@ static const struct sock_filter preauth_insns[] = { + SC_ALLOW(shutdown), + #endif + SC_ALLOW(brk), ++#ifdef __NR_poll /* not on AArch64 */ + SC_ALLOW(poll), ++#endif + #ifdef __NR__newselect + SC_ALLOW(_newselect), + #else ++#ifdef __NR_select /* not on AArch64 */ + SC_ALLOW(select), + #endif ++#ifdef __NR_pselect6 /* AArch64 */ ++ SC_ALLOW(pselect6), ++#endif ++#endif + SC_ALLOW(madvise), + #ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ + SC_ALLOW(mmap2), diff --git a/openssh/patches/openssh-6.7p1-sftp-force-permission.patch b/openssh/patches/openssh-6.7p1-sftp-force-permission.patch new file mode 100644 index 000000000..1a88e50e1 --- /dev/null +++ b/openssh/patches/openssh-6.7p1-sftp-force-permission.patch @@ -0,0 +1,81 @@ +diff -up openssh-6.8p1/sftp-server.8.sftp-force-mode openssh-6.8p1/sftp-server.8 +--- openssh-6.8p1/sftp-server.8.sftp-force-mode 2015-03-17 06:49:20.000000000 +0100 ++++ openssh-6.8p1/sftp-server.8 2015-03-18 13:18:05.898306477 +0100 +@@ -38,6 +38,7 @@ + .Op Fl P Ar blacklisted_requests + .Op Fl p Ar whitelisted_requests + .Op Fl u Ar umask ++.Op Fl m Ar force_file_perms + .Ek + .Nm + .Fl Q Ar protocol_feature +@@ -138,6 +139,10 @@ Sets an explicit + .Xr umask 2 + to be applied to newly-created files and directories, instead of the + user's default mask. ++.It Fl m Ar force_file_perms ++Sets explicit file permissions to be applied to newly-created files instead ++of the default or client requested mode. Numeric values include: ++777, 755, 750, 666, 644, 640, etc. Option -u is ineffective if -m is set. + .El + .Pp + On some systems, +diff -up openssh-6.8p1/sftp-server.c.sftp-force-mode openssh-6.8p1/sftp-server.c +--- openssh-6.8p1/sftp-server.c.sftp-force-mode 2015-03-18 13:18:05.883306513 +0100 ++++ openssh-6.8p1/sftp-server.c 2015-03-18 13:18:36.697232193 +0100 +@@ -70,6 +70,10 @@ struct sshbuf *oqueue; + /* Version of client */ + static u_int version; + ++/* Force file permissions */ ++int permforce = 0; ++long permforcemode; ++ + /* SSH2_FXP_INIT received */ + static int init_done; + +@@ -693,6 +697,10 @@ process_open(u_int32_t id) + debug3("request %u: open flags %d", id, pflags); + flags = flags_from_portable(pflags); + mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; ++ if (permforce == 1) { /* Force perm if -m is set */ ++ mode = permforcemode; ++ (void)umask(0); /* so umask does not interfere */ ++ } + logit("open \"%s\" flags %s mode 0%o", + name, string_from_portable(pflags), mode); + if (readonly && +@@ -1495,7 +1503,7 @@ sftp_server_usage(void) + fprintf(stderr, + "usage: %s [-ehR] [-d start_directory] [-f log_facility] " + "[-l log_level]\n\t[-P blacklisted_requests] " +- "[-p whitelisted_requests] [-u umask]\n" ++ "[-p whitelisted_requests] [-u umask] [-m force_file_perms]\n" + " %s -Q protocol_feature\n", + __progname, __progname); + exit(1); +@@ -1520,7 +1528,7 @@ sftp_server_main(int argc, char **argv, + pw = pwcopy(user_pw); + + while (!skipargs && (ch = getopt(argc, argv, +- "d:f:l:P:p:Q:u:cehR")) != -1) { ++ "d:f:l:P:p:Q:u:m:cehR")) != -1) { + switch (ch) { + case 'Q': + if (strcasecmp(optarg, "requests") != 0) { +@@ -1580,6 +1588,15 @@ sftp_server_main(int argc, char **argv, + fatal("Invalid umask \"%s\"", optarg); + (void)umask((mode_t)mask); + break; ++ case 'm': ++ /* Force permissions on file received via sftp */ ++ permforce = 1; ++ permforcemode = strtol(optarg, &cp, 8); ++ if (permforcemode < 0 || permforcemode > 0777 || ++ *cp != '\0' || (permforcemode == 0 && ++ errno != 0)) ++ fatal("Invalid file mode \"%s\"", optarg); ++ break; + case 'h': + default: + sftp_server_usage();