]> git.ipfire.org Git - people/arne_f/ipfire-3.x.git/commitdiff
openssh: Update to 6.8p1.
authorStefan Schantl <stefan.schantl@ipfire.org>
Sat, 4 Apr 2015 20:58:32 +0000 (22:58 +0200)
committerStefan Schantl <stefan.schantl@ipfire.org>
Sun, 5 Apr 2015 08:44:57 +0000 (10:44 +0200)
Fixes #10534.

35 files changed:
openssh/openssh.nm
openssh/patches/openssh-4.3p2-askpass-grab-info.patch [deleted file]
openssh/patches/openssh-5.1p1-askpass-progress.patch [deleted file]
openssh/patches/openssh-5.1p1-scp-manpage.patch [deleted file]
openssh/patches/openssh-5.2p1-allow-ip-opts.patch [deleted file]
openssh/patches/openssh-5.5p1-x11.patch [deleted file]
openssh/patches/openssh-5.6p1-exit-deadlock.patch [deleted file]
openssh/patches/openssh-5.6p1-redhat.patch [deleted file]
openssh/patches/openssh-5.8p1-fingerprint.patch [deleted file]
openssh/patches/openssh-5.8p1-getaddrinfo.patch [deleted file]
openssh/patches/openssh-5.8p1-localdomain.patch [deleted file]
openssh/patches/openssh-5.8p1-packet.patch [deleted file]
openssh/patches/openssh-5.8p2-force_krb.patch [deleted file]
openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch [deleted file]
openssh/patches/openssh-5.8p2-sigpipe.patch [deleted file]
openssh/patches/openssh-5.9p1-akc.patch [deleted file]
openssh/patches/openssh-5.9p1-edns.patch [deleted file]
openssh/patches/openssh-5.9p1-ipfire.patch [deleted file]
openssh/patches/openssh-5.9p1-ipv6man.patch [deleted file]
openssh/patches/openssh-5.9p1-keygen.patch [deleted file]
openssh/patches/openssh-5.9p1-randclean.patch [deleted file]
openssh/patches/openssh-5.9p1-sftp-chroot.patch [deleted file]
openssh/patches/openssh-6.0p1-entropy.patch [deleted file]
openssh/patches/openssh-6.1p1-akc.patch [deleted file]
openssh/patches/openssh-6.1p1-askpass-ld.patch [deleted file]
openssh/patches/openssh-6.1p1-authenticationmethods.patch [deleted file]
openssh/patches/openssh-6.1p1-coverity.patch [deleted file]
openssh/patches/openssh-6.1p1-kuserok.patch [deleted file]
openssh/patches/openssh-6.1p1-required-authentications.patch [deleted file]
openssh/patches/openssh-6.1p1-role-mls.patch [deleted file]
openssh/patches/openssh-6.1p1-vendor.patch [deleted file]
openssh/patches/openssh-6.6p1-keyperm.patch [moved from openssh/patches/openssh-5.8p1-keyperm.patch with 54% similarity]
openssh/patches/openssh-6.7p1-audit.patch [new file with mode: 0644]
openssh/patches/openssh-6.7p1-seccomp-aarch64.patch [new file with mode: 0644]
openssh/patches/openssh-6.7p1-sftp-force-permission.patch [new file with mode: 0644]

