]> git.ipfire.org Git - people/pmueller/ipfire-3.x.git/commitdiff
openssh: Update to 6.1p1.
authorStefan Schantl <stefan.schantl@ipfire.org>
Sat, 8 Dec 2012 17:22:54 +0000 (18:22 +0100)
committerStefan Schantl <stefan.schantl@ipfire.org>
Sat, 8 Dec 2012 21:30:58 +0000 (22:30 +0100)
This is a major update to the latest stable release.

* Update patchset.
* Remove non working configure flag "--with-ldap".
* Move service file for sshd-keygen into correct package.

12 files changed:
openssh/openssh.nm
openssh/patches/openssh-5.9p1-2auth.patch [deleted file]
openssh/patches/openssh-5.9p1-mls.patch [deleted file]
openssh/patches/openssh-6.0p1-entropy.patch [moved from openssh/patches/openssh-5.9p1-entropy.patch with 67% similarity]
openssh/patches/openssh-6.1p1-akc.patch [new file with mode: 0644]
openssh/patches/openssh-6.1p1-askpass-ld.patch [moved from openssh/patches/openssh-5.8p2-askpass-ld.patch with 53% similarity]
openssh/patches/openssh-6.1p1-authenticationmethods.patch [new file with mode: 0644]
openssh/patches/openssh-6.1p1-coverity.patch [moved from openssh/patches/openssh-5.9p1-coverity.patch with 73% similarity]
openssh/patches/openssh-6.1p1-kuserok.patch [moved from openssh/patches/openssh-5.9p1-kuserok.patch with 67% similarity]
openssh/patches/openssh-6.1p1-required-authentications.patch [new file with mode: 0644]
openssh/patches/openssh-6.1p1-role-mls.patch [moved from openssh/patches/openssh-5.9p1-role.patch with 50% similarity]
openssh/patches/openssh-6.1p1-vendor.patch [moved from openssh/patches/openssh-5.9p1-vendor.patch with 61% similarity]

index f46e85f4e1dbbd971b9b85c52e74416f669abc9a..10d43f474a4b92db586716a4571f71e3b57ad50d 100644 (file)
@@ -4,8 +4,8 @@
 ###############################################################################
 
 name       = openssh
-version    = 5.9p1
-release    = 8
+version    = 6.1p1
+release    = 1
 
 groups     = Application/Internet
 url        = http://www.openssh.com/portable.html
@@ -39,23 +39,21 @@ build
 
        # Apply patches in a special order
        patches
-               openssh-5.9p1-coverity.patch
+               openssh-6.1p1-coverity.patch
                openssh-5.8p1-fingerprint.patch
                openssh-5.8p1-getaddrinfo.patch
                openssh-5.8p1-packet.patch
-               openssh-5.9p1-2auth.patch
-               openssh-5.9p1-role.patch
-               openssh-5.9p1-mls.patch
+               openssh-6.1p1-authenticationmethods.patch
+               openssh-6.1p1-role-mls.patch
                openssh-5.9p1-sftp-chroot.patch
-               openssh-5.9p1-akc.patch
-               openssh-5.9p1-keygen.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-5.8p2-askpass-ld.patch
+               openssh-6.1p1-askpass-ld.patch
                openssh-5.5p1-x11.patch
                openssh-5.6p1-exit-deadlock.patch
                openssh-5.1p1-askpass-progress.patch
@@ -64,10 +62,11 @@ build
                openssh-5.1p1-scp-manpage.patch
                openssh-5.8p1-localdomain.patch
                openssh-5.9p1-ipfire.patch
-               openssh-5.9p1-entropy.patch
-               openssh-5.9p1-vendor.patch
+               openssh-6.0p1-entropy.patch
+               openssh-6.1p1-vendor.patch
                openssh-5.8p2-force_krb.patch
-               openssh-5.9p1-kuserok.patch
+               openssh-6.1p1-kuserok.patch
+               openssh-6.1p1-required-authentications.patch
        end
 
        configure_options += \
@@ -82,7 +81,6 @@ build
                --with-ssl-engine \
                --with-authorized-keys-command \
                --with-ipaddr-display \
-               --with-ldap \
                --with-pam \
                --with-libedit \
                --with-selinux \
@@ -168,6 +166,7 @@ packages
                        %{sysconfdir}/pam.d/sshd
                        %{sysconfdir}/ssh/sshd_config
                        %{unitdir}/sshd.service
+                       %{unitdir}/sshd-keygen.service
                        %{libdir}/openssh/sftp-server
                        %{sbindir}/sshd-keygen
                        %{sbindir}/sshd
