From: Stefan Schantl Date: Sat, 8 Dec 2012 17:22:54 +0000 (+0100) Subject: openssh: Update to 6.1p1. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=43c69e28b99bb6c6f847f2467d79297df2c96b92;p=ipfire-3.x.git openssh: Update to 6.1p1. 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. --- diff --git a/openssh/openssh.nm b/openssh/openssh.nm index f46e85f4e..10d43f474 100644 --- a/openssh/openssh.nm +++ b/openssh/openssh.nm @@ -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 index b19d2acb9..000000000 --- a/openssh/patches/openssh-5.9p1-2auth.patch +++ /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 index 116394906..000000000 --- a/openssh/patches/openssh-5.9p1-mls.patch +++ /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 - #include -+#include - #include -+#include -+#include -+ -+#ifdef HAVE_LINUX_AUDIT -+#include -+#include -+#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); diff --git a/openssh/patches/openssh-5.9p1-entropy.patch b/openssh/patches/openssh-6.0p1-entropy.patch similarity index 67% rename from openssh/patches/openssh-5.9p1-entropy.patch rename to openssh/patches/openssh-6.0p1-entropy.patch index b3dec46a6..79f05f4aa 100644 --- a/openssh/patches/openssh-5.9p1-entropy.patch +++ b/openssh/patches/openssh-6.0p1-entropy.patch @@ -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 index 000000000..0401ba078 --- /dev/null +++ b/openssh/patches/openssh-6.1p1-akc.patch @@ -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 + #include ++#include + ++#include + #include ++#include + #include ++#include + #include + #include + #include +@@ -260,7 +264,7 @@ match_principals_file(char *file, struct + if (strcmp(cp, cert->principals[i]) == 0) { + debug3("matched principal \"%.100s\" " + "from file \"%s\" on line %lu", +- cert->principals[i], file, linenum); ++ cert->principals[i], file, linenum); + if (auth_parse_options(pw, line_opts, + file, linenum) != 1) + continue; +@@ -273,31 +277,22 @@ match_principals_file(char *file, struct + fclose(f); + restore_uid(); + return 0; +-} ++} + +-/* return 1 if user allows given key */ ++/* ++ * Checks whether key is allowed in authorized_keys-format file, ++ * returns 1 if the key is allowed or 0 otherwise. ++ */ + static int +-user_key_allowed2(struct passwd *pw, Key *key, char *file) ++check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) + { + char line[SSH_MAX_PUBKEY_BYTES]; + const char *reason; + int found_key = 0; +- FILE *f; + u_long linenum = 0; + Key *found; + char *fp; + +- /* Temporarily use the user's uid. */ +- temporarily_use_uid(pw); +- +- debug("trying public key file %s", file); +- f = auth_openkeyfile(file, pw, options.strict_modes); +- +- if (!f) { +- restore_uid(); +- return 0; +- } +- + found_key = 0; + found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); + +@@ -390,8 +385,6 @@ user_key_allowed2(struct passwd *pw, Key + break; + } + } +- restore_uid(); +- fclose(f); + key_free(found); + if (!found_key) + debug2("key not found"); +@@ -453,7 +446,173 @@ user_cert_trusted_ca(struct passwd *pw, + return ret; + } + +-/* check whether given key is in .ssh/authorized_keys* */ ++/* ++ * Checks whether key is allowed in file. ++ * returns 1 if the key is allowed or 0 otherwise. ++ */ ++static int ++user_key_allowed2(struct passwd *pw, Key *key, char *file) ++{ ++ FILE *f; ++ int found_key = 0; ++ ++ /* Temporarily use the user's uid. */ ++ temporarily_use_uid(pw); ++ ++ debug("trying public key file %s", file); ++ if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) { ++ found_key = check_authkeys_file(f, file, key, pw); ++ fclose(f); ++ } ++ ++ restore_uid(); ++ return found_key; ++} ++ ++/* ++ * Checks whether key is allowed in output of command. ++ * returns 1 if the key is allowed or 0 otherwise. ++ */ ++static int ++user_key_command_allowed2(struct passwd *user_pw, Key *key) ++{ ++ FILE *f; ++ int ok, found_key = 0; ++ struct passwd *pw; ++ struct stat st; ++ int status, devnull, p[2], i; ++ pid_t pid; ++ char errmsg[512]; ++ ++ if (options.authorized_keys_command == NULL || ++ options.authorized_keys_command[0] != '/') ++ return 0; ++ ++ /* If no user specified to run commands the default to target user */ ++ if (options.authorized_keys_command_user == NULL) ++ pw = user_pw; ++ else { ++ pw = getpwnam(options.authorized_keys_command_user); ++ if (pw == NULL) { ++ error("AuthorizedKeyCommandUser \"%s\" not found: %s", ++ options.authorized_keys_command, strerror(errno)); ++ return 0; ++ } ++ } ++ ++ temporarily_use_uid(pw); ++ if (stat(options.authorized_keys_command, &st) < 0) { ++ error("Could not stat AuthorizedKeysCommand \"%s\": %s", ++ options.authorized_keys_command, strerror(errno)); ++ goto out; ++ } ++ ++ if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0, ++ errmsg, sizeof(errmsg)) != 0) { ++ error("Unsafe AuthorizedKeysCommand: %s", errmsg); ++ goto out; ++ } ++ ++ /* open the pipe and read the keys */ ++ if (pipe(p) != 0) { ++ error("%s: pipe: %s", __func__, strerror(errno)); ++ goto out; ++ } ++ ++ debug3("Running AuthorizedKeysCommand: \"%s\" as \"%s\"", ++ options.authorized_keys_command, pw->pw_name); ++ ++ /* ++ * Don't want to call this in the child, where it can fatal() and ++ * run cleanup_exit() code. ++ */ ++ restore_uid(); ++ ++ switch ((pid = fork())) { ++ case -1: /* error */ ++ error("%s: fork: %s", __func__, strerror(errno)); ++ close(p[0]); ++ close(p[1]); ++ return 0; ++ case 0: /* child */ ++ for (i = 0; i < NSIG; i++) ++ signal(i, SIG_DFL); ++ ++ /* Don't use permanently_set_uid() here to avoid fatal() */ ++ if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { ++ error("setresgid %u: %s", (u_int)pw->pw_gid, ++ strerror(errno)); ++ _exit(1); ++ } ++ if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) { ++ error("setresuid %u: %s", (u_int)pw->pw_uid, ++ strerror(errno)); ++ _exit(1); ++ } ++ ++ close(p[0]); ++ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { ++ error("%s: open %s: %s", __func__, _PATH_DEVNULL, ++ strerror(errno)); ++ _exit(1); ++ } ++ if (dup2(devnull, STDIN_FILENO) == -1 || ++ dup2(p[1], STDOUT_FILENO) == -1 || ++ dup2(devnull, STDERR_FILENO) == -1) { ++ error("%s: dup2: %s", __func__, strerror(errno)); ++ _exit(1); ++ } ++ closefrom(STDERR_FILENO + 1); ++ ++ execl(options.authorized_keys_command, ++ options.authorized_keys_command, pw->pw_name, NULL); ++ ++ error("AuthorizedKeysCommand %s exec failed: %s", ++ options.authorized_keys_command, strerror(errno)); ++ _exit(127); ++ default: /* parent */ ++ break; ++ } ++ ++ temporarily_use_uid(pw); ++ ++ close(p[1]); ++ if ((f = fdopen(p[0], "r")) == NULL) { ++ error("%s: fdopen: %s", __func__, strerror(errno)); ++ close(p[0]); ++ /* Don't leave zombie child */ ++ while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) ++ ; ++ goto out; ++ } ++ ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); ++ fclose(f); ++ ++ while (waitpid(pid, &status, 0) == -1) { ++ if (errno != EINTR) { ++ error("%s: waitpid: %s", __func__, strerror(errno)); ++ goto out; ++ } ++ } ++ if (WIFSIGNALED(status)) { ++ error("AuthorizedKeysCommand %s exited on signal %d", ++ options.authorized_keys_command, WTERMSIG(status)); ++ goto out; ++ } else if (WEXITSTATUS(status) != 0) { ++ error("AuthorizedKeysCommand %s returned status %d", ++ options.authorized_keys_command, WEXITSTATUS(status)); ++ goto out; ++ } ++ found_key = ok; ++ out: ++ restore_uid(); ++ ++ return found_key; ++} ++ ++/* ++ * Check whether key authenticates and authorises the user. ++ */ + int + user_key_allowed(struct passwd *pw, Key *key) + { +@@ -469,6 +628,10 @@ user_key_allowed(struct passwd *pw, Key + if (success) + return success; + ++ success = user_key_command_allowed2(pw, key); ++ if (success > 0) ++ return success; ++ + for (i = 0; !success && i < options.num_authkeys_files; i++) { + file = expand_authorized_keys( + options.authorized_keys_files[i], pw); +diff -up openssh-6.1p1/auth.c.akc openssh-6.1p1/auth.c +--- openssh-6.1p1/auth.c.akc 2012-11-28 17:12:43.187524558 +0100 ++++ openssh-6.1p1/auth.c 2012-11-28 17:12:43.263524297 +0100 +@@ -411,39 +411,41 @@ check_key_in_hostfiles(struct passwd *pw + + + /* +- * Check a given file for security. This is defined as all components ++ * Check a given path for security. This is defined as all components + * of the path to the file must be owned by either the owner of + * of the file or root and no directories must be group or world writable. + * + * XXX Should any specific check be done for sym links ? + * +- * Takes an open file descriptor, the file name, a uid and and ++ * Takes an the file name, its stat information (preferably from fstat() to ++ * avoid races), the uid of the expected owner, their home directory and an + * error buffer plus max size as arguments. + * + * Returns 0 on success and -1 on failure + */ +-static int +-secure_filename(FILE *f, const char *file, struct passwd *pw, +- char *err, size_t errlen) ++int ++auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, ++ uid_t uid, char *err, size_t errlen) + { +- uid_t uid = pw->pw_uid; + char buf[MAXPATHLEN], homedir[MAXPATHLEN]; + char *cp; + int comparehome = 0; + struct stat st; + +- if (realpath(file, buf) == NULL) { +- snprintf(err, errlen, "realpath %s failed: %s", file, ++ if (realpath(name, buf) == NULL) { ++ snprintf(err, errlen, "realpath %s failed: %s", name, + strerror(errno)); + return -1; + } +- if (realpath(pw->pw_dir, homedir) != NULL) ++ if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) + comparehome = 1; + +- /* check the open file to avoid races */ +- if (fstat(fileno(f), &st) < 0 || +- (st.st_uid != 0 && st.st_uid != uid) || +- (st.st_mode & 022) != 0) { ++ if (!S_ISREG(stp->st_mode)) { ++ snprintf(err, errlen, "%s is not a regular file", buf); ++ return -1; ++ } ++ if ((stp->st_uid != 0 && stp->st_uid != uid) || ++ (stp->st_mode & 022) != 0) { + snprintf(err, errlen, "bad ownership or modes for file %s", + buf); + return -1; +@@ -479,6 +481,31 @@ secure_filename(FILE *f, const char *fil + return 0; + } + ++/* ++ * Version of secure_path() that accepts an open file descriptor to ++ * avoid races. ++ * ++ * Returns 0 on success and -1 on failure ++ */ ++static int ++secure_filename(FILE *f, const char *file, struct passwd *pw, ++ char *err, size_t errlen) ++{ ++ uid_t uid = pw->pw_uid; ++ char buf[MAXPATHLEN], homedir[MAXPATHLEN]; ++ char *cp; ++ int comparehome = 0; ++ struct stat st; ++ ++ /* check the open file to avoid races */ ++ if (fstat(fileno(f), &st) < 0) { ++ snprintf(err, errlen, "cannot stat file %s: %s", ++ buf, strerror(errno)); ++ return -1; ++ } ++ return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); ++} ++ + static FILE * + auth_openfile(const char *file, struct passwd *pw, int strict_modes, + int log_missing, char *file_type) +diff -up openssh-6.1p1/auth.h.akc openssh-6.1p1/auth.h +--- openssh-6.1p1/auth.h.akc 2012-11-28 17:12:43.239524381 +0100 ++++ openssh-6.1p1/auth.h 2012-11-28 17:12:43.263524297 +0100 +@@ -125,6 +125,10 @@ int auth_rhosts_rsa_key_allowed(struct + int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); + int user_key_allowed(struct passwd *, Key *); + ++struct stat; ++int auth_secure_path(const char *, struct stat *, const char *, uid_t, ++ char *, size_t); ++ + #ifdef KRB5 + int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); + int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); +diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c +--- openssh-6.1p1/servconf.c.akc 2012-11-28 17:12:43.198524521 +0100 ++++ openssh-6.1p1/servconf.c 2012-11-28 17:14:50.314005026 +0100 +@@ -137,6 +137,8 @@ initialize_server_options(ServerOptions + options->num_permitted_opens = -1; + options->adm_forced_command = NULL; + options->chroot_directory = NULL; ++ options->authorized_keys_command = NULL; ++ options->authorized_keys_command_user = NULL; + options->zero_knowledge_password_authentication = -1; + options->revoked_keys_file = NULL; + options->trusted_user_ca_keys = NULL; +@@ -331,6 +333,7 @@ typedef enum { + sZeroKnowledgePasswordAuthentication, sHostCertificate, + sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, + sKexAlgorithms, sIPQoS, sVersionAddendum, ++ sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, + sAuthenticationMethods, + sDeprecated, sUnsupported + } ServerOpCodes; +@@ -457,6 +460,9 @@ static struct { + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, + { "ipqos", sIPQoS, SSHCFG_ALL }, + { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, ++ { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, ++ { "authorizedkeyscommandrunas", sAuthorizedKeysCommandUser, SSHCFG_ALL }, ++ { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, + { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, + { NULL, sBadOption, 0 } + }; +@@ -1520,6 +1526,26 @@ process_server_config_line(ServerOptions + } + return 0; + ++ case sAuthorizedKeysCommand: ++ len = strspn(cp, WHITESPACE); ++ if (*activep && options->authorized_keys_command == NULL) { ++ options->authorized_keys_command = xstrdup(cp + len); ++ if (*options->authorized_keys_command != '/') { ++ fatal("%.200s line %d: AuthorizedKeysCommand " ++ "must be an absolute path", ++ filename, linenum); ++ } ++ } ++ return 0; ++ ++ case sAuthorizedKeysCommandUser: ++ charptr = &options->authorized_keys_command_user; ++ ++ arg = strdelim(&cp); ++ if (*activep && *charptr == NULL) ++ *charptr = xstrdup(arg); ++ break; ++ + case sDeprecated: + logit("%s line %d: Deprecated option %s", + filename, linenum, arg); +@@ -1670,6 +1696,8 @@ copy_set_server_options(ServerOptions *d + M_CP_INTOPT(hostbased_uses_name_from_packet_only); + M_CP_INTOPT(kbd_interactive_authentication); + M_CP_INTOPT(zero_knowledge_password_authentication); ++ M_CP_STROPT(authorized_keys_command); ++ M_CP_STROPT(authorized_keys_command_user); + M_CP_INTOPT(permit_root_login); + M_CP_INTOPT(permit_empty_passwd); + +@@ -1930,6 +1958,8 @@ dump_config(ServerOptions *o) + dump_cfg_string(sAuthorizedPrincipalsFile, + o->authorized_principals_file); + dump_cfg_string(sVersionAddendum, o->version_addendum); ++ dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); ++ dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); + + /* string arguments requiring a lookup */ + dump_cfg_string(sLogLevel, log_level_name(o->log_level)); +diff -up openssh-6.1p1/servconf.h.akc openssh-6.1p1/servconf.h +--- openssh-6.1p1/servconf.h.akc 2012-11-28 17:12:43.000000000 +0100 ++++ openssh-6.1p1/servconf.h 2012-11-28 17:18:41.217055157 +0100 +@@ -167,6 +167,8 @@ typedef struct { + char *revoked_keys_file; + char *trusted_user_ca_keys; + char *authorized_principals_file; ++ char *authorized_keys_command; ++ char *authorized_keys_command_user; + + char *version_addendum; /* Appended to SSH banner */ + +diff -up openssh-6.1p1/sshd.c.akc openssh-6.1p1/sshd.c +--- openssh-6.1p1/sshd.c.akc 2012-11-28 17:12:43.245524360 +0100 ++++ openssh-6.1p1/sshd.c 2012-11-28 17:12:43.265524291 +0100 +@@ -366,9 +366,20 @@ main_sigchld_handler(int sig) + static void + grace_alarm_handler(int sig) + { ++ pid_t pgid; ++ + if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0) + kill(pmonitor->m_pid, SIGALRM); + ++ /* ++ * Try to kill any processes that we have spawned, E.g. authorized ++ * keys command helpers. ++ */ ++ if ((pgid = getpgid(0)) == getpid()) { ++ signal(SIGTERM, SIG_IGN); ++ killpg(pgid, SIGTERM); ++ } ++ + /* Log error and exit. */ + sigdie("Timeout before authentication for %s", get_remote_ipaddr()); + } +diff -up openssh-6.1p1/sshd_config.0.akc openssh-6.1p1/sshd_config.0 +--- openssh-6.1p1/sshd_config.0.akc 2012-08-29 02:53:04.000000000 +0200 ++++ openssh-6.1p1/sshd_config.0 2012-11-28 17:12:43.265524291 +0100 +@@ -71,6 +71,23 @@ DESCRIPTION + + See PATTERNS in ssh_config(5) for more information on patterns. + ++ AuthorizedKeysCommand ++ ++ Specifies a program to be used for lookup of the user's ++ public keys. The program will be invoked with its first ++ argument the name of the user being authorized, and should produce ++ on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS ++ in sshd(8)). By default (or when set to the empty string) there is no ++ AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully ++ authorize the user, authorization falls through to the ++ AuthorizedKeysFile. Note that this option has an effect ++ only with PubkeyAuthentication turned on. ++ ++ AuthorizedKeysCommandRunAs ++ Specifies the user under whose account the AuthorizedKeysCommand is run. ++ Empty string (the default value) means the user being authorized ++ is used. ++ + AuthorizedKeysFile + Specifies the file that contains the public keys that can be used + for user authentication. The format is described in the +@@ -402,7 +419,8 @@ DESCRIPTION + Only a subset of keywords may be used on the lines following a + Match keyword. Available keywords are AcceptEnv, + AllowAgentForwarding, AllowGroups, AllowTcpForwarding, +- AllowUsers, AuthorizedKeysFile, AuthorizedPrincipalsFile, Banner, ++ AllowUsers, AuthorizedKeysFile, AuthorizedKeysCommand, ++ AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile, Banner, + ChrootDirectory, DenyGroups, DenyUsers, ForceCommand, + GatewayPorts, GSSAPIAuthentication, HostbasedAuthentication, + HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication, +diff -up openssh-6.1p1/sshd_config.5.akc openssh-6.1p1/sshd_config.5 +--- openssh-6.1p1/sshd_config.5.akc 2012-11-28 17:12:43.199524517 +0100 ++++ openssh-6.1p1/sshd_config.5 2012-11-28 17:16:23.736624980 +0100 +@@ -173,6 +173,20 @@ Note that each authentication method lis + in the configuration. + The default is not to require multiple authentication; successful completion + of a single authentication method is sufficient. ++.It Cm AuthorizedKeysCommand ++Specifies a program to be used for lookup of the user's public keys. ++The program will be invoked with a single argument of the username ++being authenticated, and should produce on standard output zero or ++more lines of authorized_keys output (see AUTHORIZED_KEYS in ++.Xr sshd 8 ) ++If a key supplied by AuthorizedKeysCommand does not successfully authenticate ++and authorize the user then public key authentication continues using the usual ++.Cm AuthorizedKeysFile ++files. ++By default, no AuthorizedKeysCommand is run. ++.It Cm AuthorizedKeysCommandUser ++Specifies the user under whose account the AuthorizedKeysCommand is run. ++The default is the user being authenticated. + .It Cm AuthorizedKeysFile + Specifies the file that contains the public keys that can be used + for user authentication. +@@ -734,6 +748,8 @@ Available keywords are + .Cm AllowTcpForwarding , + .Cm AllowUsers , + .Cm AuthenticationMethods , ++.Cm AuthorizedKeysCommand , ++.Cm AuthorizedKeysCommandUser , + .Cm AuthorizedKeysFile , + .Cm AuthorizedPrincipalsFile , + .Cm Banner , +@@ -749,6 +765,7 @@ Available keywords are + .Cm KerberosAuthentication , + .Cm MaxAuthTries , + .Cm MaxSessions , ++.Cm PubkeyAuthentication , + .Cm PasswordAuthentication , + .Cm PermitEmptyPasswords , + .Cm PermitOpen , +diff -up openssh-6.1p1/sshd_config.akc openssh-6.1p1/sshd_config +--- openssh-6.1p1/sshd_config.akc 2012-07-31 04:21:34.000000000 +0200 ++++ openssh-6.1p1/sshd_config 2012-11-28 17:12:43.265524291 +0100 +@@ -49,6 +49,9 @@ + # but this is overridden so installations will only check .ssh/authorized_keys + AuthorizedKeysFile .ssh/authorized_keys + ++#AuthorizedKeysCommand none ++#AuthorizedKeysCommandUser nobody ++ + #AuthorizedPrincipalsFile none + + # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts diff --git a/openssh/patches/openssh-5.8p2-askpass-ld.patch b/openssh/patches/openssh-6.1p1-askpass-ld.patch similarity index 53% rename from openssh/patches/openssh-5.8p2-askpass-ld.patch rename to openssh/patches/openssh-6.1p1-askpass-ld.patch index 5b85c80b3..f7a7facb3 100644 --- a/openssh/patches/openssh-5.8p2-askpass-ld.patch +++ b/openssh/patches/openssh-6.1p1-askpass-ld.patch @@ -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 index 000000000..7b5a06a34 --- /dev/null +++ b/openssh/patches/openssh-6.1p1-authenticationmethods.patch @@ -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 , diff --git a/openssh/patches/openssh-5.9p1-coverity.patch b/openssh/patches/openssh-6.1p1-coverity.patch similarity index 73% rename from openssh/patches/openssh-5.9p1-coverity.patch rename to openssh/patches/openssh-6.1p1-coverity.patch index f3524e3a0..0c8fb236c 100644 --- a/openssh/patches/openssh-5.9p1-coverity.patch +++ b/openssh/patches/openssh-6.1p1-coverity.patch @@ -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. */ diff --git a/openssh/patches/openssh-5.9p1-kuserok.patch b/openssh/patches/openssh-6.1p1-kuserok.patch similarity index 67% rename from openssh/patches/openssh-5.9p1-kuserok.patch rename to openssh/patches/openssh-6.1p1-kuserok.patch index 11f38a51c..7b695e0b3 100644 --- a/openssh/patches/openssh-5.9p1-kuserok.patch +++ b/openssh/patches/openssh-6.1p1-kuserok.patch @@ -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 index 000000000..bfc28eed8 --- /dev/null +++ b/openssh/patches/openssh-6.1p1-required-authentications.patch @@ -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 >= diff --git a/openssh/patches/openssh-5.9p1-role.patch b/openssh/patches/openssh-6.1p1-role-mls.patch similarity index 50% rename from openssh/patches/openssh-5.9p1-role.patch rename to openssh/patches/openssh-6.1p1-role-mls.patch index 8a26bdfc5..4de3dae94 100644 --- a/openssh/patches/openssh-5.9p1-role.patch +++ b/openssh/patches/openssh-6.1p1-role-mls.patch @@ -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 -@@ -42,41 +46,63 @@ + #include ++#include + #include ++#include ++#include ++ ++#ifdef HAVE_LINUX_AUDIT ++#include ++#include ++#endif + + #ifndef SSH_SELINUX_UNCONFINED_TYPE # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" #endif -/* Wrapper around is_selinux_enabled() to log its return value once only */ -int -ssh_selinux_enabled(void) --{ -- 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); diff --git a/openssh/patches/openssh-5.9p1-vendor.patch b/openssh/patches/openssh-6.1p1-vendor.patch similarity index 61% rename from openssh/patches/openssh-5.9p1-vendor.patch rename to openssh/patches/openssh-6.1p1-vendor.patch index 3e63d3bb9..9cb326d39 100644 --- a/openssh/patches/openssh-5.9p1-vendor.patch +++ b/openssh/patches/openssh-6.1p1-vendor.patch @@ -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) {