index 10d43f474a4b92db586716a4571f71e3b57ad50d..59491fdebefac1c75e7e98c0d41716f09f89e1b5 100644 (file)
@@ -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 (file)
index e9dc835..0000000
+++ /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 (file)
index ec93b87..0000000
+++ /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 <string.h>
- #include <unistd.h>
- #include <X11/Xlib.h>
-+#include <glib.h>
- #include <gtk/gtk.h>
- #include <gdk/gdkx.h>
-@@ -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 (file)
index e314a05..0000000
+++ /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 (file)
index 96aaab1..0000000
+++ /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 (file)
index cac5d5e..0000000
+++ /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 (file)
index 278dfa1..0000000
+++ /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 (file)
index d1df8c1..0000000
+++ /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 (file)
index a0438ff..0000000
+++ /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 (file)
index 6f64067..0000000
+++ /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 (file)
index 2f21658..0000000
+++ /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 (file)
index 4951af6..0000000
+++ /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 (file)
index 1842ce4..0000000
+++ /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 <sys/types.h>
- #include <stdarg.h>
-+#include <stdio.h>
- #include <string.h>
-+#include <unistd.h>
- #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 <krb5.h>
- #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 (file)
index 4a25d9e..0000000
+++ /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 (file)
index 56af045..0000000
+++ /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 (file)
index 62a478b..0000000
+++ /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 <sys/types.h>
- #include <sys/stat.h>
-+#include <sys/wait.h>
- #include <fcntl.h>
- #include <pwd.h>
-@@ -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 <AuthorizedKeysCommand or .ssh/authorized_keys* */
- int
- user_key_allowed(struct passwd *pw, Key *key)
- {
-       u_int success, i;
-       char *file;
-+#ifdef WITH_AUTHORIZED_KEYS_COMMAND
-+      success = user_key_via_command_allowed2(pw, key);
-+      if (success > 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 (file)
index 34f3851..0000000
+++ /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 (file)
index cdb49c6..0000000
+++ /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 (file)
index ece1a73..0000000
+++ /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 (file)
index 69d4a6f..0000000
+++ /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 (file)
index a2c5d33..0000000
+++ /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 (file)
index cfe4366..0000000
+++ /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 (file)
index 79f05f4..0000000
+++ /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 <jchadima@redhat.com>
-+ *
-+ * 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 <errno.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <stdio.h>
-+#include <openssl/rand.h>
-+
-+#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 (file)
index 0401ba0..0000000
+++ /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 <sys/types.h>
- #include <sys/stat.h>
-+#include <sys/wait.h>
-+#include <errno.h>
- #include <fcntl.h>
-+#include <paths.h>
- #include <pwd.h>
-+#include <signal.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
-@@ -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 (file)
index f7a7fac..0000000
+++ /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 (file)
index 7b5a06a..0000000
+++ /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 (file)
index 0c8fb23..0000000
+++ /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 (file)
index 7b695e0..0000000
+++ /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 (file)
index bfc28ee..0000000
+++ /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 (file)
index 4de3dae..0000000
+++ /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 <selinux/selinux.h>
- #include <selinux/flask.h>
-+#include <selinux/context.h>
- #include <selinux/get_context_list.h>
-+#include <selinux/get_default_type.h>
-+#include <selinux/av_permissions.h>
-+
-+#ifdef HAVE_LINUX_AUDIT
-+#include <libaudit.h>
-+#include <unistd.h>
-+#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 <dwalsh@redhat.com>
-+ * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
-+ *
-+ * 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 <errno.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <stdio.h>
-+
-+#include "log.h"
-+#include "xmalloc.h"
-+#include "port-linux.h"
-+#include "key.h"
-+#include "hostfile.h"
-+#include "auth.h"
-+
-+#ifdef WITH_SELINUX
-+#include <selinux/selinux.h>
-+#include <selinux/flask.h>
-+#include <selinux/get_context_list.h>
-+
-+/* 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 (file)
index 9cb326d..0000000
+++ /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) {
similarity index 54%
rename from openssh/patches/openssh-5.8p1-keyperm.patch
rename to openssh/patches/openssh-6.6p1-keyperm.patch
index 6167c149da50b0d04be30961082b4d582d1cd03d..fbe33b0e12c0becb4b482d261c37ca03235f6a07 100644 (file)
@@ -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 <stdlib.h>
- #include <string.h>
- #include <unistd.h>
-+#include <grp.h>
+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 <errno.h>
+ #include <fcntl.h>
++#include <grp.h>
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include <stdlib.h>
+@@ -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 (file)
index 0000000..213ca67
--- /dev/null
@@ -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 <stdarg.h>
+ #include <string.h>
++#include <unistd.h>
+ #ifdef SSH_AUDIT_EVENTS
+@@ -36,6 +37,11 @@
+ #include "key.h"
+ #include "hostfile.h"
+ #include "auth.h"
++#include "ssh-gss.h"
++#include "monitor_wrap.h"
++#include "xmalloc.h"
++#include "misc.h"
++#include "servconf.h"
+ /*
+  * Care must be taken when using this since it WILL NOT be initialized when
+@@ -43,6 +49,7 @@
+  * audit_event(CONNECTION_ABANDON) is called.  Test for NULL before using.
+  */
+ extern Authctxt *the_authctxt;
++extern ServerOptions options;
+ /* Maybe add the audit class to struct Authmethod? */
+ ssh_audit_event_t
+@@ -71,13 +78,10 @@ audit_classify_auth(const char *method)
+ const char *
+ audit_username(void)
+ {
+-      static const char unknownuser[] = "(unknown user)";
+-      static const char invaliduser[] = "(invalid user)";
++      static const char unknownuser[] = "(unknown)";
+-      if (the_authctxt == NULL || the_authctxt->user == NULL)
++      if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid)
+               return (unknownuser);
+-      if (!the_authctxt->valid)
+-              return (invaliduser);
+       return (the_authctxt->user);
+ }
+@@ -111,6 +115,40 @@ audit_event_lookup(ssh_audit_event_t ev)
+       return(event_lookup[i].name);
+ }
++void
++audit_key(int host_user, int *rv, const Key *key)
++{
++      char *fp;
++      const char *crypto_name;
++
++      fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
++      if (key->type == KEY_RSA1)
++              crypto_name = "ssh-rsa1";
++      else
++              crypto_name = key_ssh_name(key);
++      if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0)
++              *rv = 0;
++      free(fp);
++}
++
++void
++audit_unsupported(int what)
++{
++      PRIVSEP(audit_unsupported_body(what));
++}
++
++void
++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs)
++{
++      PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid()));
++}
++
++void
++audit_session_key_free(int ctos)
++{
++      PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid()));
++}
++
+ # ifndef CUSTOM_SSH_AUDIT_EVENTS
+ /*
+  * Null implementations of audit functions.
+@@ -140,6 +178,17 @@ audit_event(ssh_audit_event_t event)
+ }
+ /*
++ * Called when a child process has called, or will soon call,
++ * audit_session_open.
++ */
++void
++audit_count_session_open(void)
++{
++      debug("audit count session open euid %d user %s", geteuid(),
++            audit_username());
++}
++
++/*
+  * Called when a user session is started.  Argument is the tty allocated to
+  * the session, or NULL if no tty was allocated.
+  *
+@@ -174,13 +223,91 @@ audit_session_close(struct logininfo *li)
+ /*
+  * This will be called when a user runs a non-interactive command.  Note that
+  * it may be called multiple times for a single connection since SSH2 allows
+- * multiple sessions within a single connection.
++ * multiple sessions within a single connection.  Returns a "handle" for
++ * audit_end_command.
+  */
+-void
++int
+ audit_run_command(const char *command)
+ {
+       debug("audit run command euid %d user %s command '%.200s'", geteuid(),
+           audit_username(), command);
++      return 0;
++}
++
++/*
++ * This will be called when the non-interactive command finishes.  Note that
++ * it may be called multiple times for a single connection since SSH2 allows
++ * multiple sessions within a single connection.  "handle" should come from
++ * the corresponding audit_run_command.
++ */
++void
++audit_end_command(int handle, const char *command)
++{
++      debug("audit end nopty exec  euid %d user %s command '%.200s'", geteuid(),
++          audit_username(), command);
++}
++
++/*
++ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key.
++ *
++ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key.
++ */
++int
++audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
++{
++      debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d", 
++              host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits,
++              sshkey_fingerprint_prefix(), fp, rv);
++}
++
++/*
++ * This will be called when the protocol negotiation fails.
++ */
++void
++audit_unsupported_body(int what)
++{
++      debug("audit unsupported protocol euid %d type %d", geteuid(), what);
++}
++
++/*
++ * This will be called on succesfull protocol negotiation.
++ */
++void
++audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid,
++             uid_t uid)
++{
++      debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u",
++              (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid,
++              (unsigned)uid);
++}
++
++/*
++ * This will be called on succesfull session key discard
++ */
++void
++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
++{
++      debug("audit session key discard euid %u direction %d from pid %ld uid %u",
++              (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid);
++}
++
++/*
++ * This will be called on destroy private part of the server key
++ */
++void
++audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
++{
++      debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u",
++              geteuid(), fp, (long)pid, (unsigned)uid);
++}
++
++/*
++ * This will be called on generation of the ephemeral server key
++ */
++void
++audit_generate_ephemeral_server_key(const char *)
++{
++      debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
+ }
+ # endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
+ #endif /* SSH_AUDIT_EVENTS */
+diff -up openssh-6.8p1/audit.h.audit openssh-6.8p1/audit.h
+--- openssh-6.8p1/audit.h.audit        2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/audit.h      2015-03-20 13:41:15.093883780 +0100
+@@ -28,6 +28,7 @@
+ # define _SSH_AUDIT_H
+ #include "loginrec.h"
++#include "key.h"
+ enum ssh_audit_event_type {
+       SSH_LOGIN_EXCEED_MAXTRIES,
+@@ -47,11 +48,25 @@ enum ssh_audit_event_type {
+ };
+ typedef enum ssh_audit_event_type ssh_audit_event_t;
++int   listening_for_clients(void);
++
+ void  audit_connection_from(const char *, int);
+ void  audit_event(ssh_audit_event_t);
++void  audit_count_session_open(void);
+ void  audit_session_open(struct logininfo *);
+ void  audit_session_close(struct logininfo *);
+-void  audit_run_command(const char *);
++int   audit_run_command(const char *);
++void  audit_end_command(int, const char *);
+ ssh_audit_event_t audit_classify_auth(const char *);
++int   audit_keyusage(int, const char *, unsigned, char *, int);
++void  audit_key(int, int *, const Key *);
++void  audit_unsupported(int);
++void  audit_kex(int, char *, char *, char *, char *);
++void  audit_unsupported_body(int);
++void  audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
++void  audit_session_key_free(int ctos);
++void  audit_session_key_free_body(int ctos, pid_t, uid_t);
++void  audit_destroy_sensitive_data(const char *, pid_t, uid_t);
++void  audit_generate_ephemeral_server_key(const char *);
+ #endif /* _SSH_AUDIT_H */
+diff -up openssh-6.8p1/auditstub.c.audit openssh-6.8p1/auditstub.c
+--- openssh-6.8p1/auditstub.c.audit    2015-03-20 13:41:15.093883780 +0100
++++ openssh-6.8p1/auditstub.c  2015-03-20 13:41:15.093883780 +0100
+@@ -0,0 +1,50 @@
++/* $Id: auditstub.c,v 1.1 jfch Exp $ */
++
++/*
++ * Copyright 2010 Red Hat, Inc.  All rights reserved.
++ * Use is subject to license terms.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Red Hat author: Jan F. Chadima <jchadima@redhat.com>
++ */
++
++#include <sys/types.h>
++
++void
++audit_unsupported(int n)
++{
++}
++
++void
++audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs)
++{
++}
++
++void
++audit_session_key_free(int ctos)
++{
++}
++
++void
++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
++{
++}
+diff -up openssh-6.8p1/auth-rsa.c.audit openssh-6.8p1/auth-rsa.c
+--- openssh-6.8p1/auth-rsa.c.audit     2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/auth-rsa.c   2015-03-20 13:41:15.094883779 +0100
+@@ -95,7 +95,10 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
+ {
+       u_char buf[32], mdbuf[16];
+       struct ssh_digest_ctx *md;
+-      int len;
++      int len, rv;
++#ifdef SSH_AUDIT_EVENTS
++      char *fp;
++#endif
+       /* don't allow short keys */
+       if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
+@@ -119,12 +122,18 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
+       ssh_digest_free(md);
+       /* Verify that the response is the original challenge. */
+-      if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
+-              /* Wrong answer. */
+-              return (0);
++      rv = timingsafe_bcmp(response, mdbuf, 16) == 0;
++
++#ifdef SSH_AUDIT_EVENTS
++      fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
++      if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) {
++              debug("unsuccessful audit");
++              rv = 0;
+       }
+-      /* Correct answer. */
+-      return (1);
++      free(fp);
++#endif
++
++      return rv;
+ }
+ /*
+diff -up openssh-6.8p1/auth.c.audit openssh-6.8p1/auth.c
+--- openssh-6.8p1/auth.c.audit 2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/auth.c       2015-03-20 13:41:15.094883779 +0100
+@@ -644,9 +644,6 @@ getpwnamallow(const char *user)
+               record_failed_login(user,
+                   get_canonical_hostname(options.use_dns), "ssh");
+ #endif
+-#ifdef SSH_AUDIT_EVENTS
+-              audit_event(SSH_INVALID_USER);
+-#endif /* SSH_AUDIT_EVENTS */
+               return (NULL);
+       }
+       if (!allowed_user(pw))
+diff -up openssh-6.8p1/auth.h.audit openssh-6.8p1/auth.h
+--- openssh-6.8p1/auth.h.audit 2015-03-20 13:41:15.002883927 +0100
++++ openssh-6.8p1/auth.h       2015-03-20 13:41:15.094883779 +0100
+@@ -195,6 +195,7 @@ void       abandon_challenge_response(Authctxt
+ char  *expand_authorized_keys(const char *, struct passwd *pw);
+ char  *authorized_principals_file(struct passwd *);
++int    user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
+ FILE  *auth_openkeyfile(const char *, struct passwd *, int);
+ FILE  *auth_openprincipals(const char *, struct passwd *, int);
+@@ -213,6 +214,7 @@ int         get_hostkey_index(Key *, int, struc
+ int    ssh1_session_key(BIGNUM *);
+ int    sshd_hostkey_sign(Key *, Key *, u_char **, size_t *,
+            const u_char *, size_t, u_int);
++int    hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
+ /* debug messages during authentication */
+ void   auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
+diff -up openssh-6.8p1/auth2-hostbased.c.audit openssh-6.8p1/auth2-hostbased.c
+--- openssh-6.8p1/auth2-hostbased.c.audit      2015-03-20 13:41:15.002883927 +0100
++++ openssh-6.8p1/auth2-hostbased.c    2015-03-20 13:41:15.093883780 +0100
+@@ -147,7 +147,7 @@ userauth_hostbased(Authctxt *authctxt)
+       /* test for allowed key and correct signature */
+       authenticated = 0;
+       if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
+-          PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
++          PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b),
+                       buffer_len(&b))) == 1)
+               authenticated = 1;
+@@ -164,6 +164,18 @@ done:
+       return authenticated;
+ }
++int
++hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
++{
++      int rv;
++
++      rv = key_verify(key, sig, slen, data, datalen);
++#ifdef SSH_AUDIT_EVENTS
++      audit_key(0, &rv, key);
++#endif
++      return rv;
++}
++
+ /* return 1 if given hostkey is allowed */
+ int
+ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
+diff -up openssh-6.8p1/auth2-pubkey.c.audit openssh-6.8p1/auth2-pubkey.c
+--- openssh-6.8p1/auth2-pubkey.c.audit 2015-03-20 13:41:15.013883910 +0100
++++ openssh-6.8p1/auth2-pubkey.c       2015-03-20 13:41:15.094883779 +0100
+@@ -172,7 +172,7 @@ userauth_pubkey(Authctxt *authctxt)
+               /* test for correct signature */
+               authenticated = 0;
+               if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
+-                  PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
++                  PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b),
+                   buffer_len(&b))) == 1) {
+                       authenticated = 1;
+                       /* Record the successful key to prevent reuse */
+@@ -250,6 +250,18 @@ pubkey_auth_info(Authctxt *authctxt, con
+       free(extra);
+ }
++int
++user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
++{
++      int rv;
++
++      rv = key_verify(key, sig, slen, data, datalen);
++#ifdef SSH_AUDIT_EVENTS
++      audit_key(1, &rv, key);
++#endif
++      return rv;
++}
++
+ static int
+ match_principals_option(const char *principal_list, struct sshkey_cert *cert)
+ {
+diff -up openssh-6.8p1/auth2.c.audit openssh-6.8p1/auth2.c
+--- openssh-6.8p1/auth2.c.audit        2015-03-20 13:41:15.044883860 +0100
++++ openssh-6.8p1/auth2.c      2015-03-20 13:41:15.093883780 +0100
+@@ -249,9 +249,6 @@ input_userauth_request(int type, u_int32
+               } else {
+                       logit("input_userauth_request: invalid user %s", user);
+                       authctxt->pw = fakepw();
+-#ifdef SSH_AUDIT_EVENTS
+-                      PRIVSEP(audit_event(SSH_INVALID_USER));
+-#endif
+               }
+ #ifdef USE_PAM
+               if (options.use_pam)
+diff -up openssh-6.8p1/cipher.c.audit openssh-6.8p1/cipher.c
+--- openssh-6.8p1/cipher.c.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/cipher.c     2015-03-20 13:41:15.101883767 +0100
+@@ -57,26 +59,6 @@ extern const EVP_CIPHER *evp_ssh1_3des(v
+ extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
+ #endif
+-struct sshcipher {
+-      char    *name;
+-      int     number;         /* for ssh1 only */
+-      u_int   block_size;
+-      u_int   key_len;
+-      u_int   iv_len;         /* defaults to block_size */
+-      u_int   auth_len;
+-      u_int   discard_len;
+-      u_int   flags;
+-#define CFLAG_CBC             (1<<0)
+-#define CFLAG_CHACHAPOLY      (1<<1)
+-#define CFLAG_AESCTR          (1<<2)
+-#define CFLAG_NONE            (1<<3)
+-#ifdef WITH_OPENSSL
+-      const EVP_CIPHER        *(*evptype)(void);
+-#else
+-      void    *ignored;
+-#endif
+-};
+-
+ static const struct sshcipher ciphers[] = {
+ #ifdef WITH_SSH1
+       { "des",        SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
+diff -up openssh-6.8p1/cipher.h.audit openssh-6.8p1/cipher.h
+--- openssh-6.8p1/cipher.h.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/cipher.h     2015-03-20 13:41:15.094883779 +0100
+@@ -62,7 +62,26 @@
+ #define CIPHER_ENCRYPT                1
+ #define CIPHER_DECRYPT                0
+-struct sshcipher;
++struct sshcipher {
++      char    *name;
++      int     number;         /* for ssh1 only */
++      u_int   block_size;
++      u_int   key_len;
++      u_int   iv_len;         /* defaults to block_size */
++      u_int   auth_len;
++      u_int   discard_len;
++      u_int   flags;
++#define CFLAG_CBC             (1<<0)
++#define CFLAG_CHACHAPOLY      (1<<1)
++#define CFLAG_AESCTR          (1<<2)
++#define CFLAG_NONE            (1<<3)
++#ifdef WITH_OPENSSL
++      const EVP_CIPHER        *(*evptype)(void);
++#else
++      void    *ignored;
++#endif
++};
++
+ struct sshcipher_ctx {
+       int     plaintext;
+       int     encrypt;
+diff -up openssh-6.8p1/kex.c.audit openssh-6.8p1/kex.c
+--- openssh-6.8p1/kex.c.audit  2015-03-20 13:41:15.046883856 +0100
++++ openssh-6.8p1/kex.c        2015-03-20 13:41:15.101883767 +0100
+@@ -54,6 +55,7 @@
+ #include "ssherr.h"
+ #include "sshbuf.h"
+ #include "digest.h"
++#include "audit.h"
+ #ifdef GSSAPI
+ #include "ssh-gss.h"
+@@ -484,8 +508,12 @@ choose_enc(struct sshenc *enc, char *cli
+ {
+       char *name = match_list(client, server, NULL);
+-      if (name == NULL)
++      if (name == NULL) {
++#ifdef SSH_AUDIT_EVENTS
++              audit_unsupported(0);
++#endif
+               return SSH_ERR_NO_CIPHER_ALG_MATCH;
++      }
+       if ((enc->cipher = cipher_by_name(name)) == NULL)
+               return SSH_ERR_INTERNAL_ERROR;
+       enc->name = name;
+@@ -503,8 +531,12 @@ choose_mac(struct ssh *ssh, struct sshma
+ {
+       char *name = match_list(client, server, NULL);
+-      if (name == NULL)
++      if (name == NULL) {
++#ifdef SSH_AUDIT_EVENTS
++              audit_unsupported(1);
++#endif
+               return SSH_ERR_NO_MAC_ALG_MATCH;
++      }
+       if (mac_setup(mac, name) < 0)
+               return SSH_ERR_INTERNAL_ERROR;
+       /* truncate the key */
+@@ -521,8 +553,12 @@ choose_comp(struct sshcomp *comp, char *
+ {
+       char *name = match_list(client, server, NULL);
+-      if (name == NULL)
++      if (name == NULL) {
++#ifdef SSH_AUDIT_EVENTS
++              audit_unsupported(2);
++#endif
+               return SSH_ERR_NO_COMPRESS_ALG_MATCH;
++      }
+       if (strcmp(name, "zlib@openssh.com") == 0) {
+               comp->type = COMP_DELAYED;
+       } else if (strcmp(name, "zlib") == 0) {
+@@ -672,6 +708,10 @@ kex_choose_conf(struct ssh *ssh)
+               dh_need = MAX(dh_need, newkeys->enc.block_size);
+               dh_need = MAX(dh_need, newkeys->enc.iv_len);
+               dh_need = MAX(dh_need, newkeys->mac.key_len);
++              debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need);
++#ifdef SSH_AUDIT_EVENTS
++              audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name);
++#endif
+       }
+       /* XXX need runden? */
+       kex->we_need = need;
+@@ -847,3 +887,34 @@ dump_digest(char *msg, u_char *digest, i
+       sshbuf_dump_data(digest, len, stderr);
+ }
+ #endif
++
++static void
++enc_destroy(struct sshenc *enc)
++{
++      if (enc == NULL)
++              return;
++
++      if (enc->key) {
++              memset(enc->key, 0, enc->key_len);
++              free(enc->key);
++      }
++
++      if (enc->iv) {
++              memset(enc->iv,  0, enc->block_size);
++              free(enc->iv);
++      }
++
++      memset(enc, 0, sizeof(*enc));
++}
++
++void
++newkeys_destroy(struct newkeys *newkeys)
++{
++      if (newkeys == NULL)
++              return;
++
++      enc_destroy(&newkeys->enc);
++      mac_destroy(&newkeys->mac);
++      memset(&newkeys->comp, 0, sizeof(newkeys->comp));
++}
++
+diff -up openssh-6.8p1/kex.h.audit openssh-6.8p1/kex.h
+--- openssh-6.8p1/kex.h.audit  2015-03-20 13:41:15.046883856 +0100
++++ openssh-6.8p1/kex.h        2015-03-20 13:41:15.095883777 +0100
+@@ -199,6 +199,8 @@ int         kexgss_client(struct ssh *);
+ int    kexgss_server(struct ssh *);
+ #endif
++void  newkeys_destroy(struct newkeys *newkeys);
++
+ int    kex_dh_hash(const char *, const char *,
+     const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
+     const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *);
+diff -up openssh-6.8p1/key.h.audit openssh-6.8p1/key.h
+--- openssh-6.8p1/key.h.audit  2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/key.h        2015-03-20 13:41:15.095883777 +0100
+@@ -50,6 +50,7 @@ typedef struct sshkey Key;
+ #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid
+ #define key_ecdsa_key_to_nid  sshkey_ecdsa_key_to_nid
+ #define key_is_cert           sshkey_is_cert
++#define key_is_private                sshkey_is_private
+ #define key_type_plain                sshkey_type_plain
+ #define key_cert_is_legacy    sshkey_cert_is_legacy
+ #define key_curve_name_to_nid sshkey_curve_name_to_nid
+diff -up openssh-6.8p1/mac.c.audit openssh-6.8p1/mac.c
+--- openssh-6.8p1/mac.c.audit  2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/mac.c        2015-03-20 13:41:15.102883766 +0100
+@@ -226,6 +246,20 @@ mac_clear(struct sshmac *mac)
+       mac->umac_ctx = NULL;
+ }
++void
++mac_destroy(struct sshmac *mac)
++{
++      if (mac == NULL)
++              return;
++
++      if (mac->key) {
++              memset(mac->key, 0, mac->key_len);
++              free(mac->key);
++      }
++
++      memset(mac, 0, sizeof(*mac));
++}
++
+ /* XXX copied from ciphers_valid */
+ #define       MAC_SEP ","
+ int
+diff -up openssh-6.8p1/mac.h.audit openssh-6.8p1/mac.h
+--- openssh-6.8p1/mac.h.audit  2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/mac.h        2015-03-20 13:41:15.095883777 +0100
+@@ -47,5 +47,6 @@ int   mac_init(struct sshmac *);
+ int    mac_compute(struct sshmac *, u_int32_t, const u_char *, int,
+     u_char *, size_t);
+ void   mac_clear(struct sshmac *);
++void   mac_destroy(struct sshmac *);
+ #endif /* SSHMAC_H */
+diff -up openssh-6.8p1/monitor.c.audit openssh-6.8p1/monitor.c
+--- openssh-6.8p1/monitor.c.audit      2015-03-20 13:41:15.072883814 +0100
++++ openssh-6.8p1/monitor.c    2015-03-20 13:41:15.107883758 +0100
+@@ -102,6 +102,7 @@
+ #include "ssh2.h"
+ #include "roaming.h"
+ #include "authfd.h"
++#include "audit.h"
+ #include "match.h"
+ #include "ssherr.h"
+@@ -117,6 +118,8 @@ extern Buffer auth_debug;
+ extern int auth_debug_init;
+ extern Buffer loginmsg;
++extern void destroy_sensitive_data(int);
++
+ /* State exported from the child */
+ static struct sshbuf *child_state;
+@@ -167,6 +170,11 @@ int mm_answer_gss_updatecreds(int, Buffe
+ #ifdef SSH_AUDIT_EVENTS
+ int mm_answer_audit_event(int, Buffer *);
+ int mm_answer_audit_command(int, Buffer *);
++int mm_answer_audit_end_command(int, Buffer *);
++int mm_answer_audit_unsupported_body(int, Buffer *);
++int mm_answer_audit_kex_body(int, Buffer *);
++int mm_answer_audit_session_key_free_body(int, Buffer *);
++int mm_answer_audit_server_key_free(int, Buffer *);
+ #endif
+ static int monitor_read_log(struct monitor *);
+@@ -226,6 +234,10 @@ struct mon_table mon_dispatch_proto20[]
+ #endif
+ #ifdef SSH_AUDIT_EVENTS
+     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
++    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
++    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
++    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
++    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
+ #endif
+ #ifdef BSD_AUTH
+     {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
+@@ -264,6 +276,11 @@ struct mon_table mon_dispatch_postauth20
+ #ifdef SSH_AUDIT_EVENTS
+     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+     {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
++    {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
++    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
++    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
++    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
++    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
+ #endif
+     {0, 0, NULL}
+ };
+@@ -296,6 +313,10 @@ struct mon_table mon_dispatch_proto15[]
+ #endif
+ #ifdef SSH_AUDIT_EVENTS
+     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
++    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
++    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
++    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
++    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
+ #endif
+ #endif /* WITH_SSH1 */
+     {0, 0, NULL}
+@@ -309,6 +330,11 @@ struct mon_table mon_dispatch_postauth15
+ #ifdef SSH_AUDIT_EVENTS
+     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+     {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
++    {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
++    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
++    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
++    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
++    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
+ #endif
+ #endif /* WITH_SSH1 */
+     {0, 0, NULL}
+@@ -1466,9 +1493,11 @@ mm_answer_keyverify(int sock, Buffer *m)
+       Key *key;
+       u_char *signature, *data, *blob;
+       u_int signaturelen, datalen, bloblen;
++      int type = 0;
+       int verified = 0;
+       int valid_data = 0;
++      type = buffer_get_int(m);
+       blob = buffer_get_string(m, &bloblen);
+       signature = buffer_get_string(m, &signaturelen);
+       data = buffer_get_string(m, &datalen);
+@@ -1476,6 +1505,8 @@ mm_answer_keyverify(int sock, Buffer *m)
+       if (hostbased_cuser == NULL || hostbased_chost == NULL ||
+         !monitor_allowed_key(blob, bloblen))
+               fatal("%s: bad key, not previously allowed", __func__);
++      if (type != key_blobtype)
++              fatal("%s: bad key type", __func__);
+       key = key_from_blob(blob, bloblen);
+       if (key == NULL)
+@@ -1496,7 +1527,17 @@ mm_answer_keyverify(int sock, Buffer *m)
+       if (!valid_data)
+               fatal("%s: bad signature data blob", __func__);
+-      verified = key_verify(key, signature, signaturelen, data, datalen);
++      switch (key_blobtype) {
++      case MM_USERKEY:
++              verified = user_key_verify(key, signature, signaturelen, data, datalen);
++              break;
++      case MM_HOSTKEY:
++              verified = hostbased_key_verify(key, signature, signaturelen, data, datalen);
++              break;
++      default:
++              verified = 0;
++              break;
++      }
+       debug3("%s: key %p signature %s",
+           __func__, key, (verified == 1) ? "verified" : "unverified");
+@@ -1554,6 +1595,12 @@ mm_session_close(Session *s)
+               debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
+               session_pty_cleanup2(s);
+       }
++#ifdef SSH_AUDIT_EVENTS
++      if (s->command != NULL) {
++              debug3("%s: command %d", __func__, s->command_handle);
++              session_end_command2(s);
++      }
++#endif
+       session_unused(s->self);
+ }
+@@ -1836,6 +1883,8 @@ mm_answer_term(int sock, Buffer *req)
+               sshpam_cleanup();
+ #endif
++      destroy_sensitive_data(0);
++
+       while (waitpid(pmonitor->m_pid, &status, 0) == -1)
+               if (errno != EINTR)
+                       exit(1);
+@@ -1878,11 +1927,43 @@ mm_answer_audit_command(int socket, Buff
+ {
+       u_int len;
+       char *cmd;
++      Session *s;
+       debug3("%s entering", __func__);
+       cmd = buffer_get_string(m, &len);
++
+       /* sanity check command, if so how? */
+-      audit_run_command(cmd);
++      s = session_new();
++      if (s == NULL)
++              fatal("%s: error allocating a session", __func__);
++      s->command = cmd;
++      s->command_handle = audit_run_command(cmd);
++
++      buffer_clear(m);
++      buffer_put_int(m, s->self);
++
++      mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m);
++
++      return (0);
++}
++
++int
++mm_answer_audit_end_command(int socket, Buffer *m)
++{
++      int handle;
++      u_int len;
++      char *cmd;
++      Session *s;
++
++      debug3("%s entering", __func__);
++      handle = buffer_get_int(m);
++      cmd = buffer_get_string(m, &len);
++
++      s = session_by_id(handle);
++      if (s == NULL || s->ttyfd != -1 || s->command == NULL ||
++          strcmp(s->command, cmd) != 0)
++              fatal("%s: invalid handle", __func__);
++      mm_session_close(s);
+       free(cmd);
+       return (0);
+ }
+@@ -1936,6 +2017,7 @@
+ void
+ mm_get_keystate(struct monitor *pmonitor)
+ {
++      Buffer m;
+       debug3("%s: Waiting for new keys", __func__);
+       if ((child_state = sshbuf_new()) == NULL)
+@@ -1946,6 +2027,21 @@ mm_get_keystate(struct monitor *pmonitor
+       mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT,
+           child_state);
+       debug3("%s: GOT new keys", __func__);
++
++#ifdef SSH_AUDIT_EVENTS
++      if (compat20) {
++              buffer_init(&m);
++              mm_request_receive_expect(pmonitor->m_sendfd,
++                                        MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
++              mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m);
++              buffer_free(&m);
++      }
++#endif
++
++      /* Drain any buffered messages from the child */
++      while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
++              ;
++
+ }
+@@ -2212,3 +2308,87 @@ mm_answer_gss_updatecreds(int socket, Bu
+ #endif /* GSSAPI */
++#ifdef SSH_AUDIT_EVENTS
++int
++mm_answer_audit_unsupported_body(int sock, Buffer *m)
++{
++      int what;
++
++      what = buffer_get_int(m);
++
++      audit_unsupported_body(what);
++
++      buffer_clear(m);
++
++      mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m);
++      return 0;
++}
++
++int
++mm_answer_audit_kex_body(int sock, Buffer *m)
++{
++      int ctos, len;
++      char *cipher, *mac, *compress, *pfs;
++      pid_t pid;
++      uid_t uid;
++
++      ctos = buffer_get_int(m);
++      cipher = buffer_get_string(m, &len);
++      mac = buffer_get_string(m, &len);
++      compress = buffer_get_string(m, &len);
++      pfs = buffer_get_string(m, &len);
++      pid = buffer_get_int64(m);
++      uid = buffer_get_int64(m);
++
++      audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid);
++
++      free(cipher);
++      free(mac);
++      free(compress);
++      free(pfs);
++      buffer_clear(m);
++
++      mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m);
++      return 0;
++}
++
++int
++mm_answer_audit_session_key_free_body(int sock, Buffer *m)
++{
++      int ctos;
++      pid_t pid;
++      uid_t uid;
++
++      ctos = buffer_get_int(m);
++      pid = buffer_get_int64(m);
++      uid = buffer_get_int64(m);
++
++      audit_session_key_free_body(ctos, pid, uid);
++
++      buffer_clear(m);
++
++      mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m);
++      return 0;
++}
++
++int
++mm_answer_audit_server_key_free(int sock, Buffer *m)
++{
++      int len;
++      char *fp;
++      pid_t pid;
++      uid_t uid;
++
++      fp = buffer_get_string(m, &len);
++      pid = buffer_get_int64(m);
++      uid = buffer_get_int64(m);
++
++      audit_destroy_sensitive_data(fp, pid, uid);
++
++      free(fp);
++      buffer_clear(m);
++
++      mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m);
++      return 0;
++}
++#endif /* SSH_AUDIT_EVENTS */
+diff -up openssh-6.8p1/monitor.h.audit openssh-6.8p1/monitor.h
+--- openssh-6.8p1/monitor.h.audit      2015-03-20 13:41:15.072883814 +0100
++++ openssh-6.8p1/monitor.h    2015-03-20 13:41:15.096883775 +0100
+@@ -69,7 +69,13 @@ enum monitor_reqtype {
+       MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107,
+       MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109,
+       MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
+-      MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
++      MONITOR_REQ_AUDIT_EVENT = 112,
++      MONITOR_REQ_AUDIT_COMMAND = 114, MONITOR_ANS_AUDIT_COMMAND = 115,
++      MONITOR_REQ_AUDIT_END_COMMAND = 116,
++      MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119,
++      MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121,
++      MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123,
++      MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124, MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 125
+ };
+diff -up openssh-6.8p1/monitor_wrap.c.audit openssh-6.8p1/monitor_wrap.c
+--- openssh-6.8p1/monitor_wrap.c.audit 2015-03-20 13:41:15.047883855 +0100
++++ openssh-6.8p1/monitor_wrap.c       2015-03-20 13:41:15.108883756 +0100
+@@ -461,7 +461,7 @@ mm_key_allowed(enum mm_keytype type, cha
+  */
+ int
+-mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
++mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
+ {
+       Buffer m;
+       u_char *blob;
+@@ -475,6 +475,7 @@ mm_key_verify(Key *key, u_char *sig, u_i
+               return (0);
+       buffer_init(&m);
++      buffer_put_int(&m, type);
+       buffer_put_string(&m, blob, len);
+       buffer_put_string(&m, sig, siglen);
+       buffer_put_string(&m, data, datalen);
+@@ -492,6 +493,18 @@ mm_key_verify(Key *key, u_char *sig, u_i
+       return (verified);
+ }
++int
++mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
++{
++      return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, datalen);
++}
++
++int
++mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
++{
++      return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen);
++}
++
+ void
+ mm_send_keystate(struct monitor *monitor)
+ {
+@@ -1005,10 +1018,11 @@ mm_audit_event(ssh_audit_event_t event)
+       buffer_free(&m);
+ }
+-void
++int
+ mm_audit_run_command(const char *command)
+ {
+       Buffer m;
++      int handle;
+       debug3("%s entering command %s", __func__, command);
+@@ -1016,6 +1030,26 @@ mm_audit_run_command(const char *command
+       buffer_put_cstring(&m, command);
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, &m);
++
++      handle = buffer_get_int(&m);
++      buffer_free(&m);
++
++      return (handle);
++}
++
++void
++mm_audit_end_command(int handle, const char *command)
++{
++      Buffer m;
++
++      debug3("%s entering command %s", __func__, command);
++
++      buffer_init(&m);
++      buffer_put_int(&m, handle);
++      buffer_put_cstring(&m, command);
++
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, &m);
+       buffer_free(&m);
+ }
+ #endif /* SSH_AUDIT_EVENTS */
+@@ -1151,3 +1185,72 @@ mm_ssh_gssapi_update_creds(ssh_gssapi_cc
+ #endif /* GSSAPI */
++#ifdef SSH_AUDIT_EVENTS
++void
++mm_audit_unsupported_body(int what)
++{
++      Buffer m;
++
++      buffer_init(&m);
++      buffer_put_int(&m, what);
++
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED,
++                                &m);
++
++      buffer_free(&m);
++}
++
++void
++mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid,
++                uid_t uid)
++{
++      Buffer m;
++
++      buffer_init(&m);
++      buffer_put_int(&m, ctos);
++      buffer_put_cstring(&m, cipher);
++      buffer_put_cstring(&m, (mac ? mac : ""));
++      buffer_put_cstring(&m, compress);
++      buffer_put_cstring(&m, fps);
++      buffer_put_int64(&m, pid);
++      buffer_put_int64(&m, uid);
++
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX,
++                                &m);
++
++      buffer_free(&m);
++}
++
++void
++mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
++{
++      Buffer m;
++
++      buffer_init(&m);
++      buffer_put_int(&m, ctos);
++      buffer_put_int64(&m, pid);
++      buffer_put_int64(&m, uid);
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE,
++                                &m);
++      buffer_free(&m);
++}
++
++void
++mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
++{
++      Buffer m;
++
++      buffer_init(&m);
++      buffer_put_cstring(&m, fp);
++      buffer_put_int64(&m, pid);
++      buffer_put_int64(&m, uid);
++
++      mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m);
++      mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SERVER_KEY_FREE,
++                                &m);
++      buffer_free(&m);
++}
++#endif /* SSH_AUDIT_EVENTS */
+diff -up openssh-6.8p1/monitor_wrap.h.audit openssh-6.8p1/monitor_wrap.h
+--- openssh-6.8p1/monitor_wrap.h.audit 2015-03-20 13:41:15.048883853 +0100
++++ openssh-6.8p1/monitor_wrap.h       2015-03-20 13:41:15.096883775 +0100
+@@ -52,7 +52,8 @@ int mm_key_allowed(enum mm_keytype, char
+ int mm_user_key_allowed(struct passwd *, Key *);
+ int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
+ int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
+-int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
++int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int);
++int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int);
+ int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
+ int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
+ BIGNUM *mm_auth_rsa_generate_challenge(Key *);
+@@ -79,7 +80,12 @@ void mm_sshpam_free_ctx(void *);
+ #ifdef SSH_AUDIT_EVENTS
+ #include "audit.h"
+ void mm_audit_event(ssh_audit_event_t);
+-void mm_audit_run_command(const char *);
++int mm_audit_run_command(const char *);
++void mm_audit_end_command(int, const char *);
++void mm_audit_unsupported_body(int);
++void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
++void mm_audit_session_key_free_body(int, pid_t, uid_t);
++void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t);
+ #endif
+ struct Session;
+diff -up openssh-6.8p1/packet.c.audit openssh-6.8p1/packet.c
+--- openssh-6.8p1/packet.c.audit       2015-03-20 13:41:14.990883947 +0100
++++ openssh-6.8p1/packet.c     2015-03-20 13:41:15.097883774 +0100
+@@ -67,6 +67,7 @@
+ #include "key.h"      /* typedefs XXX */
+ #include "xmalloc.h"
++#include "audit.h"
+ #include "crc32.h"
+ #include "deattack.h"
+ #include "compat.h"
+@@ -448,6 +449,13 @@ ssh_packet_get_connection_out(struct ssh
+       return ssh->state->connection_out;
+ }
++static int
++packet_state_has_keys (const struct session_state *state)
++{
++      return state != NULL &&
++              (state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL);
++}
++
+ /*
+  * Returns the IP-address of the remote host as a string.  The returned
+  * string must not be freed.
+@@ -478,13 +486,6 @@ ssh_packet_close(struct ssh *ssh)
+       if (!state->initialized)
+               return;
+       state->initialized = 0;
+-      if (state->connection_in == state->connection_out) {
+-              shutdown(state->connection_out, SHUT_RDWR);
+-              close(state->connection_out);
+-      } else {
+-              close(state->connection_in);
+-              close(state->connection_out);
+-      }
+       sshbuf_free(state->input);
+       sshbuf_free(state->output);
+       sshbuf_free(state->outgoing_packet);
+@@ -516,14 +517,24 @@ ssh_packet_close(struct ssh *ssh)
+                               inflateEnd(stream);
+               }
+       }
+-      if ((r = cipher_cleanup(&state->send_context)) != 0)
+-              error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
+-      if ((r = cipher_cleanup(&state->receive_context)) != 0)
+-              error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
++      if (packet_state_has_keys(state)) {
++              if ((r = cipher_cleanup(&state->send_context)) != 0)
++                      error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
++              if ((r = cipher_cleanup(&state->receive_context)) != 0)
++                      error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
++              audit_session_key_free(2);
++      }
+       if (ssh->remote_ipaddr) {
+               free(ssh->remote_ipaddr);
+               ssh->remote_ipaddr = NULL;
+       }
++      if (state->connection_in == state->connection_out) {
++              shutdown(state->connection_out, SHUT_RDWR);
++              close(state->connection_out);
++      } else {
++              close(state->connection_in);
++              close(state->connection_out);
++      }
+       free(ssh->state);
+       ssh->state = NULL;
+ }
+@@ -941,6 +952,7 @@ ssh_set_newkeys(struct ssh *ssh, int mod
+       }
+       if (state->newkeys[mode] != NULL) {
+               debug("set_newkeys: rekeying");
++              audit_session_key_free(mode);
+               if ((r = cipher_cleanup(cc)) != 0)
+                       return r;
+               enc  = &state->newkeys[mode]->enc;
+@@ -2263,6 +2275,75 @@ ssh_packet_get_output(struct ssh *ssh)
+       return (void *)ssh->state->output;
+ }
++static void
++newkeys_destroy_and_free(struct newkeys *newkeys)
++{
++      if (newkeys == NULL)
++              return;
++
++      free(newkeys->enc.name);
++
++      if (newkeys->mac.enabled) {
++              mac_clear(&newkeys->mac);
++              free(newkeys->mac.name);
++      }
++
++      free(newkeys->comp.name);
++
++      newkeys_destroy(newkeys);
++      free(newkeys);
++}
++
++static void
++packet_destroy_state(struct session_state *state)
++{
++      if (state == NULL)
++              return;
++
++      cipher_cleanup(&state->receive_context);
++      cipher_cleanup(&state->send_context);
++
++      buffer_free(state->input);
++      state->input = NULL;
++      buffer_free(state->output);
++      state->output = NULL;
++      buffer_free(state->outgoing_packet);
++      state->outgoing_packet = NULL;
++      buffer_free(state->incoming_packet);
++      state->incoming_packet = NULL;
++      if( state->compression_buffer ) {
++              buffer_free(state->compression_buffer);
++              state->compression_buffer = NULL;
++      }
++      newkeys_destroy_and_free(state->newkeys[MODE_IN]);
++      state->newkeys[MODE_IN] = NULL;
++      newkeys_destroy_and_free(state->newkeys[MODE_OUT]);
++      state->newkeys[MODE_OUT] = NULL;
++      mac_destroy(state->packet_discard_mac);
++//    TAILQ_HEAD(, packet) outgoing;
++//    memset(state, 0, sizeof(state));
++}
++
++void
++packet_destroy_all(int audit_it, int privsep)
++{
++      if (audit_it)
++              audit_it = (active_state != NULL && packet_state_has_keys(active_state->state))
++                      || (backup_state != NULL && packet_state_has_keys(backup_state->state));
++      if (active_state != NULL)
++              packet_destroy_state(active_state->state);
++      if (backup_state != NULL)
++              packet_destroy_state(backup_state->state);
++      if (audit_it) {
++#ifdef SSH_AUDIT_EVENTS
++              if (privsep)
++                      audit_session_key_free(2);
++              else
++                      audit_session_key_free_body(2, getpid(), getuid());
++#endif
++      }
++}
++
+ /* XXX TODO update roaming to new API (does not work anyway) */
+ /*
+  * Save the state for the real connection, and use a separate state when
+@@ -2272,18 +2373,12 @@ void
+ ssh_packet_backup_state(struct ssh *ssh,
+     struct ssh *backup_state)
+ {
+-      struct ssh *tmp;
+-
+       close(ssh->state->connection_in);
+       ssh->state->connection_in = -1;
+       close(ssh->state->connection_out);
+       ssh->state->connection_out = -1;
+-      if (backup_state)
+-              tmp = backup_state;
+-      else
+-              tmp = ssh_alloc_session_state();
+       backup_state = ssh;
+-      ssh = tmp;
++      ssh = ssh_alloc_session_state();
+ }
+ /* XXX FIXME FIXME FIXME */
+@@ -2302,9 +2397,7 @@ ssh_packet_restore_state(struct ssh *ssh
+       backup_state = ssh;
+       ssh = tmp;
+       ssh->state->connection_in = backup_state->state->connection_in;
+-      backup_state->state->connection_in = -1;
+       ssh->state->connection_out = backup_state->state->connection_out;
+-      backup_state->state->connection_out = -1;
+       len = sshbuf_len(backup_state->state->input);
+       if (len > 0) {
+               if ((r = sshbuf_putb(ssh->state->input,
+@@ -2313,6 +2406,11 @@ ssh_packet_restore_state(struct ssh *ssh
+               sshbuf_reset(backup_state->state->input);
+               add_recv_bytes(len);
+       }
++      backup_state->state->connection_in = -1;
++      backup_state->state->connection_out = -1;
++      packet_destroy_state(backup_state->state);
++      free(backup_state);
++      backup_state = NULL;
+ }
+ /* Reset after_authentication and reset compression in post-auth privsep */
+diff -up openssh-6.8p1/packet.h.audit openssh-6.8p1/packet.h
+--- openssh-6.8p1/packet.h.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/packet.h     2015-03-20 13:41:15.097883774 +0100
+@@ -189,7 +189,7 @@ int        sshpkt_get_end(struct ssh *ssh);
+ const u_char  *sshpkt_ptr(struct ssh *, size_t *lenp);
+ /* OLD API */
+-extern struct ssh *active_state;
++extern struct ssh *active_state, *backup_state;
+ #include "opacket.h"
+ #if !defined(WITH_OPENSSL)
+@@ -203,4 +203,5 @@ extern struct ssh *active_state;
+ # undef EC_POINT
+ #endif
++void   packet_destroy_all(int, int);
+ #endif                                /* PACKET_H */
+diff -up openssh-6.8p1/session.c.audit openssh-6.8p1/session.c
+--- openssh-6.8p1/session.c.audit      2015-03-20 13:41:15.073883813 +0100
++++ openssh-6.8p1/session.c    2015-03-20 13:41:15.097883774 +0100
+@@ -139,7 +139,7 @@ extern int log_stderr;
+ extern int debug_flag;
+ extern u_int utmp_len;
+ extern int startup_pipe;
+-extern void destroy_sensitive_data(void);
++extern void destroy_sensitive_data(int);
+ extern Buffer loginmsg;
+ /* original command from peer. */
+@@ -731,6 +731,14 @@ do_exec_pty(Session *s, const char *comm
+       /* Parent.  Close the slave side of the pseudo tty. */
+       close(ttyfd);
++#ifndef HAVE_OSF_SIA
++      /* do_login in the child did not affect state in this process,
++         compensate.  From an architectural standpoint, this is extremely
++         ugly. */
++      if (!(options.use_login && command == NULL))
++              audit_count_session_open();
++#endif
++
+       /* Enter interactive session. */
+       s->ptymaster = ptymaster;
+       packet_set_interactive(1, 
+@@ -853,15 +861,19 @@ do_exec(Session *s, const char *command)
+           get_remote_port());
+ #ifdef SSH_AUDIT_EVENTS
++      if (s->command != NULL || s->command_handle != -1)
++              fatal("do_exec: command already set");
+       if (command != NULL)
+-              PRIVSEP(audit_run_command(command));
++              s->command = xstrdup(command);
+       else if (s->ttyfd == -1) {
+               char *shell = s->pw->pw_shell;
+               if (shell[0] == '\0')   /* empty shell means /bin/sh */
+                       shell =_PATH_BSHELL;
+-              PRIVSEP(audit_run_command(shell));
++              s->command = xstrdup(shell);
+       }
++      if (s->command != NULL && s->ptyfd == -1)
++              s->command_handle = PRIVSEP(audit_run_command(s->command));
+ #endif
+       if (s->ttyfd != -1)
+               ret = do_exec_pty(s, command);
+@@ -1704,7 +1716,10 @@ do_child(Session *s, const char *command
+       int r = 0;
+       /* remove hostkey from the child's memory */
+-      destroy_sensitive_data();
++      destroy_sensitive_data(1);
++      /* Don't audit this - both us and the parent would be talking to the
++         monitor over a single socket, with no synchronization. */
++      packet_destroy_all(0, 1);
+       /* Force a password change */
+       if (s->authctxt->force_pwchange) {
+@@ -1934,6 +1949,7 @@ session_unused(int id)
+       sessions[id].ttyfd = -1;
+       sessions[id].ptymaster = -1;
+       sessions[id].x11_chanids = NULL;
++      sessions[id].command_handle = -1;
+       sessions[id].next_unused = sessions_first_unused;
+       sessions_first_unused = id;
+ }
+@@ -2016,6 +2032,19 @@ session_open(Authctxt *authctxt, int cha
+ }
+ Session *
++session_by_id(int id)
++{
++      if (id >= 0 && id < sessions_nalloc) {
++              Session *s = &sessions[id];
++              if (s->used)
++                      return s;
++      }
++      debug("session_by_id: unknown id %d", id);
++      session_dump();
++      return NULL;
++}
++
++Session *
+ session_by_tty(char *tty)
+ {
+       int i;
+@@ -2532,6 +2561,32 @@ session_exit_message(Session *s, int sta
+               chan_write_failed(c);
+ }
++#ifdef SSH_AUDIT_EVENTS
++void
++session_end_command2(Session *s)
++{
++      if (s->command != NULL) {
++              if (s->command_handle != -1)
++                      audit_end_command(s->command_handle, s->command);
++              free(s->command);
++              s->command = NULL;
++              s->command_handle = -1;
++      }
++}
++
++static void
++session_end_command(Session *s)
++{
++      if (s->command != NULL) {
++              if (s->command_handle != -1)
++                      PRIVSEP(audit_end_command(s->command_handle, s->command));
++              free(s->command);
++              s->command = NULL;
++              s->command_handle = -1;
++      }
++}
++#endif
++
+ void
+ session_close(Session *s)
+ {
+@@ -2540,6 +2593,10 @@ session_close(Session *s)
+       debug("session_close: session %d pid %ld", s->self, (long)s->pid);
+       if (s->ttyfd != -1)
+               session_pty_cleanup(s);
++#ifdef SSH_AUDIT_EVENTS
++      if (s->command)
++              session_end_command(s);
++#endif
+       free(s->term);
+       free(s->display);
+       free(s->x11_chanids);
+@@ -2754,6 +2811,15 @@ do_authenticated2(Authctxt *authctxt)
+       server_loop2(authctxt);
+ }
++static void
++do_cleanup_one_session(Session *s)
++{
++      session_pty_cleanup2(s);
++#ifdef SSH_AUDIT_EVENTS
++      session_end_command2(s);
++#endif
++}
++
+ void
+ do_cleanup(Authctxt *authctxt)
+ {
+@@ -2802,5 +2868,5 @@ do_cleanup(Authctxt *authctxt)
+        * or if running in monitor.
+        */
+       if (!use_privsep || mm_is_monitor())
+-              session_destroy_all(session_pty_cleanup2);
++              session_destroy_all(do_cleanup_one_session);
+ }
+diff -up openssh-6.8p1/session.h.audit openssh-6.8p1/session.h
+--- openssh-6.8p1/session.h.audit      2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/session.h    2015-03-20 13:41:15.097883774 +0100
+@@ -61,6 +61,12 @@ struct Session {
+               char    *name;
+               char    *val;
+       } *env;
++
++      /* exec */
++#ifdef SSH_AUDIT_EVENTS
++      int     command_handle;
++      char    *command;
++#endif
+ };
+ void   do_authenticated(Authctxt *);
+@@ -73,8 +79,10 @@ void         session_close_by_pid(pid_t, int);
+ void   session_close_by_channel(int, void *);
+ void   session_destroy_all(void (*)(Session *));
+ void   session_pty_cleanup2(Session *);
++void   session_end_command2(Session *);
+ Session       *session_new(void);
++Session *session_by_id(int);
+ Session       *session_by_tty(char *);
+ void   session_close(Session *);
+ void   do_setusercontext(struct passwd *);
+diff -up openssh-6.8p1/sshd.c.audit openssh-6.8p1/sshd.c
+--- openssh-6.8p1/sshd.c.audit 2015-03-20 13:41:15.083883796 +0100
++++ openssh-6.8p1/sshd.c       2015-03-20 13:41:15.110883753 +0100
+@@ -121,6 +124,7 @@
+ #endif
+ #include "monitor_wrap.h"
+ #include "roaming.h"
++#include "audit.h"
+ #include "ssh-sandbox.h"
+ #include "version.h"
+ #include "ssherr.h"
+@@ -260,7 +264,7 @@ Buffer loginmsg;
+ struct passwd *privsep_pw = NULL;
+ /* Prototypes for various functions defined later in this file. */
+-void destroy_sensitive_data(void);
++void destroy_sensitive_data(int);
+ void demote_sensitive_data(void);
+ #ifdef WITH_SSH1
+@@ -281,6 +285,15 @@ close_listen_socks(void)
+       num_listen_socks = -1;
+ }
++/*
++ * Is this process listening for clients (i.e. not specific to any specific
++ * client connection?)
++ */
++int listening_for_clients(void)
++{
++      return num_listen_socks > 0;
++}
++
+ static void
+ close_startup_pipes(void)
+ {
+@@ -560,22 +573,45 @@ sshd_exchange_identification(int sock_in
+       }
+ }
+-/* Destroy the host and server keys.  They will no longer be needed. */
++/*
++ * Destroy the host and server keys.  They will no longer be needed.  Careful,
++ * this can be called from cleanup_exit() - i.e. from just about anywhere.
++ */
+ void
+-destroy_sensitive_data(void)
++destroy_sensitive_data(int privsep)
+ {
+       int i;
++      pid_t pid;
++      uid_t uid;
+       if (sensitive_data.server_key) {
+               key_free(sensitive_data.server_key);
+               sensitive_data.server_key = NULL;
+       }
++      pid = getpid();
++      uid = getuid();
+       for (i = 0; i < options.num_host_key_files; i++) {
+               if (sensitive_data.host_keys[i]) {
++                      char *fp;
++
++                      if (key_is_private(sensitive_data.host_keys[i]))
++                              fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX);
++                      else
++                              fp = NULL;
+                       key_free(sensitive_data.host_keys[i]);
+                       sensitive_data.host_keys[i] = NULL;
++                      if (fp != NULL) {
++                              if (privsep)
++                                      PRIVSEP(audit_destroy_sensitive_data(fp,
++                                              pid, uid));
++                              else
++                                      audit_destroy_sensitive_data(fp,
++                                              pid, uid);
++                              free(fp);
++                      }
+               }
+-              if (sensitive_data.host_certificates[i]) {
++              if (sensitive_data.host_certificates
++                  && sensitive_data.host_certificates[i]) {
+                       key_free(sensitive_data.host_certificates[i]);
+                       sensitive_data.host_certificates[i] = NULL;
+               }
+@@ -589,6 +625,8 @@ void
+ demote_sensitive_data(void)
+ {
+       Key *tmp;
++      pid_t pid;
++      uid_t uid;
+       int i;
+       if (sensitive_data.server_key) {
+@@ -597,13 +635,25 @@ demote_sensitive_data(void)
+               sensitive_data.server_key = tmp;
+       }
++      pid = getpid();
++      uid = getuid();
+       for (i = 0; i < options.num_host_key_files; i++) {
+               if (sensitive_data.host_keys[i]) {
++                      char *fp;
++
++                      if (key_is_private(sensitive_data.host_keys[i]))
++                              fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX);
++                      else
++                              fp = NULL;
+                       tmp = key_demote(sensitive_data.host_keys[i]);
+                       key_free(sensitive_data.host_keys[i]);
+                       sensitive_data.host_keys[i] = tmp;
+                       if (tmp->type == KEY_RSA1)
+                               sensitive_data.ssh1_host_key = tmp;
++                      if (fp != NULL) {
++                              audit_destroy_sensitive_data(fp, pid, uid);
++                              free(fp);
++                      }
+               }
+               /* Certs do not need demotion */
+       }
+@@ -675,7 +725,7 @@ privsep_preauth(Authctxt *authctxt)
+       if (use_privsep == PRIVSEP_ON)
+               box = ssh_sandbox_init(pmonitor);
+-      pid = fork();
++      pmonitor->m_pid = pid = fork();
+       if (pid == -1) {
+               fatal("fork of unprivileged child failed");
+       } else if (pid != 0) {
+@@ -759,6 +811,12 @@ privsep_postauth(Authctxt *authctxt)
+       else if (pmonitor->m_pid != 0) {
+               verbose("User child is on pid %ld", (long)pmonitor->m_pid);
+               buffer_clear(&loginmsg);
++              if (*pmonitor->m_pkex != NULL ){
++                      newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]);
++                      newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_IN]);
++                      audit_session_key_free_body(2, getpid(), getuid());
++                      packet_destroy_all(0, 0);
++              }
+               monitor_child_postauth(pmonitor);
+               /* NEVERREACHED */
+@@ -1286,6 +1341,7 @@ server_accept_loop(int *sock_in, int *so
+               if (received_sigterm) {
+                       logit("Received signal %d; terminating.",
+                           (int) received_sigterm);
++                      destroy_sensitive_data(0);
+                       close_listen_socks();
+                       if (options.pid_file != NULL)
+                               unlink(options.pid_file);
+@@ -2242,6 +2321,7 @@ main(int ac, char **av)
+        */
+       if (use_privsep) {
+               mm_send_keystate(pmonitor);
++              packet_destroy_all(1, 1);
+               exit(0);
+       }
+@@ -2287,7 +2367,7 @@ main(int ac, char **av)
+               privsep_postauth(authctxt);
+               /* the monitor process [priv] will not return */
+               if (!compat20)
+-                      destroy_sensitive_data();
++                      destroy_sensitive_data(0);
+       }
+       packet_set_timeout(options.client_alive_interval,
+@@ -2301,6 +2381,9 @@ main(int ac, char **av)
+       do_authenticated(authctxt);
+       /* The connection has been terminated. */
++      packet_destroy_all(1, 1);
++      destroy_sensitive_data(1);
++
+       packet_get_bytes(&ibytes, &obytes);
+       verbose("Transferred: sent %llu, received %llu bytes",
+           (unsigned long long)obytes, (unsigned long long)ibytes);
+@@ -2461,6 +2544,10 @@ do_ssh1_kex(void)
+               if (cookie[i] != packet_get_char())
+                       packet_disconnect("IP Spoofing check bytes do not match.");
++#ifdef SSH_AUDIT_EVENTS
++      audit_kex(2, cipher_name(cipher_type), "crc", "none", "none");
++#endif
++
+       debug("Encryption type: %.200s", cipher_name(cipher_type));
+       /* Get the encrypted integer. */
+@@ -2520,7 +2607,7 @@ do_ssh1_kex(void)
+       }
+       /* Destroy the private and public keys. No longer. */
+-      destroy_sensitive_data();
++      destroy_sensitive_data(1);
+       if (use_privsep)
+               mm_ssh1_session_id(session_id);
+@@ -2703,6 +2802,16 @@ do_ssh2_kex(void)
+ void
+ cleanup_exit(int i)
+ {
++      static int in_cleanup = 0;
++      int is_privsep_child;
++
++      /* cleanup_exit can be called at the very least from the privsep
++         wrappers used for auditing.  Make sure we don't recurse
++         indefinitely. */
++      if (in_cleanup)
++              _exit(i);
++      in_cleanup = 1;
++
+       if (the_authctxt) {
+               do_cleanup(the_authctxt);
+               if (use_privsep && privsep_is_preauth &&
+@@ -2714,9 +2823,14 @@ cleanup_exit(int i)
+                                   pmonitor->m_pid, strerror(errno));
+               }
+       }
++      is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0;
++      if (sensitive_data.host_keys != NULL)
++              destroy_sensitive_data(is_privsep_child);
++      packet_destroy_all(1, is_privsep_child);
+ #ifdef SSH_AUDIT_EVENTS
+       /* done after do_cleanup so it can cancel the PAM auth 'thread' */
+-      if (!use_privsep || mm_is_monitor())
++      if ((the_authctxt == NULL || !the_authctxt->authenticated) &&
++          (!use_privsep || mm_is_monitor()))
+               audit_event(SSH_CONNECTION_ABANDON);
+ #endif
+       _exit(i);
+diff -up openssh-6.8p1/sshkey.c.audit openssh-6.8p1/sshkey.c
+--- openssh-6.8p1/sshkey.c.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/sshkey.c     2015-03-20 13:41:15.111883751 +0100
+@@ -317,6 +319,33 @@ sshkey_type_is_valid_ca(int type)
+ }
+ int
++sshkey_is_private(const struct sshkey *k)
++{
++      switch (k->type) {
++      case KEY_RSA_CERT_V00:
++      case KEY_RSA_CERT:
++      case KEY_RSA1:
++      case KEY_RSA:
++              return k->rsa->d != NULL;
++      case KEY_DSA_CERT_V00:
++      case KEY_DSA_CERT:
++      case KEY_DSA:
++              return k->dsa->priv_key != NULL;
++#ifdef OPENSSL_HAS_ECC
++      case KEY_ECDSA_CERT:
++      case KEY_ECDSA:
++              return EC_KEY_get0_private_key(k->ecdsa) != NULL;
++#endif
++      case KEY_ED25519_CERT:
++      case KEY_ED25519:
++              return (k->ed25519_pk != NULL);
++      default:
++              /* fatal("key_is_private: bad key type %d", k->type); */
++              return 0;
++      }
++}
++
++int
+ sshkey_is_cert(const struct sshkey *k)
+ {
+       if (k == NULL)
+diff -up openssh-6.8p1/sshkey.h.audit openssh-6.8p1/sshkey.h
+--- openssh-6.8p1/sshkey.h.audit       2015-03-17 06:49:20.000000000 +0100
++++ openssh-6.8p1/sshkey.h     2015-03-20 13:41:15.098883772 +0100
+@@ -134,6 +134,7 @@ u_int               sshkey_size(const struct sshkey
+ int            sshkey_generate(int type, u_int bits, struct sshkey **keyp);
+ int            sshkey_from_private(const struct sshkey *, struct sshkey **);
+ int    sshkey_type_from_name(const char *);
++int    sshkey_is_private(const struct sshkey *);
+ int    sshkey_is_cert(const struct sshkey *);
+ int    sshkey_type_is_cert(int);
+ int    sshkey_type_plain(int);
+diff -up openssh-6.8p1/sandbox-seccomp-filter.c.audit openssh-6.8p1/sandbox-seccomp-filter.c
+--- openssh-6.8p1/sandbox-seccomp-filter.c.audit       2015-03-20 13:41:15.088883788 +0100
++++ openssh-6.8p1/sandbox-seccomp-filter.c     2015-03-20 13:41:15.097883774 +0100
+@@ -110,6 +110,12 @@ static const struct sock_filter preauth_
+ #ifdef __NR_time /* not defined on EABI ARM */
+       SC_ALLOW(time),
+ #endif
++#ifdef SSH_AUDIT_EVENTS
++      SC_ALLOW(getuid),
++#ifdef __NR_getuid32 /* not defined on x86_64 */
++      SC_ALLOW(getuid32),
++#endif
++#endif
+       SC_ALLOW(read),
+       SC_ALLOW(write),
+       SC_ALLOW(close),
diff --git a/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch b/openssh/patches/openssh-6.7p1-seccomp-aarch64.patch
new file mode 100644 (file)
index 0000000..4285bd9
--- /dev/null
@@ -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 (file)
index 0000000..1a88e50
--- /dev/null
@@ -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();