diff --git a/openssh/patches/openssh-5.9p1-2auth.patch b/openssh/patches/openssh-5.9p1-2auth.patch
deleted file mode 100644 (file)
index b19d2ac..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-diff -up openssh-5.9p1/auth.h.2auth openssh-5.9p1/auth.h
---- openssh-5.9p1/auth.h.2auth 2011-05-29 13:39:38.000000000 +0200
-+++ openssh-5.9p1/auth.h       2011-09-17 11:36:54.314522599 +0200
-@@ -149,6 +149,8 @@ int        auth_root_allowed(char *);
- char  *auth2_read_banner(void);
-+void  userauth_restart(const char *);
-+
- void  privsep_challenge_enable(void);
- int   auth2_challenge(Authctxt *, char *);
-diff -up openssh-5.9p1/auth2.c.2auth openssh-5.9p1/auth2.c
---- openssh-5.9p1/auth2.c.2auth        2011-05-05 06:04:11.000000000 +0200
-+++ openssh-5.9p1/auth2.c      2011-09-17 11:36:54.402521709 +0200
-@@ -290,6 +290,24 @@ input_userauth_request(int type, u_int32
- }
- void
-+userauth_restart(const char *method)
-+{
-+      options.two_factor_authentication = 0;
-+
-+      debug2("userauth restart, method = %s", method);
-+      options.pubkey_authentication = options.second_pubkey_authentication && strcmp(method, method_pubkey.name);
-+#ifdef GSSAPI
-+      options.gss_authentication = options.second_gss_authentication && strcmp(method, method_gssapi.name);
-+#endif
-+#ifdef JPAKE
-+      options.zero_knowledge_password_authentication = options.second_zero_knowledge_password_authentication && strcmp(method, method_jpake.name);
-+#endif
-+      options.password_authentication = options.second_password_authentication && strcmp(method, method_passwd.name);
-+      options.kbd_interactive_authentication = options.second_kbd_interactive_authentication && strcmp(method, method_kbdint.name);
-+      options.hostbased_authentication = options.second_hostbased_authentication && strcmp(method, method_hostbased.name);
-+}
-+
-+void
- userauth_finish(Authctxt *authctxt, int authenticated, char *method)
- {
-       char *methods;
-@@ -337,6 +355,12 @@ userauth_finish(Authctxt *authctxt, int
-       /* XXX todo: check if multiple auth methods are needed */
-       if (authenticated == 1) {
-+              if (options.two_factor_authentication) {
-+                      userauth_restart(method);
-+                      debug("1st factor authentication done go to 2nd factor");
-+                      goto ask_methods;
-+              }
-+
-               /* turn off userauth */
-               dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
-               packet_start(SSH2_MSG_USERAUTH_SUCCESS);
-@@ -356,7 +380,9 @@ userauth_finish(Authctxt *authctxt, int
- #endif
-                       packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
-               }
-+ask_methods:
-               methods = authmethods_get();
-+              debug2("next auth methods = %s", methods);
-               packet_start(SSH2_MSG_USERAUTH_FAILURE);
-               packet_put_cstring(methods);
-               packet_put_char(0);     /* XXX partial success, unused */
-diff -up openssh-5.9p1/monitor.c.2auth openssh-5.9p1/monitor.c
---- openssh-5.9p1/monitor.c.2auth      2011-08-05 22:15:18.000000000 +0200
-+++ openssh-5.9p1/monitor.c    2011-09-17 11:36:54.513491937 +0200
-@@ -417,6 +417,10 @@ monitor_child_preauth(Authctxt *_authctx
-                       }
-               }
- #endif
-+              if (authenticated && options.two_factor_authentication) {
-+                      userauth_restart(auth_method);
-+                      authenticated = 0;
-+              }
-       }
-       /* Drain any buffered messages from the child */
-diff -up openssh-5.9p1/servconf.c.2auth openssh-5.9p1/servconf.c
---- openssh-5.9p1/servconf.c.2auth     2011-06-23 00:30:03.000000000 +0200
-+++ openssh-5.9p1/servconf.c   2011-09-17 11:36:54.632461730 +0200
-@@ -92,6 +92,13 @@ initialize_server_options(ServerOptions
-       options->hostbased_uses_name_from_packet_only = -1;
-       options->rsa_authentication = -1;
-       options->pubkey_authentication = -1;
-+      options->two_factor_authentication = -1;
-+      options->second_pubkey_authentication = -1;
-+      options->second_gss_authentication = -1;
-+      options->second_password_authentication = -1;
-+      options->second_kbd_interactive_authentication = -1;
-+      options->second_zero_knowledge_password_authentication = -1;
-+      options->second_hostbased_authentication = -1;
-       options->kerberos_authentication = -1;
-       options->kerberos_or_local_passwd = -1;
-       options->kerberos_ticket_cleanup = -1;
-@@ -237,6 +244,20 @@ fill_default_server_options(ServerOption
-               options->permit_empty_passwd = 0;
-       if (options->permit_user_env == -1)
-               options->permit_user_env = 0;
-+      if (options->two_factor_authentication == -1)
-+              options->two_factor_authentication = 0;
-+      if (options->second_pubkey_authentication == -1)
-+              options->second_pubkey_authentication = 1;
-+      if (options->second_gss_authentication == -1)
-+              options->second_gss_authentication = 0;
-+      if (options->second_password_authentication == -1)
-+              options->second_password_authentication = 1;
-+      if (options->second_kbd_interactive_authentication == -1)
-+              options->second_kbd_interactive_authentication = 0;
-+      if (options->second_zero_knowledge_password_authentication == -1)
-+              options->second_zero_knowledge_password_authentication = 0;
-+      if (options->second_hostbased_authentication == -1)
-+              options->second_hostbased_authentication = 0;
-       if (options->use_login == -1)
-               options->use_login = 0;
-       if (options->compression == -1)
-@@ -316,8 +337,11 @@ typedef enum {
-       sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
-       sMaxStartups, sMaxAuthTries, sMaxSessions,
-       sBanner, sUseDNS, sHostbasedAuthentication,
--      sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
--      sClientAliveCountMax, sAuthorizedKeysFile,
-+      sHostbasedUsesNameFromPacketOnly, sTwoFactorAuthentication,
-+      sSecondPubkeyAuthentication, sSecondGssAuthentication,
-+      sSecondPasswordAuthentication, sSecondKbdInteractiveAuthentication,
-+      sSecondZeroKnowledgePasswordAuthentication, sSecondHostbasedAuthentication,
-+      sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
-       sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
-       sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
-       sUsePrivilegeSeparation, sAllowAgentForwarding,
-@@ -395,6 +419,21 @@ static struct {
- #else
-       { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
- #endif
-+      { "twofactorauthentication", sTwoFactorAuthentication, SSHCFG_ALL },
-+      { "secondpubkeyauthentication", sSecondPubkeyAuthentication, SSHCFG_ALL },
-+#ifdef GSSAPI
-+      { "secondgssapiauthentication", sSecondGssAuthentication, SSHCFG_ALL },
-+#else
-+      { "secondgssapiauthentication", sUnsupported, SSHCFG_ALL },
-+#endif
-+      { "secondpasswordauthentication", sSecondPasswordAuthentication, SSHCFG_ALL },
-+      { "secondkbdinteractiveauthentication", sSecondKbdInteractiveAuthentication, SSHCFG_ALL },
-+#ifdef JPAKE
-+      { "secondzeroknowledgepasswordauthentication", sSecondZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
-+#else
-+      { "secondzeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
-+#endif
-+      { "secondhostbasedauthentication", sSecondHostbasedAuthentication, SSHCFG_ALL },
-       { "checkmail", sDeprecated, SSHCFG_GLOBAL },
-       { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
-       { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
-@@ -982,6 +1021,34 @@ process_server_config_line(ServerOptions
-               intptr = &options->challenge_response_authentication;
-               goto parse_flag;
-+      case sTwoFactorAuthentication:
-+              intptr = &options->two_factor_authentication;
-+              goto parse_flag;
-+
-+      case sSecondPubkeyAuthentication:
-+              intptr = &options->second_pubkey_authentication;
-+              goto parse_flag;
-+
-+      case sSecondGssAuthentication:
-+              intptr = &options->second_gss_authentication;
-+              goto parse_flag;
-+
-+      case sSecondPasswordAuthentication:
-+              intptr = &options->second_password_authentication;
-+              goto parse_flag;
-+
-+      case sSecondKbdInteractiveAuthentication:
-+              intptr = &options->second_kbd_interactive_authentication;
-+              goto parse_flag;
-+
-+      case sSecondZeroKnowledgePasswordAuthentication:
-+              intptr = &options->second_zero_knowledge_password_authentication;
-+              goto parse_flag;
-+
-+      case sSecondHostbasedAuthentication:
-+              intptr = &options->second_hostbased_authentication;
-+              goto parse_flag;
-+
-       case sPrintMotd:
-               intptr = &options->print_motd;
-               goto parse_flag;
-@@ -1491,14 +1558,21 @@ void
- copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
- {
-       M_CP_INTOPT(password_authentication);
-+      M_CP_INTOPT(second_password_authentication);
-       M_CP_INTOPT(gss_authentication);
-+      M_CP_INTOPT(second_gss_authentication);
-       M_CP_INTOPT(rsa_authentication);
-       M_CP_INTOPT(pubkey_authentication);
-+      M_CP_INTOPT(second_pubkey_authentication);
-       M_CP_INTOPT(kerberos_authentication);
-       M_CP_INTOPT(hostbased_authentication);
-+      M_CP_INTOPT(second_hostbased_authentication);
-       M_CP_INTOPT(hostbased_uses_name_from_packet_only);
-       M_CP_INTOPT(kbd_interactive_authentication);
-+      M_CP_INTOPT(second_kbd_interactive_authentication);
-       M_CP_INTOPT(zero_knowledge_password_authentication);
-+      M_CP_INTOPT(second_zero_knowledge_password_authentication);
-+      M_CP_INTOPT(two_factor_authentication);
-       M_CP_INTOPT(permit_root_login);
-       M_CP_INTOPT(permit_empty_passwd);
-@@ -1720,17 +1794,24 @@ dump_config(ServerOptions *o)
- #endif
- #ifdef GSSAPI
-       dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
-+      dump_cfg_fmtint(sSecondGssAuthentication, o->second_gss_authentication);
-       dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
- #endif
- #ifdef JPAKE
-       dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
-           o->zero_knowledge_password_authentication);
-+      dump_cfg_fmtint(sSecondZeroKnowledgePasswordAuthentication,
-+          o->second_zero_knowledge_password_authentication);
- #endif
-       dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
-+      dump_cfg_fmtint(sSecondPasswordAuthentication, o->second_password_authentication);
-       dump_cfg_fmtint(sKbdInteractiveAuthentication,
-           o->kbd_interactive_authentication);
-+      dump_cfg_fmtint(sSecondKbdInteractiveAuthentication,
-+          o->second_kbd_interactive_authentication);
-       dump_cfg_fmtint(sChallengeResponseAuthentication,
-           o->challenge_response_authentication);
-+      dump_cfg_fmtint(sTwoFactorAuthentication, o->two_factor_authentication);
-       dump_cfg_fmtint(sPrintMotd, o->print_motd);
-       dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
-       dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
-diff -up openssh-5.9p1/servconf.h.2auth openssh-5.9p1/servconf.h
---- openssh-5.9p1/servconf.h.2auth     2011-06-23 00:30:03.000000000 +0200
-+++ openssh-5.9p1/servconf.h   2011-09-17 11:36:54.749584245 +0200
-@@ -112,6 +112,14 @@ typedef struct {
-                                       /* If true, permit jpake auth */
-       int     permit_empty_passwd;    /* If false, do not permit empty
-                                        * passwords. */
-+      int     two_factor_authentication;      /* If true, the first sucessful authentication
-+                                       * will be followed by the second one from anorher set */
-+      int     second_pubkey_authentication;   /* second set of authentications */
-+      int     second_gss_authentication;
-+      int     second_password_authentication;
-+      int     second_kbd_interactive_authentication;
-+      int     second_zero_knowledge_password_authentication;
-+      int     second_hostbased_authentication;
-       int     permit_user_env;        /* If true, read ~/.ssh/environment */
-       int     use_login;      /* If true, login(1) is used */
-       int     compression;    /* If true, compression is allowed */
-diff -up openssh-5.9p1/sshd_config.2auth openssh-5.9p1/sshd_config
---- openssh-5.9p1/sshd_config.2auth    2011-05-29 13:39:39.000000000 +0200
-+++ openssh-5.9p1/sshd_config  2011-09-17 11:36:54.859588726 +0200
-@@ -87,6 +87,13 @@ AuthorizedKeysFile  .ssh/authorized_keys
- # and ChallengeResponseAuthentication to 'no'.
- #UsePAM no
-+#TwoFactorAuthentication no
-+#SecondPubkeyAuthentication yes
-+#SecondHostbasedAuthentication no
-+#SecondPasswordAuthentication yes
-+#SecondKBDInteractiveAuthentication yes
-+#SecondGSSAPIAuthentication no
-+
- #AllowAgentForwarding yes
- #AllowTcpForwarding yes
- #GatewayPorts no
-diff -up openssh-5.9p1/sshd_config.5.2auth openssh-5.9p1/sshd_config.5
---- openssh-5.9p1/sshd_config.5.2auth  2011-08-05 22:17:33.000000000 +0200
-+++ openssh-5.9p1/sshd_config.5        2011-09-17 13:45:49.022521436 +0200
-@@ -726,6 +726,12 @@ Available keywords are
- .Cm PubkeyAuthentication ,
- .Cm RhostsRSAAuthentication ,
- .Cm RSAAuthentication ,
-+.Cm SecondGSSAPIAuthentication ,
-+.Cm SecondHostbasedAuthentication ,
-+.Cm SecondKbdInteractiveAuthentication ,
-+.Cm SecondPasswordAuthentication ,
-+.Cm SecondPubkeyAuthentication ,
-+.Cm TwoFactorAuthentication ,
- .Cm X11DisplayOffset ,
- .Cm X11Forwarding
- and
-@@ -931,6 +937,45 @@ Specifies whether pure RSA authenticatio
- The default is
- .Dq yes .
- This option applies to protocol version 1 only.
-+.It Cm SecondGSSAPIAuthentication
-+Specifies whether the
-+.Cm GSSAPIAuthentication
-+may be used on the second authentication while
-+.Cm TwoFactorAuthentication
-+is set.
-+The default is
-+.Dq no .
-+.It Cm SecondHostbasedAuthentication
-+Specifies whether the
-+.Cm HostbasedAuthentication
-+may be used on the second authentication while
-+.Cm TwoFactorAuthentication
-+is set.
-+The default is
-+.Dq no .
-+.It Cm SecondKbdInteractiveAuthentication
-+Specifies whether the
-+.Cm KbdInteractiveAuthentication
-+may be used on the second authentication while
-+.Cm TwoFactorAuthentication
-+is set.
-+The default is
-+.Dq yes .
-+.It Cm SecondPasswordAuthentication
-+Specifies whether the
-+.Cm PasswordAuthentication
-+may be used on the second authentication while
-+.Cm TwoFactorAuthentication
-+is set.
-+The default is
-+.Dq yes .
-+Specifies whether the
-+.Cm PubkeyAuthentication
-+may be used on the second authentication while
-+.Cm TwoFactorAuthentication
-+is set.
-+The default is
-+.Dq yes .
- .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.
-@@ -1011,6 +1056,23 @@ For more details on certificates, see th
- .Sx CERTIFICATES
- section in
- .Xr ssh-keygen 1 .
-+.It Cm TwoFactorAuthentication
-+Specifies whether for a successful login is necessary to meet two independent authentications.
-+If select the first method is selected from the set of allowed methods from
-+.Cm GSSAPIAuthentication ,
-+.Cm HostbasedAuthentication ,
-+.Cm KbdInteractiveAuthentication ,
-+.Cm PasswordAuthentication ,
-+.Cm PubkeyAuthentication .
-+And the second method is selected from the set of allowed methods from
-+.Cm SecondGSSAPIAuthentication ,
-+.Cm SecondHostbasedAuthentication ,
-+.Cm SecondKbdInteractiveAuthentication ,
-+.Cm SecondPasswordAuthentication ,
-+.Cm SecondPubkeyAuthentication 
-+without the method used for the first authentication.
-+The default is
-+.Dq no .
- .It Cm UseDNS
- Specifies whether
- .Xr sshd 8
diff --git a/openssh/patches/openssh-5.9p1-mls.patch b/openssh/patches/openssh-5.9p1-mls.patch
deleted file mode 100644 (file)
index 1163949..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-diff -up openssh-5.9p0/misc.c.mls openssh-5.9p0/misc.c
---- openssh-5.9p0/misc.c.mls   2011-05-05 06:14:34.000000000 +0200
-+++ openssh-5.9p0/misc.c       2011-08-30 12:29:29.157087474 +0200
-@@ -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-5.9p0/openbsd-compat/port-linux.c.mls openssh-5.9p0/openbsd-compat/port-linux.c
---- openssh-5.9p0/openbsd-compat/port-linux.c.mls      2011-08-30 12:29:28.873086987 +0200
-+++ openssh-5.9p0/openbsd-compat/port-linux.c  2011-08-30 13:28:12.584149668 +0200
-@@ -40,7 +40,15 @@
- #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:"
-@@ -51,6 +59,149 @@ 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)
-+{
-+      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;
-+              }
-+
-+              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;
-+}
-+
- static void
- ssh_selinux_get_role_level(char **role, const char **level)
- {
-@@ -69,14 +220,15 @@ ssh_selinux_get_role_level(char **role,
- }
- /* Return the default security context for the given username */
--static security_context_t
--ssh_selinux_getctxbyname(char *pwname)
-+static int
-+ssh_selinux_getctxbyname(char *pwname,
-+      security_context_t *default_sc, security_context_t *user_sc)
- {
--      security_context_t sc = NULL;
-       char *sename, *lvl;
-       char *role;
-       const char *reqlvl;
-       int r = 0;
-+      context_t con = NULL;
-  
-       ssh_selinux_get_role_level(&role, &reqlvl);
-@@ -87,37 +239,62 @@ ssh_selinux_getctxbyname(char *pwname)
-       }
- #else
-       sename = pwname;
--      lvl = NULL;
-+      lvl = "";
- #endif
-       if (r == 0) {
- #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
--              if (role != NULL && role[0])
--                      r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc);
--              else
--                      r = get_default_context_with_level(sename, lvl, NULL, &sc);
-+              r = get_default_context_with_level(sename, lvl, NULL, default_sc);
- #else
--              if (role != NULL && role[0])
--                      r = get_default_context_with_role(sename, role, NULL, &sc);
--              else
--                      r = get_default_context(sename, NULL, &sc);
-+              r = get_default_context(sename, NULL, default_sc);
- #endif
-       }
--      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);
--                      break;
--              default:
--                      fatal("%s: Failed to get default SELinux security "
--                          "context for %s (in enforcing mode)",
--                          __func__, pwname);
-+      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 ((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
-@@ -126,8 +303,12 @@ ssh_selinux_getctxbyname(char *pwname)
-       if (lvl != NULL)
-               xfree(lvl);
- #endif
--
--      return (sc);
-+      if (role != NULL)
-+              xfree(role);
-+      if (con)
-+              context_free(con);
-+ 
-+      return (r);
- }
- /* Setup environment variables for pam_selinux */
-@@ -165,6 +346,8 @@ 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;
-@@ -189,22 +372,45 @@ ssh_selinux_setup_exec_context(char *pwn
-       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__);
- }
-@@ -222,7 +428,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? */
-diff -up openssh-5.9p0/sshd.c.mls openssh-5.9p0/sshd.c
---- openssh-5.9p0/sshd.c.mls   2011-08-30 12:29:22.663149706 +0200
-+++ openssh-5.9p0/sshd.c       2011-08-30 12:29:29.524024777 +0200
-@@ -2082,6 +2082,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);
similarity index 67%
rename from openssh/patches/openssh-5.9p1-entropy.patch
rename to openssh/patches/openssh-6.0p1-entropy.patch
index b3dec46a69e5c761b2b4126ce24e26ff1e07be24..79f05f4aa1ec060b7144319f65bfb7578f712ad1 100644 (file)
@@ -1,7 +1,7 @@
-diff -up openssh-5.9p0/entropy.c.entropy openssh-5.9p0/entropy.c
---- openssh-5.9p0/entropy.c.entropy    2011-08-31 13:20:59.660150441 +0200
-+++ openssh-5.9p0/entropy.c    2011-08-31 13:21:05.072024970 +0200
-@@ -232,6 +232,9 @@ seed_rng(void)
+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 */
@@ -11,21 +11,21 @@ diff -up openssh-5.9p0/entropy.c.entropy openssh-5.9p0/entropy.c
        if (RAND_status() != 1)
                fatal("PRNG is not seeded");
  }
-diff -up openssh-5.9p0/openbsd-compat/Makefile.in.entropy openssh-5.9p0/openbsd-compat/Makefile.in
---- openssh-5.9p0/openbsd-compat/Makefile.in.entropy   2011-08-31 13:20:54.000000000 +0200
-+++ openssh-5.9p0/openbsd-compat/Makefile.in   2011-08-31 13:44:25.138151565 +0200
+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 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
+ 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-5.9p0/openbsd-compat/port-linux-prng.c.entropy openssh-5.9p0/openbsd-compat/port-linux-prng.c
---- openssh-5.9p0/openbsd-compat/port-linux-prng.c.entropy     2011-08-31 13:21:05.382024083 +0200
-+++ openssh-5.9p0/openbsd-compat/port-linux-prng.c     2011-08-31 13:21:05.386024776 +0200
+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 $ */
 +
@@ -86,13 +86,15 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux-prng.c.entropy openssh-5.9p0/op
 +                      fatal ("EOF reading %s", random);
 +      }
 +}
-diff -up openssh-5.9p0/ssh-add.1.entropy openssh-5.9p0/ssh-add.1
---- openssh-5.9p0/ssh-add.1.entropy    2010-11-05 00:20:14.000000000 +0100
-+++ openssh-5.9p0/ssh-add.1    2011-08-31 13:21:05.597122030 +0200
-@@ -158,6 +158,20 @@ Identifies the path of a
- .Ux Ns -domain
- socket used to communicate with the agent.
- .El
+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 .
@@ -107,20 +109,38 @@ diff -up openssh-5.9p0/ssh-add.1.entropy openssh-5.9p0/ssh-add.1
 +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-5.9p0/ssh-agent.1.entropy openssh-5.9p0/ssh-agent.1
---- openssh-5.9p0/ssh-agent.1.entropy  2010-12-01 01:50:35.000000000 +0100
-+++ openssh-5.9p0/ssh-agent.1  2011-08-31 13:21:05.735150196 +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
+ .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 
@@ -134,16 +154,16 @@ diff -up openssh-5.9p0/ssh-agent.1.entropy openssh-5.9p0/ssh-agent.1
 +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-5.9p0/ssh-keygen.1.entropy openssh-5.9p0/ssh-keygen.1
---- openssh-5.9p0/ssh-keygen.1.entropy 2011-08-31 13:20:59.200212619 +0200
-+++ openssh-5.9p0/ssh-keygen.1 2011-08-31 13:21:06.077150115 +0200
-@@ -669,6 +669,24 @@ Contains Diffie-Hellman groups used for
- The file format is described in
.Xr moduli 5 .
+ .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
@@ -166,12 +186,12 @@ diff -up openssh-5.9p0/ssh-keygen.1.entropy openssh-5.9p0/ssh-keygen.1
  .Sh SEE ALSO
  .Xr ssh 1 ,
  .Xr ssh-add 1 ,
-diff -up openssh-5.9p0/ssh-keysign.8.entropy openssh-5.9p0/ssh-keysign.8
---- openssh-5.9p0/ssh-keysign.8.entropy        2010-08-31 14:41:14.000000000 +0200
-+++ openssh-5.9p0/ssh-keysign.8        2011-08-31 13:21:06.207024356 +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.
+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
@@ -191,19 +211,20 @@ diff -up openssh-5.9p0/ssh-keysign.8.entropy openssh-5.9p0/ssh-keysign.8
 +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
- .Xr ssh 1 ,
- .Xr ssh-keygen 1 ,
-diff -up openssh-5.9p0/ssh.1.entropy openssh-5.9p0/ssh.1
---- openssh-5.9p0/ssh.1.entropy        2011-08-31 13:21:00.835103535 +0200
-+++ openssh-5.9p0/ssh.1        2011-08-31 13:21:05.482032754 +0200
-@@ -1255,6 +1255,23 @@ For more information, see the
- .Cm PermitUserEnvironment
- option in
- .Xr sshd_config 5 .
+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
-+.It Ev SSH_USE_STRONG_RNG
++.Pp
++.It Pa SSH_USE_STRONG_RNG
 +The reseeding of the OpenSSL random generator is usually done from
 +.Cm /dev/urandom .
 +If the 
@@ -218,15 +239,15 @@ diff -up openssh-5.9p0/ssh.1.entropy openssh-5.9p0/ssh.1
 +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-5.9p0/sshd.8.entropy openssh-5.9p0/sshd.8
---- openssh-5.9p0/sshd.8.entropy       2011-08-31 13:21:00.000000000 +0200
-+++ openssh-5.9p0/sshd.8       2011-08-31 13:46:27.341025537 +0200
-@@ -940,6 +940,24 @@ concurrently for different ports, this c
- started last).
The content of this file is not sensitive; it can be world-readable.
+ .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
@@ -246,6 +267,6 @@ diff -up openssh-5.9p0/sshd.8.entropy openssh-5.9p0/sshd.8
 +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
+ .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
new file mode 100644 (file)
index 0000000..0401ba0
--- /dev/null
@@ -0,0 +1,565 @@
+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
similarity index 53%
rename from openssh/patches/openssh-5.8p2-askpass-ld.patch
rename to openssh/patches/openssh-6.1p1-askpass-ld.patch
index 5b85c80b3b0c4ea485f587a64e388374ec0f85ad..f7a7facb3bcc1e1b8e46d60eb08c28161328a586 100644 (file)
@@ -1,7 +1,7 @@
-diff -up openssh-5.8p2/contrib/Makefile.askpass-ld openssh-5.8p2/contrib/Makefile
---- openssh-5.8p2/contrib/Makefile.askpass-ld  2011-08-08 22:54:06.050546199 +0200
-+++ openssh-5.8p2/contrib/Makefile     2011-08-08 22:54:43.364420118 +0200
-@@ -2,12 +2,12 @@ all:
+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
@@ -11,8 +11,8 @@ diff -up openssh-5.8p2/contrib/Makefile.askpass-ld openssh-5.8p2/contrib/Makefil
                `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` \
+-      $(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`
+               `$(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
new file mode 100644 (file)
index 0000000..7b5a06a
--- /dev/null
@@ -0,0 +1,841 @@
+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 ,
similarity index 73%
rename from openssh/patches/openssh-5.9p1-coverity.patch
rename to openssh/patches/openssh-6.1p1-coverity.patch
index f3524e3a0c7a13bba3e34b00da30e3ee0954cad4..0c8fb236c63e02e99aa62c9a537dd2c3f79e903e 100644 (file)
@@ -1,6 +1,6 @@
-diff -up openssh-5.9p1/auth-pam.c.coverity openssh-5.9p1/auth-pam.c
---- openssh-5.9p1/auth-pam.c.coverity  2009-07-12 14:07:21.000000000 +0200
-+++ openssh-5.9p1/auth-pam.c   2011-09-14 08:09:47.074520582 +0200
+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);
@@ -15,10 +15,31 @@ diff -up openssh-5.9p1/auth-pam.c.coverity openssh-5.9p1/auth-pam.c
        return (status);
  }
  #endif
-diff -up openssh-5.9p1/channels.c.coverity openssh-5.9p1/channels.c
---- openssh-5.9p1/channels.c.coverity  2011-06-23 00:31:57.000000000 +0200
-+++ openssh-5.9p1/channels.c   2011-09-14 08:09:47.556582810 +0200
-@@ -229,11 +229,11 @@ channel_register_fds(Channel *c, int rfd
+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);
  
@@ -33,7 +54,7 @@ diff -up openssh-5.9p1/channels.c.coverity openssh-5.9p1/channels.c
                fcntl(efd, F_SETFD, FD_CLOEXEC);
  
        c->rfd = rfd;
-@@ -248,11 +248,11 @@ channel_register_fds(Channel *c, int rfd
+@@ -251,11 +251,11 @@ channel_register_fds(Channel *c, int rfd
  
        /* enable nonblocking mode */
        if (nonblock) {
@@ -48,31 +69,10 @@ diff -up openssh-5.9p1/channels.c.coverity openssh-5.9p1/channels.c
                        set_nonblock(efd);
        }
  }
-diff -up openssh-5.9p1/clientloop.c.coverity openssh-5.9p1/clientloop.c
---- openssh-5.9p1/clientloop.c.coverity        2011-06-23 00:31:58.000000000 +0200
-+++ openssh-5.9p1/clientloop.c 2011-09-14 08:17:41.556521887 +0200
-@@ -1970,14 +1970,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-5.9p1/key.c.coverity openssh-5.9p1/key.c
---- openssh-5.9p1/key.c.coverity       2011-05-20 11:03:08.000000000 +0200
-+++ openssh-5.9p1/key.c        2011-09-14 08:09:47.803458435 +0200
-@@ -803,8 +803,10 @@ key_read(Key *ret, char **cpp)
+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);
@@ -83,10 +83,9 @@ diff -up openssh-5.9p1/key.c.coverity openssh-5.9p1/key.c
                /* advance cp: skip whitespace and data */
                while (*cp == ' ' || *cp == '\t')
                        cp++;
-diff -up openssh-5.9p1/misc.c.coverity openssh-5.9p1/misc.c
-diff -up openssh-5.9p1/monitor.c.coverity openssh-5.9p1/monitor.c
---- openssh-5.9p1/monitor.c.coverity   2011-08-05 22:15:18.000000000 +0200
-+++ openssh-5.9p1/monitor.c    2011-09-14 08:09:47.914584009 +0200
+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
        }
  
@@ -96,7 +95,7 @@ diff -up openssh-5.9p1/monitor.c.coverity openssh-5.9p1/monitor.c
                ;
  
        if (!authctxt->valid)
-@@ -1161,6 +1161,10 @@ mm_answer_keyallowed(int sock, Buffer *m
+@@ -1159,6 +1159,10 @@ mm_answer_keyallowed(int sock, Buffer *m
                        break;
                }
        }
@@ -107,7 +106,7 @@ diff -up openssh-5.9p1/monitor.c.coverity openssh-5.9p1/monitor.c
        if (key != NULL)
                key_free(key);
  
-@@ -1182,9 +1186,6 @@ mm_answer_keyallowed(int sock, Buffer *m
+@@ -1180,9 +1184,6 @@ mm_answer_keyallowed(int sock, Buffer *m
                xfree(chost);
        }
  
@@ -117,9 +116,9 @@ diff -up openssh-5.9p1/monitor.c.coverity openssh-5.9p1/monitor.c
        buffer_clear(m);
        buffer_put_int(m, allowed);
        buffer_put_int(m, forced_command != NULL);
-diff -up openssh-5.9p1/monitor_wrap.c.coverity openssh-5.9p1/monitor_wrap.c
---- openssh-5.9p1/monitor_wrap.c.coverity      2011-09-14 08:11:36.480500123 +0200
-+++ openssh-5.9p1/monitor_wrap.c       2011-09-14 08:14:11.279520598 +0200
+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) {
@@ -134,9 +133,9 @@ diff -up openssh-5.9p1/monitor_wrap.c.coverity openssh-5.9p1/monitor_wrap.c
                return 0;
        }
        close(tmp1);
-diff -up openssh-5.9p1/openbsd-compat/bindresvport.c.coverity openssh-5.9p1/openbsd-compat/bindresvport.c
---- openssh-5.9p1/openbsd-compat/bindresvport.c.coverity       2010-12-03 00:50:26.000000000 +0100
-+++ openssh-5.9p1/openbsd-compat/bindresvport.c        2011-09-14 08:09:48.084459344 +0200
+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;
@@ -146,9 +145,9 @@ diff -up openssh-5.9p1/openbsd-compat/bindresvport.c.coverity openssh-5.9p1/open
        int i;
  
        if (sa == NULL) {
-diff -up openssh-5.9p1/packet.c.coverity openssh-5.9p1/packet.c
---- openssh-5.9p1/packet.c.coverity    2011-05-15 00:58:15.000000000 +0200
-+++ openssh-5.9p1/packet.c     2011-09-14 08:09:48.184587842 +0200
+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: "
@@ -157,7 +156,7 @@ diff -up openssh-5.9p1/packet.c.coverity openssh-5.9p1/packet.c
                case DEATTACK_DOS_DETECTED:
                        packet_disconnect("deattack denial of "
                            "service detected");
-@@ -1684,7 +1685,7 @@ void
+@@ -1678,7 +1679,7 @@ void
  packet_write_wait(void)
  {
        fd_set *setp;
@@ -166,9 +165,9 @@ diff -up openssh-5.9p1/packet.c.coverity openssh-5.9p1/packet.c
        struct timeval start, timeout, *timeoutp = NULL;
  
        setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
-diff -up openssh-5.9p1/progressmeter.c.coverity openssh-5.9p1/progressmeter.c
---- openssh-5.9p1/progressmeter.c.coverity     2006-08-05 04:39:40.000000000 +0200
-+++ openssh-5.9p1/progressmeter.c      2011-09-14 08:09:48.300586004 +0200
+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 */
@@ -187,9 +186,9 @@ diff -up openssh-5.9p1/progressmeter.c.coverity openssh-5.9p1/progressmeter.c
  {
        start = last_update = time(NULL);
        file = f;
-diff -up openssh-5.9p1/progressmeter.h.coverity openssh-5.9p1/progressmeter.h
---- openssh-5.9p1/progressmeter.h.coverity     2006-03-26 05:30:02.000000000 +0200
-+++ openssh-5.9p1/progressmeter.h      2011-09-14 08:09:48.420645724 +0200
+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.
   */
@@ -197,9 +196,9 @@ diff -up openssh-5.9p1/progressmeter.h.coverity openssh-5.9p1/progressmeter.h
 -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-5.9p1/scp.c.coverity openssh-5.9p1/scp.c
---- openssh-5.9p1/scp.c.coverity       2011-01-06 12:41:21.000000000 +0100
-+++ openssh-5.9p1/scp.c        2011-09-14 08:09:48.531505457 +0200
+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) {
@@ -209,19 +208,10 @@ diff -up openssh-5.9p1/scp.c.coverity openssh-5.9p1/scp.c
        }
  
        if (signo)
-diff -up openssh-5.9p1/servconf.c.coverity openssh-5.9p1/servconf.c
---- openssh-5.9p1/servconf.c.coverity  2011-06-23 00:30:03.000000000 +0200
-+++ openssh-5.9p1/servconf.c   2011-09-14 08:30:17.557468182 +0200
-@@ -609,7 +609,7 @@ match_cfg_line(char **condition, int lin
-               debug3("checking syntax for 'Match %s'", cp);
-       else
-               debug3("checking match for '%s' user %s host %s addr %s", cp,
--                  user ? user : "(null)", host ? host : "(null)",
-+                  user /* User is not NULL ? user : "(null)" */, host ? host : "(null)",
-                   address ? address : "(null)");
-       while ((attrib = strdelim(&cp)) && *attrib != '\0') {
-@@ -1171,7 +1171,7 @@ process_server_config_line(ServerOptions
+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) {
@@ -230,7 +220,7 @@ diff -up openssh-5.9p1/servconf.c.coverity openssh-5.9p1/servconf.c
                        break;
                }
                for (i = 0; i < options->num_subsystems; i++)
-@@ -1262,8 +1262,9 @@ process_server_config_line(ServerOptions
+@@ -1340,8 +1340,9 @@ process_server_config_line(ServerOptions
                if (*activep && *charptr == NULL) {
                        *charptr = tilde_expand_filename(arg, getuid());
                        /* increase optional counter */
@@ -242,9 +232,9 @@ diff -up openssh-5.9p1/servconf.c.coverity openssh-5.9p1/servconf.c
                }
                break;
  
-diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
---- openssh-5.9p1/serverloop.c.coverity        2011-05-20 11:02:50.000000000 +0200
-+++ openssh-5.9p1/serverloop.c 2011-09-14 08:09:48.793586380 +0200
+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)
@@ -272,7 +262,7 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                        debug2("notify_done: reading");
  }
  
-@@ -330,7 +330,7 @@ wait_until_can_do_something(fd_set **rea
+@@ -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.
                 */
@@ -281,7 +271,7 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                        FD_SET(fdin, *writesetp);
        }
        notify_prepare(*readsetp);
-@@ -470,7 +470,7 @@ process_output(fd_set *writeset)
+@@ -476,7 +476,7 @@ process_output(fd_set *writeset)
        int len;
  
        /* Write buffered data to program stdin. */
@@ -290,7 +280,7 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                data = buffer_ptr(&stdin_buffer);
                dlen = buffer_len(&stdin_buffer);
                len = write(fdin, data, dlen);
-@@ -583,7 +583,7 @@ server_loop(pid_t pid, int fdin_arg, int
+@@ -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 */
@@ -299,7 +289,7 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                set_nonblock(fderr);
  
        if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
-@@ -607,7 +607,7 @@ server_loop(pid_t pid, int fdin_arg, int
+@@ -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);
@@ -308,7 +298,7 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                max_fd = MAX(max_fd, fderr);
  #endif
  
-@@ -637,7 +637,7 @@ server_loop(pid_t pid, int fdin_arg, int
+@@ -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.
                 */
@@ -317,7 +307,7 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                        if (fdin != fdout)
                                close(fdin);
                        else
-@@ -735,15 +735,15 @@ server_loop(pid_t pid, int fdin_arg, int
+@@ -741,15 +741,15 @@ server_loop(pid_t pid, int fdin_arg, int
        buffer_free(&stderr_buffer);
  
        /* Close the file descriptors. */
@@ -336,7 +326,7 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                close(fdin);
        fdin = -1;
  
-@@ -937,7 +937,7 @@ server_input_window_size(int type, u_int
+@@ -943,7 +943,7 @@ server_input_window_size(int type, u_int
  
        debug("Window change received.");
        packet_check_eom();
@@ -345,7 +335,7 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                pty_change_window_size(fdin, row, col, xpixel, ypixel);
  }
  
-@@ -990,7 +990,7 @@ server_request_tun(void)
+@@ -996,7 +996,7 @@ server_request_tun(void)
        }
  
        tun = packet_get_int();
@@ -354,9 +344,111 @@ diff -up openssh-5.9p1/serverloop.c.coverity openssh-5.9p1/serverloop.c
                if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
                        goto done;
                tun = forced_tun_device;
-diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
---- openssh-5.9p1/sftp-client.c.coverity       2010-12-04 23:02:48.000000000 +0100
-+++ openssh-5.9p1/sftp-client.c        2011-09-14 08:09:48.910470343 +0200
+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 *
  }
  
@@ -393,7 +485,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
      SFTP_DIRENT ***dir)
  {
        Buffer msg;
-@@ -571,7 +571,7 @@ do_lsreaddir(struct sftp_conn *conn, cha
+@@ -572,7 +572,7 @@ do_lsreaddir(struct sftp_conn *conn, cha
  }
  
  int
@@ -402,7 +494,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        return(do_lsreaddir(conn, path, 0, dir));
  }
-@@ -589,7 +589,7 @@ void free_sftp_dirents(SFTP_DIRENT **s)
+@@ -590,7 +590,7 @@ void free_sftp_dirents(SFTP_DIRENT **s)
  }
  
  int
@@ -411,7 +503,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        u_int status, id;
  
-@@ -604,7 +604,7 @@ do_rm(struct sftp_conn *conn, char *path
+@@ -605,7 +605,7 @@ do_rm(struct sftp_conn *conn, char *path
  }
  
  int
@@ -420,7 +512,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        u_int status, id;
  
-@@ -620,7 +620,7 @@ do_mkdir(struct sftp_conn *conn, char *p
+@@ -621,7 +621,7 @@ do_mkdir(struct sftp_conn *conn, char *p
  }
  
  int
@@ -429,7 +521,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        u_int status, id;
  
-@@ -636,7 +636,7 @@ do_rmdir(struct sftp_conn *conn, char *p
+@@ -637,7 +637,7 @@ do_rmdir(struct sftp_conn *conn, char *p
  }
  
  Attrib *
@@ -438,7 +530,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        u_int id;
  
-@@ -650,7 +650,7 @@ do_stat(struct sftp_conn *conn, char *pa
+@@ -651,7 +651,7 @@ do_stat(struct sftp_conn *conn, char *pa
  }
  
  Attrib *
@@ -447,7 +539,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        u_int id;
  
-@@ -684,7 +684,7 @@ do_fstat(struct sftp_conn *conn, char *h
+@@ -685,7 +685,7 @@ do_fstat(struct sftp_conn *conn, char *h
  #endif
  
  int
@@ -456,7 +548,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        u_int status, id;
  
-@@ -701,7 +701,7 @@ do_setstat(struct sftp_conn *conn, char
+@@ -702,7 +702,7 @@ do_setstat(struct sftp_conn *conn, char
  }
  
  int
@@ -465,7 +557,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
      Attrib *a)
  {
        u_int status, id;
-@@ -718,12 +718,12 @@ do_fsetstat(struct sftp_conn *conn, char
+@@ -719,7 +719,7 @@ do_fsetstat(struct sftp_conn *conn, char
  }
  
  char *
@@ -474,22 +566,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        Buffer msg;
        u_int type, expected_id, count, id;
-       char *filename, *longname;
--      Attrib *a;
-+/*UNUSED Attrib *a; */
-       expected_id = id = conn->msg_id++;
-       send_string_request(conn, id, SSH2_FXP_REALPATH, path,
-@@ -754,7 +754,7 @@ do_realpath(struct sftp_conn *conn, char
-       filename = buffer_get_string(&msg, NULL);
-       longname = buffer_get_string(&msg, NULL);
--      a = decode_attrib(&msg);
-+      /*a =*/ (void) decode_attrib(&msg);
-       debug3("SSH_FXP_REALPATH %s -> %s", path, filename);
-@@ -766,7 +766,7 @@ do_realpath(struct sftp_conn *conn, char
+@@ -768,7 +768,7 @@ do_realpath(struct sftp_conn *conn, char
  }
  
  int
@@ -498,7 +575,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        Buffer msg;
        u_int status, id;
-@@ -800,7 +800,7 @@ do_rename(struct sftp_conn *conn, char *
+@@ -802,7 +802,7 @@ do_rename(struct sftp_conn *conn, char *
  }
  
  int
@@ -507,7 +584,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        Buffer msg;
        u_int status, id;
-@@ -833,7 +833,7 @@ do_hardlink(struct sftp_conn *conn, char
+@@ -835,7 +835,7 @@ do_hardlink(struct sftp_conn *conn, char
  }
  
  int
@@ -516,7 +593,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        Buffer msg;
        u_int status, id;
-@@ -984,7 +984,7 @@ send_read_request(struct sftp_conn *conn
+@@ -987,7 +987,7 @@ send_read_request(struct sftp_conn *conn
  }
  
  int
@@ -525,7 +602,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
      Attrib *a, int pflag)
  {
        Attrib junk;
-@@ -1223,7 +1223,7 @@ do_download(struct sftp_conn *conn, char
+@@ -1226,7 +1226,7 @@ do_download(struct sftp_conn *conn, char
  }
  
  static int
@@ -534,7 +611,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
      Attrib *dirattrib, int pflag, int printflag, int depth)
  {
        int i, ret = 0;
-@@ -1313,7 +1313,7 @@ download_dir_internal(struct sftp_conn *
+@@ -1316,7 +1316,7 @@ download_dir_internal(struct sftp_conn *
  }
  
  int
@@ -543,7 +620,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
      Attrib *dirattrib, int pflag, int printflag)
  {
        char *src_canon;
-@@ -1331,7 +1331,7 @@ download_dir(struct sftp_conn *conn, cha
+@@ -1334,7 +1334,7 @@ download_dir(struct sftp_conn *conn, cha
  }
  
  int
@@ -552,7 +629,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
      int pflag)
  {
        int local_fd;
-@@ -1514,7 +1514,7 @@ do_upload(struct sftp_conn *conn, char *
+@@ -1517,7 +1517,7 @@ do_upload(struct sftp_conn *conn, char *
  }
  
  static int
@@ -561,7 +638,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
      int pflag, int printflag, int depth)
  {
        int ret = 0, status;
-@@ -1605,7 +1605,7 @@ upload_dir_internal(struct sftp_conn *co
+@@ -1608,7 +1608,7 @@ upload_dir_internal(struct sftp_conn *co
  }
  
  int
@@ -570,7 +647,7 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
      int pflag)
  {
        char *dst_canon;
-@@ -1622,7 +1622,7 @@ upload_dir(struct sftp_conn *conn, char
+@@ -1625,7 +1625,7 @@ upload_dir(struct sftp_conn *conn, char
  }
  
  char *
@@ -579,9 +656,9 @@ diff -up openssh-5.9p1/sftp-client.c.coverity openssh-5.9p1/sftp-client.c
  {
        char *ret;
        size_t len = strlen(p1) + strlen(p2) + 2;
-diff -up openssh-5.9p1/sftp-client.h.coverity openssh-5.9p1/sftp-client.h
---- openssh-5.9p1/sftp-client.h.coverity       2010-12-04 23:02:48.000000000 +0100
-+++ openssh-5.9p1/sftp-client.h        2011-09-14 08:09:49.021583940 +0200
+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 *);
  
@@ -679,124 +756,9 @@ diff -up openssh-5.9p1/sftp-client.h.coverity openssh-5.9p1/sftp-client.h
 +char *path_append(const char *, const char *);
  
  #endif
-diff -up openssh-5.9p1/sftp.c.coverity openssh-5.9p1/sftp.c
---- openssh-5.9p1/sftp.c.coverity      2010-12-04 23:02:48.000000000 +0100
-+++ openssh-5.9p1/sftp.c       2011-09-14 08:09:49.468493585 +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,10 +780,10 @@ 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)
- {
--      Attrib *a = NULL;
-+/*UNUSED Attrib *a = NULL;*/
-       char *fname, *lname;
-       glob_t g;
-       int err;
-@@ -828,7 +828,7 @@ do_globbed_ls(struct sftp_conn *conn, ch
-               colspace = width / columns;
-       }
--      for (i = 0; g.gl_pathv[i] && !interrupted; i++, a = NULL) {
-+      for (i = 0; g.gl_pathv[i] && !interrupted; i++/*, a = NULL*/) {
-               fname = path_strip(g.gl_pathv[i], strip_path);
-               if (lflag & LS_LONG_VIEW) {
-                       if (g.gl_statv[i] == NULL) {
-@@ -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-5.9p1/ssh-agent.c.coverity openssh-5.9p1/ssh-agent.c
---- openssh-5.9p1/ssh-agent.c.coverity 2011-06-03 06:14:16.000000000 +0200
-+++ openssh-5.9p1/ssh-agent.c  2011-09-14 08:09:49.572460295 +0200
+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();
  
@@ -808,10 +770,10 @@ diff -up openssh-5.9p1/ssh-agent.c.coverity openssh-5.9p1/ssh-agent.c
  
  #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
        /* Disable ptrace on Linux without sgid bit */
-diff -up openssh-5.9p1/sshd.c.coverity openssh-5.9p1/sshd.c
---- openssh-5.9p1/sshd.c.coverity      2011-06-23 11:45:51.000000000 +0200
-+++ openssh-5.9p1/sshd.c       2011-09-14 08:09:49.687509968 +0200
-@@ -676,8 +676,10 @@ privsep_preauth(Authctxt *authctxt)
+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]");
@@ -823,7 +785,7 @@ diff -up openssh-5.9p1/sshd.c.coverity openssh-5.9p1/sshd.c
  
                return 0;
        }
-@@ -1302,6 +1304,9 @@ server_accept_loop(int *sock_in, int *so
+@@ -1311,6 +1313,9 @@ server_accept_loop(int *sock_in, int *so
                if (num_listen_socks < 0)
                        break;
        }
@@ -833,7 +795,7 @@ diff -up openssh-5.9p1/sshd.c.coverity openssh-5.9p1/sshd.c
  }
  
  
-@@ -1774,7 +1779,7 @@ main(int ac, char **av)
+@@ -1768,7 +1773,7 @@ main(int ac, char **av)
  
        /* Chdir to the root directory so that the current disk can be
           unmounted if desired. */
similarity index 67%
rename from openssh/patches/openssh-5.9p1-kuserok.patch
rename to openssh/patches/openssh-6.1p1-kuserok.patch
index 11f38a51c9e78ffa0a10cec903fe7bedb890d642..7b695e0b328608810ca9221e78db0a34d26d791d 100644 (file)
@@ -1,7 +1,7 @@
-diff -up openssh-5.9p0/auth-krb5.c.kuserok openssh-5.9p0/auth-krb5.c
---- openssh-5.9p0/auth-krb5.c.kuserok  2011-08-30 16:37:32.651150128 +0200
-+++ openssh-5.9p0/auth-krb5.c  2011-08-30 16:37:37.549087368 +0200
-@@ -54,6 +54,20 @@
+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;
  
@@ -22,7 +22,7 @@ diff -up openssh-5.9p0/auth-krb5.c.kuserok openssh-5.9p0/auth-krb5.c
  static int
  krb5_init(void *context)
  {
-@@ -146,7 +160,7 @@ auth_krb5_password(Authctxt *authctxt, c
+@@ -147,7 +161,7 @@ auth_krb5_password(Authctxt *authctxt, c
        if (problem)
                goto out;
  
@@ -31,9 +31,9 @@ diff -up openssh-5.9p0/auth-krb5.c.kuserok openssh-5.9p0/auth-krb5.c
                problem = -1;
                goto out;
        }
-diff -up openssh-5.9p0/gss-serv-krb5.c.kuserok openssh-5.9p0/gss-serv-krb5.c
---- openssh-5.9p0/gss-serv-krb5.c.kuserok      2011-08-30 16:37:36.988024804 +0200
-+++ openssh-5.9p0/gss-serv-krb5.c      2011-08-30 16:37:37.659088030 +0200
+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);
  
@@ -51,27 +51,27 @@ diff -up openssh-5.9p0/gss-serv-krb5.c.kuserok openssh-5.9p0/gss-serv-krb5.c
                retval = 1;
                logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
                    luser, (char *)client->displayname.value);
-diff -up openssh-5.9p0/servconf.c.kuserok openssh-5.9p0/servconf.c
---- openssh-5.9p0/servconf.c.kuserok   2011-08-30 16:37:35.093073603 +0200
-+++ openssh-5.9p0/servconf.c   2011-08-30 16:41:13.568087145 +0200
-@@ -144,6 +144,7 @@ initialize_server_options(ServerOptions
-       options->authorized_principals_file = NULL;
+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
-@@ -291,6 +292,8 @@ fill_default_server_options(ServerOption
-               options->ip_qos_bulk = IPTOS_THROUGHPUT;
+@@ -301,6 +302,8 @@ fill_default_server_options(ServerOption
+               options->version_addendum = xstrdup("");
        if (options->show_patchlevel == -1)
-               options->show_patchlevel = 0;
+               options->show_patchlevel = 0;
 +      if (options->use_kuserok == -1)
 +              options->use_kuserok = 1;
  
        /* Turn privilege separation on by default */
        if (use_privsep == -1)
-@@ -317,7 +320,7 @@ typedef enum {
+@@ -327,7 +330,7 @@ typedef enum {
        sPermitRootLogin, sLogFacility, sLogLevel,
        sRhostsRSAAuthentication, sRSAAuthentication,
        sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
@@ -80,7 +80,7 @@ diff -up openssh-5.9p0/servconf.c.kuserok openssh-5.9p0/servconf.c
        sKerberosTgtPassing, sChallengeResponseAuthentication,
        sPasswordAuthentication, sKbdInteractiveAuthentication,
        sListenAddress, sAddressFamily,
-@@ -388,11 +391,13 @@ static struct {
+@@ -399,11 +402,13 @@ static struct {
  #else
        { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
  #endif
@@ -94,7 +94,7 @@ diff -up openssh-5.9p0/servconf.c.kuserok openssh-5.9p0/servconf.c
  #endif
        { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
        { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
-@@ -1371,6 +1376,10 @@ process_server_config_line(ServerOptions
+@@ -1486,6 +1491,10 @@ process_server_config_line(ServerOptions
                *activep = value;
                break;
  
@@ -105,7 +105,7 @@ diff -up openssh-5.9p0/servconf.c.kuserok openssh-5.9p0/servconf.c
        case sPermitOpen:
                arg = strdelim(&cp);
                if (!arg || *arg == '\0')
-@@ -1580,6 +1589,7 @@ copy_set_server_options(ServerOptions *d
+@@ -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);
@@ -113,7 +113,7 @@ diff -up openssh-5.9p0/servconf.c.kuserok openssh-5.9p0/servconf.c
  
        /* See comment in servconf.h */
        COPY_MATCH_STRING_OPTS();
-@@ -1816,6 +1826,7 @@ dump_config(ServerOptions *o)
+@@ -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);
@@ -121,10 +121,10 @@ diff -up openssh-5.9p0/servconf.c.kuserok openssh-5.9p0/servconf.c
  
        /* string arguments */
        dump_cfg_string(sPidFile, o->pid_file);
-diff -up openssh-5.9p0/servconf.h.kuserok openssh-5.9p0/servconf.h
---- openssh-5.9p0/servconf.h.kuserok   2011-08-30 16:37:35.201051957 +0200
-+++ openssh-5.9p0/servconf.h   2011-08-30 16:37:37.926087431 +0200
-@@ -166,6 +166,7 @@ typedef struct {
+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;
  
@@ -132,10 +132,21 @@ diff -up openssh-5.9p0/servconf.h.kuserok openssh-5.9p0/servconf.h
        char   *chroot_directory;
        char   *revoked_keys_file;
        char   *trusted_user_ca_keys;
-diff -up openssh-5.9p0/sshd_config.5.kuserok openssh-5.9p0/sshd_config.5
---- openssh-5.9p0/sshd_config.5.kuserok        2011-08-30 16:37:35.979024607 +0200
-+++ openssh-5.9p0/sshd_config.5        2011-08-30 16:37:38.040087843 +0200
-@@ -603,6 +603,10 @@ Specifies whether to automatically destr
+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 .
@@ -146,7 +157,7 @@ diff -up openssh-5.9p0/sshd_config.5.kuserok openssh-5.9p0/sshd_config.5
  .It Cm KexAlgorithms
  Specifies the available KEX (Key Exchange) algorithms.
  Multiple algorithms must be comma-separated.
-@@ -746,6 +750,7 @@ Available keywords are
+@@ -767,6 +771,7 @@ Available keywords are
  .Cm HostbasedUsesNameFromPacketOnly ,
  .Cm KbdInteractiveAuthentication ,
  .Cm KerberosAuthentication ,
@@ -154,14 +165,3 @@ diff -up openssh-5.9p0/sshd_config.5.kuserok openssh-5.9p0/sshd_config.5
  .Cm MaxAuthTries ,
  .Cm MaxSessions ,
  .Cm PubkeyAuthentication ,
-diff -up openssh-5.9p0/sshd_config.kuserok openssh-5.9p0/sshd_config
---- openssh-5.9p0/sshd_config.kuserok  2011-08-30 16:37:36.808026328 +0200
-+++ openssh-5.9p0/sshd_config  2011-08-30 16:37:38.148071520 +0200
-@@ -77,6 +77,7 @@ ChallengeResponseAuthentication no
- #KerberosOrLocalPasswd yes
- #KerberosTicketCleanup yes
- #KerberosGetAFSToken no
-+#KerberosUseKuserok yes
- # GSSAPI options
- #GSSAPIAuthentication no
diff --git a/openssh/patches/openssh-6.1p1-required-authentications.patch b/openssh/patches/openssh-6.1p1-required-authentications.patch
new file mode 100644 (file)
index 0000000..bfc28ee
--- /dev/null
@@ -0,0 +1,22 @@
+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 >=
similarity index 50%
rename from openssh/patches/openssh-5.9p1-role.patch
rename to openssh/patches/openssh-6.1p1-role-mls.patch
index 8a26bdfc561110c23029ed989de911c09c2aa3a7..4de3dae94c3a2f2c71cade5fde887cb23a15ebab 100644 (file)
@@ -1,43 +1,6 @@
-diff -up openssh-5.9p0/auth-pam.c.role openssh-5.9p0/auth-pam.c
---- openssh-5.9p0/auth-pam.c.role      2009-07-12 14:07:21.000000000 +0200
-+++ openssh-5.9p0/auth-pam.c   2011-08-31 11:42:54.870087433 +0200
-@@ -1069,7 +1069,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-5.9p0/auth-pam.h.role openssh-5.9p0/auth-pam.h
---- openssh-5.9p0/auth-pam.h.role      2004-09-11 14:17:26.000000000 +0200
-+++ openssh-5.9p0/auth-pam.h   2011-08-31 11:42:54.979086333 +0200
-@@ -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-5.9p0/auth.h.role openssh-5.9p0/auth.h
---- openssh-5.9p0/auth.h.role  2011-08-31 11:42:47.760024631 +0200
-+++ openssh-5.9p0/auth.h       2011-08-31 11:42:55.090151027 +0200
-@@ -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-5.9p0/auth1.c.role openssh-5.9p0/auth1.c
---- openssh-5.9p0/auth1.c.role 2010-08-31 14:36:39.000000000 +0200
-+++ openssh-5.9p0/auth1.c      2011-08-31 11:42:55.215033075 +0200
+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;
@@ -73,9 +36,51 @@ diff -up openssh-5.9p0/auth1.c.role openssh-5.9p0/auth1.c
  
        /* Verify that the user is a valid user. */
        if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
-diff -up openssh-5.9p0/auth2-gss.c.role openssh-5.9p0/auth2-gss.c
---- openssh-5.9p0/auth2-gss.c.role     2011-05-05 06:04:11.000000000 +0200
-+++ openssh-5.9p0/auth2-gss.c  2011-08-31 11:42:55.313025576 +0200
+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;
@@ -108,9 +113,9 @@ diff -up openssh-5.9p0/auth2-gss.c.role openssh-5.9p0/auth2-gss.c
        xfree(mic.value);
  
        authctxt->postponed = 0;
-diff -up openssh-5.9p0/auth2-hostbased.c.role openssh-5.9p0/auth2-hostbased.c
---- openssh-5.9p0/auth2-hostbased.c.role       2011-08-31 11:42:47.863023264 +0200
-+++ openssh-5.9p0/auth2-hostbased.c    2011-08-31 11:42:55.421024814 +0200
+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 */
@@ -128,9 +133,9 @@ diff -up openssh-5.9p0/auth2-hostbased.c.role openssh-5.9p0/auth2-hostbased.c
        buffer_put_cstring(&b, service);
        buffer_put_cstring(&b, "hostbased");
        buffer_put_string(&b, pkalg, alen);
-diff -up openssh-5.9p0/auth2-pubkey.c.role openssh-5.9p0/auth2-pubkey.c
---- openssh-5.9p0/auth2-pubkey.c.role  2011-08-31 11:42:47.978087418 +0200
-+++ openssh-5.9p0/auth2-pubkey.c       2011-08-31 11:42:55.551025263 +0200
+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 */
@@ -148,51 +153,71 @@ diff -up openssh-5.9p0/auth2-pubkey.c.role openssh-5.9p0/auth2-pubkey.c
                buffer_put_cstring(&b,
                    datafellows & SSH_BUG_PKSERVICE ?
                    "ssh-userauth" :
-diff -up openssh-5.9p0/auth2.c.role openssh-5.9p0/auth2.c
---- openssh-5.9p0/auth2.c.role 2011-08-31 11:42:45.409026065 +0200
-+++ openssh-5.9p0/auth2.c      2011-08-31 11:42:55.676024869 +0200
-@@ -216,6 +216,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)
-@@ -227,6 +230,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);
+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
-+      if ((role = strchr(user, '/')) != NULL)
-+              *role++ = 0;
++      char            *role;
 +#endif
-+
-       if ((style = strchr(user, ':')) != NULL)
-               *style++ = 0;
+       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;
  
-@@ -249,8 +257,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
+       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;
 +              }
-               userauth_banner();
-       } else if (strcmp(user, authctxt->user) != 0 ||
-           strcmp(service, authctxt->service) != 0) {
-diff -up openssh-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
---- openssh-5.9p0/monitor.c.role       2011-08-31 11:42:53.301024819 +0200
-+++ openssh-5.9p0/monitor.c    2011-08-31 11:42:55.796025812 +0200
+       }
+       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 *);
@@ -213,7 +238,7 @@ diff -up openssh-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
      {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
      {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
  #ifdef USE_PAM
-@@ -819,6 +825,9 @@ mm_answer_pwnamallow(int sock, Buffer *m
+@@ -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);
@@ -223,7 +248,7 @@ diff -up openssh-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
                monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
        }
  #ifdef USE_PAM
-@@ -862,6 +871,25 @@ mm_answer_authserv(int sock, Buffer *m)
+@@ -881,6 +890,25 @@ mm_answer_authserv(int sock, Buffer *m)
        return (0);
  }
  
@@ -249,7 +274,7 @@ diff -up openssh-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
  int
  mm_answer_authpassword(int sock, Buffer *m)
  {
-@@ -1227,7 +1255,7 @@ static int
+@@ -1251,7 +1279,7 @@ static int
  monitor_valid_userblob(u_char *data, u_int datalen)
  {
        Buffer b;
@@ -258,7 +283,7 @@ diff -up openssh-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
        u_int len;
        int fail = 0;
  
-@@ -1253,6 +1281,8 @@ monitor_valid_userblob(u_char *data, u_i
+@@ -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);
@@ -267,7 +292,7 @@ diff -up openssh-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
        if (strcmp(authctxt->user, p) != 0) {
                logit("wrong user name passed to monitor: expected %s != %.100s",
                    authctxt->user, p);
-@@ -1284,7 +1314,7 @@ monitor_valid_hostbasedblob(u_char *data
+@@ -1308,7 +1338,7 @@ monitor_valid_hostbasedblob(u_char *data
      char *chost)
  {
        Buffer b;
@@ -276,7 +301,7 @@ diff -up openssh-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
        u_int len;
        int fail = 0;
  
-@@ -1301,6 +1331,8 @@ monitor_valid_hostbasedblob(u_char *data
+@@ -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);
@@ -285,9 +310,9 @@ diff -up openssh-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
        if (strcmp(authctxt->user, p) != 0) {
                logit("wrong user name passed to monitor: expected %s != %.100s",
                    authctxt->user, p);
-diff -up openssh-5.9p0/monitor.h.role openssh-5.9p0/monitor.h
---- openssh-5.9p0/monitor.h.role       2011-08-31 11:42:53.409025333 +0200
-+++ openssh-5.9p0/monitor.h    2011-08-31 11:42:55.889024801 +0200
+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,
@@ -298,9 +323,9 @@ diff -up openssh-5.9p0/monitor.h.role openssh-5.9p0/monitor.h
        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-5.9p0/monitor_wrap.c.role openssh-5.9p0/monitor_wrap.c
---- openssh-5.9p0/monitor_wrap.c.role  2011-08-31 11:42:53.548024503 +0200
-+++ openssh-5.9p0/monitor_wrap.c       2011-08-31 11:42:56.029024553 +0200
+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);
  }
@@ -327,9 +352,9 @@ diff -up openssh-5.9p0/monitor_wrap.c.role openssh-5.9p0/monitor_wrap.c
  /* Do the password authentication */
  int
  mm_auth_password(Authctxt *authctxt, char *password)
-diff -up openssh-5.9p0/monitor_wrap.h.role openssh-5.9p0/monitor_wrap.h
---- openssh-5.9p0/monitor_wrap.h.role  2011-08-31 11:42:53.660025271 +0200
-+++ openssh-5.9p0/monitor_wrap.h       2011-08-31 11:42:56.131025748 +0200
+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);
@@ -340,22 +365,22 @@ diff -up openssh-5.9p0/monitor_wrap.h.role openssh-5.9p0/monitor_wrap.h
  struct passwd *mm_getpwnamallow(const char *);
  char *mm_auth2_read_banner(void);
  int mm_auth_password(struct Authctxt *, char *);
-diff -up openssh-5.9p0/openbsd-compat/Makefile.in.role openssh-5.9p0/openbsd-compat/Makefile.in
---- openssh-5.9p0/openbsd-compat/Makefile.in.role      2010-10-07 13:19:24.000000000 +0200
-+++ openssh-5.9p0/openbsd-compat/Makefile.in   2011-08-31 11:48:02.404091479 +0200
+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 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
+ 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-5.9p0/openbsd-compat/port-linux.c.role openssh-5.9p0/openbsd-compat/port-linux.c
---- openssh-5.9p0/openbsd-compat/port-linux.c.role     2011-08-29 08:09:57.000000000 +0200
-+++ openssh-5.9p0/openbsd-compat/port-linux.c  2011-08-31 11:42:56.492087969 +0200
-@@ -31,7 +31,11 @@
+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"
@@ -367,23 +392,177 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux.c.role openssh-5.9p0/openbsd-co
  
  #ifdef WITH_SELINUX
  #include <selinux/selinux.h>
-@@ -42,41 +46,63 @@
+ #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)
--{
--      static int enabled = -1;
 +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)
 +{
@@ -398,23 +577,23 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux.c.role openssh-5.9p0/openbsd-co
 +                              *level = slash + 1;
 +                      }
 +              }
-       }
--
--      return (enabled);
++      }
  }
  
  /* Return the default security context for the given username */
  static security_context_t
- ssh_selinux_getctxbyname(char *pwname)
+-ssh_selinux_getctxbyname(char *pwname)
++ssh_selinux_getctxbyname(char *pwname,
++      security_context_t *default_sc, security_context_t *user_sc)
  {
--      security_context_t sc;
+-      security_context_t sc = NULL;
 -      char *sename = NULL, *lvl = NULL;
 -      int r;
-+      security_context_t sc = NULL;
 +      char *sename, *lvl;
 +      char *role;
 +      const char *reqlvl;
 +      int r = 0;
++      context_t con = NULL;
 + 
 +      ssh_selinux_get_role_level(&role, &reqlvl);
  
@@ -427,31 +606,96 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux.c.role openssh-5.9p0/openbsd-co
 +      }
  #else
        sename = pwname;
-       lvl = NULL;
+-      lvl = NULL;
++      lvl = "";
  #endif
  
 +      if (r == 0) {
  #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
 -      r = get_default_context_with_level(sename, lvl, NULL, &sc);
-+              if (role != NULL && role[0])
-+                      r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc);
-+              else
-+                      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);
-+              if (role != NULL && role[0])
-+                      r = get_default_context_with_role(sename, role, NULL, &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()) {
-@@ -104,6 +130,36 @@ ssh_selinux_getctxbyname(char *pwname)
-       return (sc);
- }
+-      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)
@@ -480,12 +724,16 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux.c.role openssh-5.9p0/openbsd-co
 +              xfree(role);
 +      
 +      return rv;
-+}
-+
+ }
  /* Set the execution context to the default for the specified user */
- void
+@@ -110,28 +348,71 @@ void
  ssh_selinux_setup_exec_context(char *pwname)
-@@ -113,6 +169,24 @@ ssh_selinux_setup_exec_context(char *pwn
+ {
+       security_context_t user_ctx = NULL;
++      int r = 0;
++      security_context_t default_ctx = NULL;
        if (!ssh_selinux_enabled())
                return;
  
@@ -509,8 +757,68 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux.c.role openssh-5.9p0/openbsd-co
 +
        debug3("%s: setting execution context", __func__);
  
-       user_ctx = ssh_selinux_getctxbyname(pwname);
-@@ -220,21 +294,6 @@ ssh_selinux_change_context(const char *n
+-      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);
  }
  
@@ -532,9 +840,9 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux.c.role openssh-5.9p0/openbsd-co
  #endif /* WITH_SELINUX */
  
  #ifdef LINUX_OOM_ADJUST
-diff -up openssh-5.9p0/openbsd-compat/port-linux_part_2.c.role openssh-5.9p0/openbsd-compat/port-linux_part_2.c
---- openssh-5.9p0/openbsd-compat/port-linux_part_2.c.role      2011-08-31 11:42:56.583047619 +0200
-+++ openssh-5.9p0/openbsd-compat/port-linux_part_2.c   2011-08-31 11:42:56.586178005 +0200
+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 $ */
 +
@@ -611,3 +919,16 @@ diff -up openssh-5.9p0/openbsd-compat/port-linux_part_2.c.role openssh-5.9p0/ope
 +#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);
similarity index 61%
rename from openssh/patches/openssh-5.9p1-vendor.patch
rename to openssh/patches/openssh-6.1p1-vendor.patch
index 3e63d3bb9b6d472156a8eeb949ba325f2c223766..9cb326d39af1da92060106e79e25a60368b269b8 100644 (file)
@@ -1,7 +1,7 @@
-diff -up openssh-5.9p0/configure.ac.vendor openssh-5.9p0/configure.ac
---- openssh-5.9p0/configure.ac.vendor  2011-09-03 20:24:29.899501572 +0200
-+++ openssh-5.9p0/configure.ac 2011-09-03 20:24:39.153501595 +0200
-@@ -4131,6 +4131,12 @@ AC_ARG_WITH([lastlog],
+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
        ]
  )
@@ -14,7 +14,7 @@ diff -up openssh-5.9p0/configure.ac.vendor openssh-5.9p0/configure.ac
  
  dnl lastlog, [uw]tmpx? detection
  dnl  NOTE: set the paths in the platform section to avoid the
-@@ -4357,6 +4363,7 @@ echo "           Translate v4 in v6 hack
+@@ -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"
@@ -22,10 +22,10 @@ diff -up openssh-5.9p0/configure.ac.vendor openssh-5.9p0/configure.ac
  
  echo ""
  
-diff -up openssh-5.9p0/servconf.c.vendor openssh-5.9p0/servconf.c
---- openssh-5.9p0/servconf.c.vendor    2011-09-03 20:24:29.080500853 +0200
-+++ openssh-5.9p0/servconf.c   2011-09-03 20:27:15.727564566 +0200
-@@ -130,6 +130,7 @@ initialize_server_options(ServerOptions
+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;
@@ -33,25 +33,26 @@ diff -up openssh-5.9p0/servconf.c.vendor openssh-5.9p0/servconf.c
        options->use_dns = -1;
        options->client_alive_interval = -1;
        options->client_alive_count_max = -1;
-@@ -300,6 +301,8 @@ fill_default_server_options(ServerOption
-               options->ip_qos_interactive = IPTOS_LOWDELAY;
-       if (options->ip_qos_bulk == -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;
++              options->show_patchlevel = 0;
++
        /* Turn privilege separation on by default */
        if (use_privsep == -1)
-@@ -338,7 +341,7 @@ typedef enum {
+               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, sTwoFactorAuthentication,
-       sSecondPubkeyAuthentication, sSecondGssAuthentication,
-       sSecondPasswordAuthentication, sSecondKbdInteractiveAuthentication,
-@@ -470,6 +473,7 @@ static struct {
+       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 },
@@ -59,7 +60,7 @@ diff -up openssh-5.9p0/servconf.c.vendor openssh-5.9p0/servconf.c
        { "usedns", sUseDNS, SSHCFG_GLOBAL },
        { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
        { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
-@@ -1152,6 +1156,10 @@ process_server_config_line(ServerOptions
+@@ -1162,6 +1167,10 @@ process_server_config_line(ServerOptions
                multistate_ptr = multistate_privsep;
                goto parse_multistate;
  
@@ -70,7 +71,7 @@ diff -up openssh-5.9p0/servconf.c.vendor openssh-5.9p0/servconf.c
        case sAllowUsers:
                while ((arg = strdelim(&cp)) && *arg != '\0') {
                        if (options->num_allow_users >= MAX_ALLOW_USERS)
-@@ -1849,6 +1857,7 @@ dump_config(ServerOptions *o)
+@@ -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);
@@ -78,10 +79,10 @@ diff -up openssh-5.9p0/servconf.c.vendor openssh-5.9p0/servconf.c
        dump_cfg_fmtint(sUseDNS, o->use_dns);
        dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
        dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
-diff -up openssh-5.9p0/servconf.h.vendor openssh-5.9p0/servconf.h
---- openssh-5.9p0/servconf.h.vendor    2011-09-03 20:24:29.179632045 +0200
-+++ openssh-5.9p0/servconf.h   2011-09-03 20:24:39.426502323 +0200
-@@ -148,6 +148,7 @@ typedef struct {
+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 */
@@ -89,32 +90,21 @@ diff -up openssh-5.9p0/servconf.h.vendor openssh-5.9p0/servconf.h
        int     use_dns;
        int     client_alive_interval;  /*
                                         * poke the client this often to
-diff -up openssh-5.9p0/sshd.c.vendor openssh-5.9p0/sshd.c
---- openssh-5.9p0/sshd.c.vendor        2011-09-03 20:24:35.987501565 +0200
-+++ openssh-5.9p0/sshd.c       2011-09-03 20:24:39.542501643 +0200
-@@ -431,7 +431,7 @@ sshd_exchange_identification(int sock_in
-               minor = PROTOCOL_MINOR_1;
-       }
-       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
--          SSH_VERSION, newline);
-+         (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, newline);
-       server_version_string = xstrdup(buf);
-       /* Send our protocol version identification. */
-@@ -1627,7 +1627,8 @@ main(int ac, char **av)
-               exit(1);
-       }
--      debug("sshd version %.100s", SSH_RELEASE);
-+      debug("sshd version %.100s",
-+            (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_RELEASE);
-       /* Store privilege separation user for later use if required. */
-       if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
-diff -up openssh-5.9p0/sshd_config.0.vendor openssh-5.9p0/sshd_config.0
---- openssh-5.9p0/sshd_config.0.vendor 2011-09-03 20:24:37.524438185 +0200
-+++ openssh-5.9p0/sshd_config.0        2011-09-03 20:24:39.677508255 +0200
-@@ -556,6 +556,11 @@ DESCRIPTION
+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.
  
@@ -126,10 +116,10 @@ diff -up openssh-5.9p0/sshd_config.0.vendor openssh-5.9p0/sshd_config.0
       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-5.9p0/sshd_config.5.vendor openssh-5.9p0/sshd_config.5
---- openssh-5.9p0/sshd_config.5.vendor 2011-09-03 20:24:37.640442022 +0200
-+++ openssh-5.9p0/sshd_config.5        2011-09-03 20:24:40.176544206 +0200
-@@ -952,6 +952,14 @@ This option applies to protocol version
+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.
@@ -144,14 +134,25 @@ diff -up openssh-5.9p0/sshd_config.5.vendor openssh-5.9p0/sshd_config.5
  .It Cm StrictModes
  Specifies whether
  .Xr sshd 8
-diff -up openssh-5.9p0/sshd_config.vendor openssh-5.9p0/sshd_config
---- openssh-5.9p0/sshd_config.vendor   2011-09-03 20:24:37.770439735 +0200
-+++ openssh-5.9p0/sshd_config  2011-09-03 20:24:40.278628002 +0200
-@@ -120,6 +120,7 @@ X11Forwarding yes
- #Compression delayed
- #ClientAliveInterval 0
- #ClientAliveCountMax 3
-+#ShowPatchLevel no
- #UseDNS yes
- #PidFile /var/run/sshd.pid
- #MaxStartups 10
+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) {