This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 3.x development tree".
The branch, master has been updated via 5c16bb1ac0c13a057b26a8187a44178d4189416b (commit) via 43c69e28b99bb6c6f847f2467d79297df2c96b92 (commit) from 38309f025a1c685fd6741f6a9e2e04908f0d6fa1 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 5c16bb1ac0c13a057b26a8187a44178d4189416b Merge: 38309f0 43c69e2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Dec 8 22:34:53 2012 +0100
Merge remote-tracking branch 'stevee/openssh-6.1'
commit 43c69e28b99bb6c6f847f2467d79297df2c96b92 Author: Stefan Schantl stefan.schantl@ipfire.org Date: Sat Dec 8 18:22:54 2012 +0100
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.
-----------------------------------------------------------------------
Summary of changes: openssh/openssh.nm | 25 +- openssh/patches/openssh-5.9p1-2auth.patch | 354 --------- openssh/patches/openssh-5.9p1-mls.patch | 400 ---------- ...1-entropy.patch => openssh-6.0p1-entropy.patch} | 157 ++-- openssh/patches/openssh-6.1p1-akc.patch | 565 ++++++++++++++ ...ass-ld.patch => openssh-6.1p1-askpass-ld.patch} | 14 +- .../openssh-6.1p1-authenticationmethods.patch | 841 +++++++++++++++++++++ ...coverity.patch => openssh-6.1p1-coverity.patch} | 456 +++++------ ...1-kuserok.patch => openssh-6.1p1-kuserok.patch} | 82 +- .../openssh-6.1p1-required-authentications.patch | 22 + ...9p1-role.patch => openssh-6.1p1-role-mls.patch} | 611 +++++++++++---- ...9p1-vendor.patch => openssh-6.1p1-vendor.patch} | 133 ++-- 12 files changed, 2319 insertions(+), 1341 deletions(-) delete mode 100644 openssh/patches/openssh-5.9p1-2auth.patch delete mode 100644 openssh/patches/openssh-5.9p1-mls.patch rename openssh/patches/{openssh-5.9p1-entropy.patch => openssh-6.0p1-entropy.patch} (67%) create mode 100644 openssh/patches/openssh-6.1p1-akc.patch rename openssh/patches/{openssh-5.8p2-askpass-ld.patch => openssh-6.1p1-askpass-ld.patch} (53%) create mode 100644 openssh/patches/openssh-6.1p1-authenticationmethods.patch rename openssh/patches/{openssh-5.9p1-coverity.patch => openssh-6.1p1-coverity.patch} (73%) rename openssh/patches/{openssh-5.9p1-kuserok.patch => openssh-6.1p1-kuserok.patch} (67%) create mode 100644 openssh/patches/openssh-6.1p1-required-authentications.patch rename openssh/patches/{openssh-5.9p1-role.patch => openssh-6.1p1-role-mls.patch} (50%) rename openssh/patches/{openssh-5.9p1-vendor.patch => openssh-6.1p1-vendor.patch} (61%)
Difference in files: diff --git a/openssh/openssh.nm b/openssh/openssh.nm index f46e85f..10d43f4 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.8p2-askpass-ld.patch b/openssh/patches/openssh-5.8p2-askpass-ld.patch deleted file mode 100644 index 5b85c80..0000000 --- a/openssh/patches/openssh-5.8p2-askpass-ld.patch +++ /dev/null @@ -1,18 +0,0 @@ -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: - @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" - - gnome-ssh-askpass1: gnome-ssh-askpass1.c -- $(CC) `gnome-config --cflags gnome gnomeui` \ -+ $(CC) ${CFLAGS} `gnome-config --cflags gnome gnomeui` \ - gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \ - `gnome-config --libs gnome gnomeui` - - gnome-ssh-askpass2: gnome-ssh-askpass2.c -- $(CC) `pkg-config --cflags gtk+-2.0` \ -+ $(CC) ${CFLAGS} `pkg-config --cflags gtk+-2.0` \ - gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ - `pkg-config --libs gtk+-2.0 x11` - diff --git a/openssh/patches/openssh-5.9p1-2auth.patch b/openssh/patches/openssh-5.9p1-2auth.patch deleted file mode 100644 index b19d2ac..0000000 --- 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-coverity.patch b/openssh/patches/openssh-5.9p1-coverity.patch deleted file mode 100644 index f3524e3..0000000 --- a/openssh/patches/openssh-5.9p1-coverity.patch +++ /dev/null @@ -1,844 +0,0 @@ -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 -@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void * - if (sshpam_thread_status != -1) - return (sshpam_thread_status); - signal(SIGCHLD, sshpam_oldsig); -- waitpid(thread, &status, 0); -+ while (waitpid(thread, &status, 0) < 0) { -+ if (errno == EINTR) -+ continue; -+ fatal("%s: waitpid: %s", __func__, -+ strerror(errno)); -+ } - return (status); - } - #endif -diff -up openssh-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 - channel_max_fd = MAX(channel_max_fd, wfd); - channel_max_fd = MAX(channel_max_fd, efd); - -- if (rfd != -1) -+ if (rfd >= 0) - fcntl(rfd, F_SETFD, FD_CLOEXEC); -- if (wfd != -1 && wfd != rfd) -+ if (wfd >= 0 && wfd != rfd) - fcntl(wfd, F_SETFD, FD_CLOEXEC); -- if (efd != -1 && efd != rfd && efd != wfd) -+ if (efd >= 0 && efd != rfd && efd != wfd) - fcntl(efd, F_SETFD, FD_CLOEXEC); - - c->rfd = rfd; -@@ -248,11 +248,11 @@ channel_register_fds(Channel *c, int rfd - - /* enable nonblocking mode */ - if (nonblock) { -- if (rfd != -1) -+ if (rfd >= 0) - set_nonblock(rfd); -- if (wfd != -1) -+ if (wfd >= 0) - set_nonblock(wfd); -- if (efd != -1) -+ if (efd >= 0) - set_nonblock(efd); - } - } -diff -up openssh-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) - success = 1; - /*XXXX*/ - key_free(k); -+/*XXXX - if (success != 1) - break; -+XXXX*/ - /* advance cp: skip whitespace and data */ - while (*cp == ' ' || *cp == '\t') - cp++; -diff -up openssh-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 -@@ -420,7 +420,7 @@ monitor_child_preauth(Authctxt *_authctx - } - - /* Drain any buffered messages from the child */ -- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) -+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) - ; - - if (!authctxt->valid) -@@ -1161,6 +1161,10 @@ mm_answer_keyallowed(int sock, Buffer *m - break; - } - } -+ -+ debug3("%s: key %p is %s", -+ __func__, key, allowed ? "allowed" : "not allowed"); -+ - if (key != NULL) - key_free(key); - -@@ -1182,9 +1186,6 @@ mm_answer_keyallowed(int sock, Buffer *m - xfree(chost); - } - -- debug3("%s: key %p is %s", -- __func__, key, allowed ? "allowed" : "not allowed"); -- - buffer_clear(m); - buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); -diff -up openssh-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 -@@ -707,10 +707,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, - if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || - (tmp2 = dup(pmonitor->m_recvfd)) == -1) { - error("%s: cannot allocate fds for pty", __func__); -- if (tmp1 > 0) -+ if (tmp1 >= 0) - close(tmp1); -- if (tmp2 > 0) -- close(tmp2); -+ /*DEAD CODE if (tmp2 >= 0) -+ close(tmp2);*/ - return 0; - } - close(tmp1); -diff -up openssh-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 -@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr - struct sockaddr_in6 *in6; - u_int16_t *portp; - u_int16_t port; -- socklen_t salen; -+ socklen_t salen = sizeof(struct sockaddr_storage); - int i; - - if (sa == NULL) { -diff -up openssh-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 -@@ -1177,6 +1177,7 @@ packet_read_poll1(void) - case DEATTACK_DETECTED: - packet_disconnect("crc32 compensation attack: " - "network attack detected"); -+ break; - case DEATTACK_DOS_DETECTED: - packet_disconnect("deattack denial of " - "service detected"); -@@ -1684,7 +1685,7 @@ void - packet_write_wait(void) - { - fd_set *setp; -- int ret, ms_remain; -+ int ret, ms_remain = 0; - struct timeval start, timeout, *timeoutp = NULL; - - setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, -diff -up openssh-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 -@@ -65,7 +65,7 @@ static void update_progress_meter(int); - - static time_t start; /* start progress */ - static time_t last_update; /* last progress update */ --static char *file; /* name of the file being transferred */ -+static const char *file; /* name of the file being transferred */ - static off_t end_pos; /* ending position of transfer */ - static off_t cur_pos; /* transfer position as of last refresh */ - static volatile off_t *counter; /* progress counter */ -@@ -247,7 +247,7 @@ update_progress_meter(int ignore) - } - - void --start_progress_meter(char *f, off_t filesize, off_t *ctr) -+start_progress_meter(const char *f, off_t filesize, off_t *ctr) - { - start = last_update = time(NULL); - file = f; -diff -up openssh-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 -@@ -23,5 +23,5 @@ - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - --void start_progress_meter(char *, off_t, off_t *); -+void start_progress_meter(const char *, off_t, off_t *); - void stop_progress_meter(void); -diff -up openssh-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 -@@ -155,7 +155,7 @@ killchild(int signo) - { - if (do_cmd_pid > 1) { - kill(do_cmd_pid, signo ? signo : SIGTERM); -- waitpid(do_cmd_pid, NULL, 0); -+ (void) waitpid(do_cmd_pid, NULL, 0); - } - - if (signo) -diff -up openssh-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 - fatal("%s line %d: Missing subsystem name.", - filename, linenum); - if (!*activep) { -- arg = strdelim(&cp); -+ /*arg =*/ (void) strdelim(&cp); - break; - } - for (i = 0; i < options->num_subsystems; i++) -@@ -1262,8 +1262,9 @@ process_server_config_line(ServerOptions - if (*activep && *charptr == NULL) { - *charptr = tilde_expand_filename(arg, getuid()); - /* increase optional counter */ -- if (intptr != NULL) -- *intptr = *intptr + 1; -+ /* DEAD CODE intptr is still NULL ;) -+ if (intptr != NULL) -+ *intptr = *intptr + 1; */ - } - break; - -diff -up openssh-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 -@@ -147,13 +147,13 @@ notify_setup(void) - static void - notify_parent(void) - { -- if (notify_pipe[1] != -1) -+ if (notify_pipe[1] >= 0) - write(notify_pipe[1], "", 1); - } - static void - notify_prepare(fd_set *readset) - { -- if (notify_pipe[0] != -1) -+ if (notify_pipe[0] >= 0) - FD_SET(notify_pipe[0], readset); - } - static void -@@ -161,8 +161,8 @@ notify_done(fd_set *readset) - { - char c; - -- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) -- while (read(notify_pipe[0], &c, 1) != -1) -+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) -+ while (read(notify_pipe[0], &c, 1) >= 0) - debug2("notify_done: reading"); - } - -@@ -330,7 +330,7 @@ wait_until_can_do_something(fd_set **rea - * If we have buffered data, try to write some of that data - * to the program. - */ -- if (fdin != -1 && buffer_len(&stdin_buffer) > 0) -+ if (fdin >= 0 && buffer_len(&stdin_buffer) > 0) - FD_SET(fdin, *writesetp); - } - notify_prepare(*readsetp); -@@ -470,7 +470,7 @@ process_output(fd_set *writeset) - int len; - - /* Write buffered data to program stdin. */ -- if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { -+ if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) { - data = buffer_ptr(&stdin_buffer); - dlen = buffer_len(&stdin_buffer); - len = write(fdin, data, dlen); -@@ -583,7 +583,7 @@ server_loop(pid_t pid, int fdin_arg, int - set_nonblock(fdin); - set_nonblock(fdout); - /* we don't have stderr for interactive terminal sessions, see below */ -- if (fderr != -1) -+ if (fderr >= 0) - set_nonblock(fderr); - - if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) -@@ -607,7 +607,7 @@ server_loop(pid_t pid, int fdin_arg, int - max_fd = MAX(connection_in, connection_out); - max_fd = MAX(max_fd, fdin); - max_fd = MAX(max_fd, fdout); -- if (fderr != -1) -+ if (fderr >= 0) - max_fd = MAX(max_fd, fderr); - #endif - -@@ -637,7 +637,7 @@ server_loop(pid_t pid, int fdin_arg, int - * If we have received eof, and there is no more pending - * input data, cause a real eof by closing fdin. - */ -- if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { -+ if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) { - if (fdin != fdout) - close(fdin); - else -@@ -735,15 +735,15 @@ server_loop(pid_t pid, int fdin_arg, int - buffer_free(&stderr_buffer); - - /* Close the file descriptors. */ -- if (fdout != -1) -+ if (fdout >= 0) - close(fdout); - fdout = -1; - fdout_eof = 1; -- if (fderr != -1) -+ if (fderr >= 0) - close(fderr); - fderr = -1; - fderr_eof = 1; -- if (fdin != -1) -+ if (fdin >= 0) - close(fdin); - fdin = -1; - -@@ -937,7 +937,7 @@ server_input_window_size(int type, u_int - - debug("Window change received."); - packet_check_eom(); -- if (fdin != -1) -+ if (fdin >= 0) - pty_change_window_size(fdin, row, col, xpixel, ypixel); - } - -@@ -990,7 +990,7 @@ server_request_tun(void) - } - - tun = packet_get_int(); -- if (forced_tun_device != -1) { -+ if (forced_tun_device >= 0) { - if (tun != SSH_TUNID_ANY && forced_tun_device != tun) - goto done; - tun = forced_tun_device; -diff -up openssh-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 -@@ -149,7 +149,7 @@ get_msg(struct sftp_conn *conn, Buffer * - } - - static void --send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, -+send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s, - u_int len) - { - Buffer msg; -@@ -165,7 +165,7 @@ send_string_request(struct sftp_conn *co - - static void - send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, -- char *s, u_int len, Attrib *a) -+ const char *s, u_int len, Attrib *a) - { - Buffer msg; - -@@ -422,7 +422,7 @@ sftp_proto_version(struct sftp_conn *con - } - - int --do_close(struct sftp_conn *conn, char *handle, u_int handle_len) -+do_close(struct sftp_conn *conn, const char *handle, u_int handle_len) - { - u_int id, status; - Buffer msg; -@@ -447,7 +447,7 @@ do_close(struct sftp_conn *conn, char *h - - - static int --do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, -+do_lsreaddir(struct sftp_conn *conn, const char *path, int printflag, - SFTP_DIRENT ***dir) - { - Buffer msg; -@@ -571,7 +571,7 @@ do_lsreaddir(struct sftp_conn *conn, cha - } - - int --do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir) -+do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir) - { - return(do_lsreaddir(conn, path, 0, dir)); - } -@@ -589,7 +589,7 @@ void free_sftp_dirents(SFTP_DIRENT **s) - } - - int --do_rm(struct sftp_conn *conn, char *path) -+do_rm(struct sftp_conn *conn, const char *path) - { - u_int status, id; - -@@ -604,7 +604,7 @@ do_rm(struct sftp_conn *conn, char *path - } - - int --do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) -+do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int printflag) - { - u_int status, id; - -@@ -620,7 +620,7 @@ do_mkdir(struct sftp_conn *conn, char *p - } - - int --do_rmdir(struct sftp_conn *conn, char *path) -+do_rmdir(struct sftp_conn *conn, const char *path) - { - u_int status, id; - -@@ -636,7 +636,7 @@ do_rmdir(struct sftp_conn *conn, char *p - } - - Attrib * --do_stat(struct sftp_conn *conn, char *path, int quiet) -+do_stat(struct sftp_conn *conn, const char *path, int quiet) - { - u_int id; - -@@ -650,7 +650,7 @@ do_stat(struct sftp_conn *conn, char *pa - } - - Attrib * --do_lstat(struct sftp_conn *conn, char *path, int quiet) -+do_lstat(struct sftp_conn *conn, const char *path, int quiet) - { - u_int id; - -@@ -684,7 +684,7 @@ do_fstat(struct sftp_conn *conn, char *h - #endif - - int --do_setstat(struct sftp_conn *conn, char *path, Attrib *a) -+do_setstat(struct sftp_conn *conn, const char *path, Attrib *a) - { - u_int status, id; - -@@ -701,7 +701,7 @@ do_setstat(struct sftp_conn *conn, char - } - - int --do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, -+do_fsetstat(struct sftp_conn *conn, const char *handle, u_int handle_len, - Attrib *a) - { - u_int status, id; -@@ -718,12 +718,12 @@ do_fsetstat(struct sftp_conn *conn, char - } - - char * --do_realpath(struct sftp_conn *conn, char *path) -+do_realpath(struct sftp_conn *conn, const char *path) - { - Buffer msg; - u_int type, expected_id, count, id; - 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 - } - - int --do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -800,7 +800,7 @@ do_rename(struct sftp_conn *conn, char * - } - - int --do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -833,7 +833,7 @@ do_hardlink(struct sftp_conn *conn, char - } - - int --do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) -+do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) - { - Buffer msg; - u_int status, id; -@@ -984,7 +984,7 @@ send_read_request(struct sftp_conn *conn - } - - int --do_download(struct sftp_conn *conn, char *remote_path, char *local_path, -+do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path, - Attrib *a, int pflag) - { - Attrib junk; -@@ -1223,7 +1223,7 @@ do_download(struct sftp_conn *conn, char - } - - static int --download_dir_internal(struct sftp_conn *conn, char *src, char *dst, -+download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, - Attrib *dirattrib, int pflag, int printflag, int depth) - { - int i, ret = 0; -@@ -1313,7 +1313,7 @@ download_dir_internal(struct sftp_conn * - } - - int --download_dir(struct sftp_conn *conn, char *src, char *dst, -+download_dir(struct sftp_conn *conn, const char *src, const char *dst, - Attrib *dirattrib, int pflag, int printflag) - { - char *src_canon; -@@ -1331,7 +1331,7 @@ download_dir(struct sftp_conn *conn, cha - } - - int --do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, -+do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path, - int pflag) - { - int local_fd; -@@ -1514,7 +1514,7 @@ do_upload(struct sftp_conn *conn, char * - } - - static int --upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, -+upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, - int pflag, int printflag, int depth) - { - int ret = 0, status; -@@ -1605,7 +1605,7 @@ upload_dir_internal(struct sftp_conn *co - } - - int --upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag, -+upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int printflag, - int pflag) - { - char *dst_canon; -@@ -1622,7 +1622,7 @@ upload_dir(struct sftp_conn *conn, char - } - - char * --path_append(char *p1, char *p2) -+path_append(const char *p1, const char *p2) - { - char *ret; - size_t len = strlen(p1) + strlen(p2) + 2; -diff -up openssh-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 -@@ -56,49 +56,49 @@ struct sftp_conn *do_init(int, int, u_in - u_int sftp_proto_version(struct sftp_conn *); - - /* Close file referred to by 'handle' */ --int do_close(struct sftp_conn *, char *, u_int); -+int do_close(struct sftp_conn *, const char *, u_int); - - /* Read contents of 'path' to NULL-terminated array 'dir' */ --int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***); -+int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***); - - /* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */ - void free_sftp_dirents(SFTP_DIRENT **); - - /* Delete file 'path' */ --int do_rm(struct sftp_conn *, char *); -+int do_rm(struct sftp_conn *, const char *); - - /* Create directory 'path' */ --int do_mkdir(struct sftp_conn *, char *, Attrib *, int); -+int do_mkdir(struct sftp_conn *, const char *, Attrib *, int); - - /* Remove directory 'path' */ --int do_rmdir(struct sftp_conn *, char *); -+int do_rmdir(struct sftp_conn *, const char *); - - /* Get file attributes of 'path' (follows symlinks) */ --Attrib *do_stat(struct sftp_conn *, char *, int); -+Attrib *do_stat(struct sftp_conn *, const char *, int); - - /* Get file attributes of 'path' (does not follow symlinks) */ --Attrib *do_lstat(struct sftp_conn *, char *, int); -+Attrib *do_lstat(struct sftp_conn *, const char *, int); - - /* Set file attributes of 'path' */ --int do_setstat(struct sftp_conn *, char *, Attrib *); -+int do_setstat(struct sftp_conn *, const char *, Attrib *); - - /* Set file attributes of open file 'handle' */ --int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); -+int do_fsetstat(struct sftp_conn *, const char *, u_int, Attrib *); - - /* Canonicalise 'path' - caller must free result */ --char *do_realpath(struct sftp_conn *, char *); -+char *do_realpath(struct sftp_conn *, const char *); - - /* Get statistics for filesystem hosting file at "path" */ - int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); - - /* Rename 'oldpath' to 'newpath' */ --int do_rename(struct sftp_conn *, char *, char *); -+int do_rename(struct sftp_conn *, const char *, const char *); - - /* Link 'oldpath' to 'newpath' */ --int do_hardlink(struct sftp_conn *, char *, char *); -+int do_hardlink(struct sftp_conn *, const char *, const char *); - --/* Rename 'oldpath' to 'newpath' */ --int do_symlink(struct sftp_conn *, char *, char *); -+/* Symlink 'oldpath' to 'newpath' */ -+int do_symlink(struct sftp_conn *, const char *, const char *); - - /* XXX: add callbacks to do_download/do_upload so we can do progress meter */ - -@@ -106,27 +106,27 @@ int do_symlink(struct sftp_conn *, char - * Download 'remote_path' to 'local_path'. Preserve permissions and times - * if 'pflag' is set - */ --int do_download(struct sftp_conn *, char *, char *, Attrib *, int); -+int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int); - - /* - * Recursively download 'remote_directory' to 'local_directory'. Preserve - * times if 'pflag' is set - */ --int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int); -+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, int); - - /* - * Upload 'local_path' to 'remote_path'. Preserve permissions and times - * if 'pflag' is set - */ --int do_upload(struct sftp_conn *, char *, char *, int); -+int do_upload(struct sftp_conn *, const char *, const char *, int); - - /* - * Recursively upload 'local_directory' to 'remote_directory'. Preserve - * times if 'pflag' is set - */ --int upload_dir(struct sftp_conn *, char *, char *, int, int); -+int upload_dir(struct sftp_conn *, const char *, const char *, int, int); - - /* Concatenate paths, taking care of slashes. Caller must free result. */ --char *path_append(char *, char *); -+char *path_append(const char *, const char *); - - #endif -diff -up openssh-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 -@@ -1147,8 +1147,8 @@ main(int ac, char **av) - sanitise_stdfd(); - - /* drop */ -- setegid(getgid()); -- setgid(getgid()); -+ (void) setegid(getgid()); -+ (void) setgid(getgid()); - - #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) - /* Disable ptrace on Linux without sgid bit */ -diff -up openssh-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) - if (getuid() == 0 || geteuid() == 0) - privsep_preauth_child(); - setproctitle("%s", "[net]"); -- if (box != NULL) -+ if (box != NULL) { - ssh_sandbox_child(box); -+ xfree(box); -+ } - - return 0; - } -@@ -1302,6 +1304,9 @@ server_accept_loop(int *sock_in, int *so - if (num_listen_socks < 0) - break; - } -+ -+ if (fdset != NULL) -+ xfree(fdset); - } - - -@@ -1774,7 +1779,7 @@ main(int ac, char **av) - - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ -- chdir("/"); -+ (void) chdir("/"); - - /* ignore SIGPIPE */ - signal(SIGPIPE, SIG_IGN); diff --git a/openssh/patches/openssh-5.9p1-entropy.patch b/openssh/patches/openssh-5.9p1-entropy.patch deleted file mode 100644 index b3dec46..0000000 --- a/openssh/patches/openssh-5.9p1-entropy.patch +++ /dev/null @@ -1,251 +0,0 @@ -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) - memset(buf, '\0', sizeof(buf)); - - #endif /* OPENSSL_PRNG_ONLY */ -+#ifdef __linux__ -+ linux_seed(); -+#endif /* __linux__ */ - if (RAND_status() != 1) - fatal("PRNG is not seeded"); - } -diff -up openssh-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 -@@ -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 - --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 -@@ -0,0 +1,59 @@ -+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ -+ -+/* -+ * Copyright (c) 2011 Jan F. Chadima jchadima@redhat.com -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/* -+ * Linux-specific portability code - prng support -+ */ -+ -+#include "includes.h" -+ -+#include <errno.h> -+#include <stdarg.h> -+#include <string.h> -+#include <stdio.h> -+#include <openssl/rand.h> -+ -+#include "log.h" -+#include "xmalloc.h" -+#include "servconf.h" -+#include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" -+ -+void -+linux_seed(void) -+{ -+ int len; -+ char *env = getenv("SSH_USE_STRONG_RNG"); -+ char *random = "/dev/random"; -+ size_t ienv, randlen = 6; -+ -+ if (!env || !strcmp(env, "0")) -+ random = "/dev/urandom"; -+ else if ((ienv = atoi(env)) > 6) -+ randlen = ienv; -+ -+ errno = 0; -+ if ((len = RAND_load_file(random, randlen)) != randlen) { -+ if (errno) -+ fatal ("cannot read from %s, %s", random, strerror(errno)); -+ else -+ fatal ("EOF reading %s", random); -+ } -+} -diff -up openssh-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 -+.It Ev SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. - .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 -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-add 1 , -diff -up openssh-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 ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-add 1 , -diff -up openssh-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. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh SEE ALSO - .Xr ssh 1 , - .Xr ssh-keygen 1 , -diff -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 . -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.It Ev SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh FILES - .Bl -tag -width Ds -compact - .It Pa ~/.rhosts -diff -up openssh-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. - .El -+.Sh ENVIRONMENT -+.Bl -tag -width Ds -compact -+.Pp -+.It Pa SSH_USE_STRONG_RNG -+The reseeding of the OpenSSL random generator is usually done from -+.Cm /dev/urandom . -+If the -+.Cm SSH_USE_STRONG_RNG -+environment variable is set to value other than -+.Cm 0 -+the OpenSSL random generator is reseeded from -+.Cm /dev/random . -+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. -+Minimum is 6 bytes. -+This setting is not recommended on the computers without the hardware -+random generator because insufficient entropy causes the connection to -+be blocked until enough entropy is available. -+.El - .Sh IPV6 - IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. - .Sh SEE ALSO diff --git a/openssh/patches/openssh-5.9p1-kuserok.patch b/openssh/patches/openssh-5.9p1-kuserok.patch deleted file mode 100644 index 11f38a5..0000000 --- a/openssh/patches/openssh-5.9p1-kuserok.patch +++ /dev/null @@ -1,167 +0,0 @@ -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 @@ - - extern ServerOptions options; - -+int -+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client) -+{ -+ if (options.use_kuserok) -+ return krb5_kuserok(krb5_ctx, krb5_user, client); -+ else { -+ char kuser[65]; -+ -+ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) -+ return 0; -+ return strcmp(kuser, client) == 0; -+ } -+} -+ - static int - krb5_init(void *context) - { -@@ -146,7 +160,7 @@ auth_krb5_password(Authctxt *authctxt, c - if (problem) - goto out; - -- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { -+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { - problem = -1; - goto out; - } -diff -up openssh-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 -@@ -68,6 +68,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr - int); - - static krb5_context krb_context = NULL; -+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *); - - /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ - -@@ -115,7 +116,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - /* NOTE: .k5login and .k5users must opened as root, not the user, - * because if they are on a krb5-protected filesystem, user credentials - * to access these files aren't available yet. */ -- if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) { -+ if (ssh_krb5_kuserok(krb_context, princ, luser) && k5login_exists) { - retval = 1; - logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", - luser, (char *)client->displayname.value); -diff -up openssh-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; - options->ip_qos_interactive = -1; - options->ip_qos_bulk = -1; -+ options->use_kuserok = -1; - } - - void -@@ -291,6 +292,8 @@ fill_default_server_options(ServerOption - options->ip_qos_bulk = IPTOS_THROUGHPUT; - if (options->show_patchlevel == -1) - options->show_patchlevel = 0; -+ if (options->use_kuserok == -1) -+ options->use_kuserok = 1; - - /* Turn privilege separation on by default */ - if (use_privsep == -1) -@@ -317,7 +320,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, -+ sKerberosGetAFSToken, sKerberosUseKuserok, - sKerberosTgtPassing, sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, -@@ -388,11 +391,13 @@ static struct { - #else - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, - #endif -+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, - #else - { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, - { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, -+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, - #endif - { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, - { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1371,6 +1376,10 @@ process_server_config_line(ServerOptions - *activep = value; - break; - -+ case sKerberosUseKuserok: -+ intptr = &options->use_kuserok; -+ goto parse_flag; -+ - case sPermitOpen: - arg = strdelim(&cp); - if (!arg || *arg == '\0') -@@ -1580,6 +1589,7 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(max_authtries); - M_CP_INTOPT(ip_qos_interactive); - M_CP_INTOPT(ip_qos_bulk); -+ M_CP_INTOPT(use_kuserok); - - /* See comment in servconf.h */ - COPY_MATCH_STRING_OPTS(); -@@ -1816,6 +1826,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); -+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-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 { - - int num_permitted_opens; - -+ int use_kuserok; - 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 - file on logout. - The default is - .Dq yes . -+.It Cm KerberosUseKuserok -+Specifies whether to look at .k5login file for user's aliases. -+The default is -+.Dq yes . - .It Cm KexAlgorithms - Specifies the available KEX (Key Exchange) algorithms. - Multiple algorithms must be comma-separated. -@@ -746,6 +750,7 @@ Available keywords are - .Cm HostbasedUsesNameFromPacketOnly , - .Cm KbdInteractiveAuthentication , - .Cm KerberosAuthentication , -+.Cm KerberosUseKuserok , - .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-5.9p1-mls.patch b/openssh/patches/openssh-5.9p1-mls.patch deleted file mode 100644 index 1163949..0000000 --- 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 <selinux/selinux.h> - #include <selinux/flask.h> -+#include <selinux/context.h> - #include <selinux/get_context_list.h> -+#include <selinux/get_default_type.h> -+#include <selinux/av_permissions.h> -+ -+#ifdef HAVE_LINUX_AUDIT -+#include <libaudit.h> -+#include <unistd.h> -+#endif - - #ifndef SSH_SELINUX_UNCONFINED_TYPE - # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" -@@ -51,6 +59,149 @@ extern Authctxt *the_authctxt; - extern int inetd_flag; - extern int rexeced_flag; - -+/* Send audit message */ -+static int -+send_audit_message(int success, security_context_t default_context, -+ security_context_t selected_context) -+{ -+ int rc=0; -+#ifdef HAVE_LINUX_AUDIT -+ char *msg = NULL; -+ int audit_fd = audit_open(); -+ security_context_t default_raw=NULL; -+ security_context_t selected_raw=NULL; -+ rc = -1; -+ if (audit_fd < 0) { -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || -+ errno == EAFNOSUPPORT) -+ return 0; /* No audit support in kernel */ -+ error("Error connecting to audit system."); -+ return rc; -+ } -+ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { -+ error("Error translating default context."); -+ default_raw = NULL; -+ } -+ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { -+ error("Error translating selected context."); -+ selected_raw = NULL; -+ } -+ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s", -+ default_raw ? default_raw : (default_context ? default_context: "?"), -+ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) { -+ error("Error allocating memory."); -+ goto out; -+ } -+ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, -+ msg, NULL, NULL, NULL, success) <= 0) { -+ error("Error sending audit message."); -+ goto out; -+ } -+ rc = 0; -+ out: -+ free(msg); -+ freecon(default_raw); -+ freecon(selected_raw); -+ close(audit_fd); -+#endif -+ return rc; -+} -+ -+static int -+mls_range_allowed(security_context_t src, security_context_t dst) -+{ -+ struct av_decision avd; -+ int retval; -+ unsigned int bit = CONTEXT__CONTAINS; -+ -+ debug("%s: src:%s dst:%s", __func__, src, dst); -+ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); -+ if (retval || ((bit & avd.allowed) != bit)) -+ return 0; -+ -+ return 1; -+} -+ -+static int -+get_user_context(const char *sename, const char *role, const char *lvl, -+ security_context_t *sc) { -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) { -+ /* User may have requested a level completely outside of his -+ allowed range. We get a context just for auditing as the -+ range check below will certainly fail for default context. */ -+#endif -+ if (get_default_context(sename, NULL, sc) != 0) { -+ *sc = NULL; -+ return -1; -+ } -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ } -+#endif -+ if (role != NULL && role[0]) { -+ context_t con; -+ char *type=NULL; -+ if (get_default_type(role, &type) != 0) { -+ error("get_default_type: failed to get default type for '%s'", -+ role); -+ goto out; -+ } -+ con = context_new(*sc); -+ if (!con) { -+ goto out; -+ } -+ context_role_set(con, role); -+ context_type_set(con, type); -+ freecon(*sc); -+ *sc = strdup(context_str(con)); -+ context_free(con); -+ if (!*sc) -+ return -1; -+ } -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ if (lvl != NULL && lvl[0]) { -+ /* verify that the requested range is obtained */ -+ context_t con; -+ security_context_t obtained_raw; -+ security_context_t requested_raw; -+ con = context_new(*sc); -+ if (!con) { -+ goto out; -+ } -+ context_range_set(con, lvl); -+ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) { -+ context_free(con); -+ goto out; -+ } -+ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) { -+ freecon(obtained_raw); -+ context_free(con); -+ goto out; -+ } -+ -+ debug("get_user_context: obtained context '%s' requested context '%s'", -+ obtained_raw, requested_raw); -+ if (strcmp(obtained_raw, requested_raw)) { -+ /* set the context to the real requested one but fail */ -+ freecon(requested_raw); -+ freecon(obtained_raw); -+ freecon(*sc); -+ *sc = strdup(context_str(con)); -+ context_free(con); -+ return -1; -+ } -+ freecon(requested_raw); -+ freecon(obtained_raw); -+ context_free(con); -+ } -+#endif -+ return 0; -+ out: -+ freecon(*sc); -+ *sc = NULL; -+ return -1; -+} -+ - static void - ssh_selinux_get_role_level(char **role, const char **level) - { -@@ -69,14 +220,15 @@ ssh_selinux_get_role_level(char **role, - } - - /* Return the default security context for the given username */ --static security_context_t --ssh_selinux_getctxbyname(char *pwname) -+static int -+ssh_selinux_getctxbyname(char *pwname, -+ security_context_t *default_sc, security_context_t *user_sc) - { -- security_context_t sc = NULL; - char *sename, *lvl; - char *role; - const char *reqlvl; - int r = 0; -+ context_t con = NULL; - - ssh_selinux_get_role_level(&role, &reqlvl); - -@@ -87,37 +239,62 @@ ssh_selinux_getctxbyname(char *pwname) - } - #else - sename = pwname; -- lvl = NULL; -+ lvl = ""; - #endif - - if (r == 0) { - #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -- if (role != NULL && role[0]) -- r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc); -- else -- r = get_default_context_with_level(sename, lvl, NULL, &sc); -+ r = get_default_context_with_level(sename, lvl, NULL, default_sc); - #else -- if (role != NULL && role[0]) -- r = get_default_context_with_role(sename, role, NULL, &sc); -- else -- r = get_default_context(sename, NULL, &sc); -+ r = get_default_context(sename, NULL, default_sc); - #endif - } - -- if (r != 0) { -- switch (security_getenforce()) { -- case -1: -- fatal("%s: ssh_selinux_getctxbyname: " -- "security_getenforce() failed", __func__); -- case 0: -- error("%s: Failed to get default SELinux security " -- "context for %s", __func__, pwname); -- break; -- default: -- fatal("%s: Failed to get default SELinux security " -- "context for %s (in enforcing mode)", -- __func__, pwname); -+ if (r == 0) { -+ /* If launched from xinetd, we must use current level */ -+ if (inetd_flag && !rexeced_flag) { -+ security_context_t sshdsc=NULL; -+ -+ if (getcon_raw(&sshdsc) < 0) -+ fatal("failed to allocate security context"); -+ -+ if ((con=context_new(sshdsc)) == NULL) -+ fatal("failed to allocate selinux context"); -+ reqlvl = context_range_get(con); -+ freecon(sshdsc); -+ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0) -+ /* we actually don't change level */ -+ reqlvl = ""; -+ -+ debug("%s: current connection level '%s'", __func__, reqlvl); - } -+ -+ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { -+ r = get_user_context(sename, role, reqlvl, user_sc); -+ -+ if (r == 0 && reqlvl != NULL && reqlvl[0]) { -+ security_context_t default_level_sc = *default_sc; -+ if (role != NULL && role[0]) { -+ if (get_user_context(sename, role, lvl, &default_level_sc) < 0) -+ default_level_sc = *default_sc; -+ } -+ /* verify that the requested range is contained in the user range */ -+ if (mls_range_allowed(default_level_sc, *user_sc)) { -+ logit("permit MLS level %s (user range %s)", reqlvl, lvl); -+ } else { -+ r = -1; -+ error("deny MLS level %s (user range %s)", reqlvl, lvl); -+ } -+ if (default_level_sc != *default_sc) -+ freecon(default_level_sc); -+ } -+ } else { -+ *user_sc = *default_sc; -+ } -+ } -+ if (r != 0) { -+ error("%s: Failed to get default SELinux security " -+ "context for %s", __func__, pwname); - } - - #ifdef HAVE_GETSEUSERBYNAME -@@ -126,8 +303,12 @@ ssh_selinux_getctxbyname(char *pwname) - if (lvl != NULL) - xfree(lvl); - #endif -- -- return (sc); -+ if (role != NULL) -+ xfree(role); -+ if (con) -+ context_free(con); -+ -+ return (r); - } - - /* Setup environment variables for pam_selinux */ -@@ -165,6 +346,8 @@ void - ssh_selinux_setup_exec_context(char *pwname) - { - security_context_t user_ctx = NULL; -+ int r = 0; -+ security_context_t default_ctx = NULL; - - if (!ssh_selinux_enabled()) - return; -@@ -189,22 +372,45 @@ ssh_selinux_setup_exec_context(char *pwn - - debug3("%s: setting execution context", __func__); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -- if (setexeccon(user_ctx) != 0) { -+ r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); -+ if (r >= 0) { -+ r = setexeccon(user_ctx); -+ if (r < 0) { -+ error("%s: Failed to set SELinux execution context %s for %s", -+ __func__, user_ctx, pwname); -+ } -+#ifdef HAVE_SETKEYCREATECON -+ else if (setkeycreatecon(user_ctx) < 0) { -+ error("%s: Failed to set SELinux keyring creation context %s for %s", -+ __func__, user_ctx, pwname); -+ } -+#endif -+ } -+ if (user_ctx == NULL) { -+ user_ctx = default_ctx; -+ } -+ if (r < 0 || user_ctx != default_ctx) { -+ /* audit just the case when user changed a role or there was -+ a failure */ -+ send_audit_message(r >= 0, default_ctx, user_ctx); -+ } -+ if (r < 0) { - switch (security_getenforce()) { - case -1: - fatal("%s: security_getenforce() failed", __func__); - case 0: -- error("%s: Failed to set SELinux execution " -- "context for %s", __func__, pwname); -+ error("%s: SELinux failure. Continuing in permissive mode.", -+ __func__); - break; - default: -- fatal("%s: Failed to set SELinux execution context " -- "for %s (in enforcing mode)", __func__, pwname); -+ fatal("%s: SELinux failure. Aborting connection.", -+ __func__); - } - } -- if (user_ctx != NULL) -+ if (user_ctx != NULL && user_ctx != default_ctx) - freecon(user_ctx); -+ if (default_ctx != NULL) -+ freecon(default_ctx); - - debug3("%s: done", __func__); - } -@@ -222,7 +428,10 @@ ssh_selinux_setup_pty(char *pwname, cons - - debug3("%s: setting TTY context on %s", __func__, tty); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -+ if (getexeccon(&user_ctx) < 0) { -+ error("%s: getexeccon: %s", __func__, strerror(errno)); -+ goto out; -+ } - - /* XXX: should these calls fatal() upon failure in enforcing mode? */ - -diff -up openssh-5.9p0/sshd.c.mls openssh-5.9p0/sshd.c ---- openssh-5.9p0/sshd.c.mls 2011-08-30 12:29:22.663149706 +0200 -+++ openssh-5.9p0/sshd.c 2011-08-30 12:29:29.524024777 +0200 -@@ -2082,6 +2082,9 @@ main(int ac, char **av) - restore_uid(); - } - #endif -+#ifdef WITH_SELINUX -+ ssh_selinux_setup_exec_context(authctxt->pw->pw_name); -+#endif - #ifdef USE_PAM - if (options.use_pam) { - do_pam_setcred(1); diff --git a/openssh/patches/openssh-5.9p1-role.patch b/openssh/patches/openssh-5.9p1-role.patch deleted file mode 100644 index 8a26bdf..0000000 --- a/openssh/patches/openssh-5.9p1-role.patch +++ /dev/null @@ -1,613 +0,0 @@ -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 -@@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt) - { - u_int ulen; - char *user, *style = NULL; -+#ifdef WITH_SELINUX -+ char *role=NULL; -+#endif - - /* Get the name of the user that we wish to log in as. */ - packet_read_expect(SSH_CMSG_USER); -@@ -392,11 +395,24 @@ do_authentication(Authctxt *authctxt) - user = packet_get_cstring(&ulen); - packet_check_eom(); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = '\0'; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = '\0'; -+#ifdef WITH_SELINUX -+ else -+ if (role && (style = strchr(role, ':')) != NULL) -+ *style++ = '\0'; -+#endif - - authctxt->user = user; - authctxt->style = style; -+#ifdef WITH_SELINUX -+ authctxt->role = role; -+#endif - - /* Verify that the user is a valid user. */ - if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) -diff -up openssh-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 -@@ -260,6 +260,7 @@ input_gssapi_mic(int type, u_int32_t ple - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - int authenticated = 0; -+ char *micuser; - Buffer b; - gss_buffer_desc mic, gssbuf; - u_int len; -@@ -272,7 +273,13 @@ input_gssapi_mic(int type, u_int32_t ple - mic.value = packet_get_string(&len); - mic.length = len; - -- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, -+#ifdef WITH_SELINUX -+ if (authctxt->role && (strlen(authctxt->role) > 0)) -+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); -+ else -+#endif -+ micuser = authctxt->user; -+ ssh_gssapi_buildmic(&b, micuser, authctxt->service, - "gssapi-with-mic"); - - gssbuf.value = buffer_ptr(&b); -@@ -284,6 +291,8 @@ input_gssapi_mic(int type, u_int32_t ple - logit("GSSAPI MIC check failed"); - - buffer_free(&b); -+ if (micuser != authctxt->user) -+ xfree(micuser); - xfree(mic.value); - - authctxt->postponed = 0; -diff -up openssh-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 -@@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt) - buffer_put_string(&b, session_id2, session_id2_len); - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); -+#ifdef WITH_SELINUX -+ if (authctxt->role) { -+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); -+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); -+ buffer_put_char(&b, '/'); -+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); -+ } else -+#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, "hostbased"); - buffer_put_string(&b, pkalg, alen); -diff -up openssh-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 -@@ -121,7 +121,15 @@ userauth_pubkey(Authctxt *authctxt) - } - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); -+#ifdef WITH_SELINUX -+ if (authctxt->role) { -+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); -+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); -+ buffer_put_char(&b, '/'); -+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); -+ } else -+#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, - datafellows & SSH_BUG_PKSERVICE ? - "ssh-userauth" : -diff -up openssh-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); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = 0; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = 0; - -@@ -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 -+ } - 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 -@@ -148,6 +148,9 @@ int mm_answer_sign(int, Buffer *); - int mm_answer_pwnamallow(int, Buffer *); - int mm_answer_auth2_read_banner(int, Buffer *); - int mm_answer_authserv(int, Buffer *); -+#ifdef WITH_SELINUX -+int mm_answer_authrole(int, Buffer *); -+#endif - int mm_answer_authpassword(int, Buffer *); - int mm_answer_bsdauthquery(int, Buffer *); - int mm_answer_bsdauthrespond(int, Buffer *); -@@ -231,6 +234,9 @@ struct mon_table mon_dispatch_proto20[] - {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, - {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, - {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, -+#ifdef WITH_SELINUX -+ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -+#endif - {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, - {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, - #ifdef USE_PAM -@@ -819,6 +825,9 @@ mm_answer_pwnamallow(int sock, Buffer *m - else { - /* Allow service/style information on the auth context */ - monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); -+#ifdef WITH_SELINUX -+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); -+#endif - monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); - } - #ifdef USE_PAM -@@ -862,6 +871,25 @@ mm_answer_authserv(int sock, Buffer *m) - return (0); - } - -+#ifdef WITH_SELINUX -+int -+mm_answer_authrole(int sock, Buffer *m) -+{ -+ monitor_permit_authentications(1); -+ -+ authctxt->role = buffer_get_string(m, NULL); -+ debug3("%s: role=%s", -+ __func__, authctxt->role); -+ -+ if (strlen(authctxt->role) == 0) { -+ xfree(authctxt->role); -+ authctxt->role = NULL; -+ } -+ -+ return (0); -+} -+#endif -+ - int - mm_answer_authpassword(int sock, Buffer *m) - { -@@ -1227,7 +1255,7 @@ static int - monitor_valid_userblob(u_char *data, u_int datalen) - { - Buffer b; -- char *p; -+ char *p, *r; - u_int len; - int fail = 0; - -@@ -1253,6 +1281,8 @@ monitor_valid_userblob(u_char *data, u_i - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) - fail++; - p = buffer_get_string(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) -+ *r = '\0'; - if (strcmp(authctxt->user, p) != 0) { - logit("wrong user name passed to monitor: expected %s != %.100s", - authctxt->user, p); -@@ -1284,7 +1314,7 @@ monitor_valid_hostbasedblob(u_char *data - char *chost) - { - Buffer b; -- char *p; -+ char *p, *r; - u_int len; - int fail = 0; - -@@ -1301,6 +1331,8 @@ monitor_valid_hostbasedblob(u_char *data - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) - fail++; - p = buffer_get_string(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) -+ *r = '\0'; - if (strcmp(authctxt->user, p) != 0) { - logit("wrong user name passed to monitor: expected %s != %.100s", - authctxt->user, p); -diff -up openssh-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 -@@ -31,6 +31,9 @@ - enum monitor_reqtype { - MONITOR_REQ_MODULI, MONITOR_ANS_MODULI, - MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, -+#ifdef WITH_SELINUX -+ MONITOR_REQ_AUTHROLE, -+#endif - MONITOR_REQ_SIGN, MONITOR_ANS_SIGN, - MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM, - MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER, -diff -up openssh-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 -@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char * - buffer_free(&m); - } - -+/* Inform the privileged process about role */ -+ -+#ifdef WITH_SELINUX -+void -+mm_inform_authrole(char *role) -+{ -+ Buffer m; -+ -+ debug3("%s entering", __func__); -+ -+ buffer_init(&m); -+ buffer_put_cstring(&m, role ? role : ""); -+ -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); -+ -+ buffer_free(&m); -+} -+#endif -+ - /* Do the password authentication */ - int - mm_auth_password(Authctxt *authctxt, char *password) -diff -up openssh-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 -@@ -42,6 +42,9 @@ int mm_is_monitor(void); - DH *mm_choose_dh(int, int, int); - int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); - void mm_inform_authserv(char *, char *); -+#ifdef WITH_SELINUX -+void mm_inform_authrole(char *); -+#endif - struct passwd *mm_getpwnamallow(const char *); - char *mm_auth2_read_banner(void); - int mm_auth_password(struct Authctxt *, char *); -diff -up openssh-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 -@@ -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 - --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 @@ - - #include "log.h" - #include "xmalloc.h" -+#include "servconf.h" - #include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" - - #ifdef WITH_SELINUX - #include <selinux/selinux.h> -@@ -42,41 +46,63 @@ - # 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; - -- if (enabled == -1) { -- enabled = (is_selinux_enabled() == 1); -- debug("SELinux support %s", enabled ? "enabled" : "disabled"); -+static void -+ssh_selinux_get_role_level(char **role, const char **level) -+{ -+ *role = NULL; -+ *level = NULL; -+ if (the_authctxt) { -+ if (the_authctxt->role != NULL) { -+ char *slash; -+ *role = xstrdup(the_authctxt->role); -+ if ((slash = strchr(*role, '/')) != NULL) { -+ *slash = '\0'; -+ *level = slash + 1; -+ } -+ } - } -- -- return (enabled); - } - - /* Return the default security context for the given username */ - static security_context_t - ssh_selinux_getctxbyname(char *pwname) - { -- security_context_t sc; -- char *sename = NULL, *lvl = NULL; -- int r; -+ security_context_t sc = NULL; -+ char *sename, *lvl; -+ char *role; -+ const char *reqlvl; -+ int r = 0; -+ -+ ssh_selinux_get_role_level(&role, &reqlvl); - - #ifdef HAVE_GETSEUSERBYNAME -- if (getseuserbyname(pwname, &sename, &lvl) != 0) -- return NULL; -+ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { -+ sename = NULL; -+ lvl = NULL; -+ } - #else - sename = pwname; - lvl = NULL; - #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); - #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); - #endif -+ } - - if (r != 0) { - switch (security_getenforce()) { -@@ -104,6 +130,36 @@ ssh_selinux_getctxbyname(char *pwname) - return (sc); - } - -+/* Setup environment variables for pam_selinux */ -+static int -+ssh_selinux_setup_pam_variables(void) -+{ -+ const char *reqlvl; -+ char *role; -+ char *use_current; -+ int rv; -+ -+ debug3("%s: setting execution context", __func__); -+ -+ ssh_selinux_get_role_level(&role, &reqlvl); -+ -+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); -+ -+ if (inetd_flag && !rexeced_flag) { -+ use_current = "1"; -+ } else { -+ use_current = ""; -+ rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); -+ } -+ -+ rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); -+ -+ if (role != NULL) -+ xfree(role); -+ -+ return rv; -+} -+ - /* Set the execution context to the default for the specified user */ - void - ssh_selinux_setup_exec_context(char *pwname) -@@ -113,6 +169,24 @@ ssh_selinux_setup_exec_context(char *pwn - if (!ssh_selinux_enabled()) - return; - -+ if (options.use_pam) { -+ /* do not compute context, just setup environment for pam_selinux */ -+ if (ssh_selinux_setup_pam_variables()) { -+ switch (security_getenforce()) { -+ case -1: -+ fatal("%s: security_getenforce() failed", __func__); -+ case 0: -+ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", -+ __func__); -+ break; -+ default: -+ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", -+ __func__); -+ } -+ } -+ return; -+ } -+ - debug3("%s: setting execution context", __func__); - - user_ctx = ssh_selinux_getctxbyname(pwname); -@@ -220,21 +294,6 @@ ssh_selinux_change_context(const char *n - xfree(newctx); - } - --void --ssh_selinux_setfscreatecon(const char *path) --{ -- security_context_t context; -- -- if (!ssh_selinux_enabled()) -- return; -- if (path == NULL) { -- setfscreatecon(NULL); -- return; -- } -- if (matchpathcon(path, 0700, &context) == 0) -- setfscreatecon(context); --} -- - #endif /* WITH_SELINUX */ - - #ifdef LINUX_OOM_ADJUST -diff -up openssh-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 -@@ -0,0 +1,75 @@ -+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ -+ -+/* -+ * Copyright (c) 2005 Daniel Walsh dwalsh@redhat.com -+ * Copyright (c) 2006 Damien Miller djm@openbsd.org -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/* -+ * Linux-specific portability code - just SELinux support at present -+ */ -+ -+#include "includes.h" -+ -+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) -+#include <errno.h> -+#include <stdarg.h> -+#include <string.h> -+#include <stdio.h> -+ -+#include "log.h" -+#include "xmalloc.h" -+#include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" -+ -+#ifdef WITH_SELINUX -+#include <selinux/selinux.h> -+#include <selinux/flask.h> -+#include <selinux/get_context_list.h> -+ -+/* Wrapper around is_selinux_enabled() to log its return value once only */ -+int -+ssh_selinux_enabled(void) -+{ -+ static int enabled = -1; -+ -+ if (enabled == -1) { -+ enabled = (is_selinux_enabled() == 1); -+ debug("SELinux support %s", enabled ? "enabled" : "disabled"); -+ } -+ -+ return (enabled); -+} -+ -+void -+ssh_selinux_setfscreatecon(const char *path) -+{ -+ security_context_t context; -+ -+ if (!ssh_selinux_enabled()) -+ return; -+ if (path == NULL) { -+ setfscreatecon(NULL); -+ return; -+ } -+ if (matchpathcon(path, 0700, &context) == 0) -+ setfscreatecon(context); -+} -+ -+#endif /* WITH_SELINUX */ -+ -+#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ diff --git a/openssh/patches/openssh-5.9p1-vendor.patch b/openssh/patches/openssh-5.9p1-vendor.patch deleted file mode 100644 index 3e63d3b..0000000 --- a/openssh/patches/openssh-5.9p1-vendor.patch +++ /dev/null @@ -1,157 +0,0 @@ -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], - fi - ] - ) -+AC_ARG_ENABLE(vendor-patchlevel, -+ [ --enable-vendor-patchlevel=TAG specify a vendor patch level], -+ [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.]) -+ SSH_VENDOR_PATCHLEVEL="$enableval"], -+ [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.]) -+ SSH_VENDOR_PATCHLEVEL=none]) - - dnl lastlog, [uw]tmpx? detection - dnl NOTE: set the paths in the platform section to avoid the -@@ -4357,6 +4363,7 @@ echo " Translate v4 in v6 hack - echo " BSD Auth support: $BSD_AUTH_MSG" - echo " Random number source: $RAND_MSG" - echo " Privsep sandbox style: $SANDBOX_STYLE" -+echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL" - - echo "" - -diff -up openssh-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 - options->max_authtries = -1; - options->max_sessions = -1; - options->banner = NULL; -+ options->show_patchlevel = -1; - options->use_dns = -1; - options->client_alive_interval = -1; - options->client_alive_count_max = -1; -@@ -300,6 +301,8 @@ fill_default_server_options(ServerOption - options->ip_qos_interactive = IPTOS_LOWDELAY; - if (options->ip_qos_bulk == -1) - options->ip_qos_bulk = IPTOS_THROUGHPUT; -+ if (options->show_patchlevel == -1) -+ options->show_patchlevel = 0; - - /* Turn privilege separation on by default */ - if (use_privsep == -1) -@@ -338,7 +341,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 { - { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, - { "maxsessions", sMaxSessions, SSHCFG_ALL }, - { "banner", sBanner, SSHCFG_ALL }, -+ { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL }, - { "usedns", sUseDNS, SSHCFG_GLOBAL }, - { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, - { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, -@@ -1152,6 +1156,10 @@ process_server_config_line(ServerOptions - multistate_ptr = multistate_privsep; - goto parse_multistate; - -+ case sShowPatchLevel: -+ intptr = &options->show_patchlevel; -+ goto parse_flag; -+ - case sAllowUsers: - while ((arg = strdelim(&cp)) && *arg != '\0') { - if (options->num_allow_users >= MAX_ALLOW_USERS) -@@ -1849,6 +1857,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUseLogin, o->use_login); - dump_cfg_fmtint(sCompression, o->compression); - dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); -+ dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); -diff -up openssh-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 { - int max_authtries; - int max_sessions; - char *banner; /* SSH-2 banner message */ -+ int show_patchlevel; /* Show vendor patch level to clients */ - int use_dns; - int client_alive_interval; /* - * poke the client this often to -diff -up openssh-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 - Defines the number of bits in the ephemeral protocol version 1 - server key. The minimum value is 512, and the default is 1024. - -+ ShowPatchLevel -+ Specifies whether sshd will display the specific patch level of -+ the binary in the server identification string. The patch level -+ is set at compile-time. The default is M-bM-^@M-^\noM-bM-^@M-^]. -+ - StrictModes - Specifies whether sshd(8) should check file modes and ownership - of the user's files and home directory before accepting login. -diff -up openssh-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 - .It Cm ServerKeyBits - Defines the number of bits in the ephemeral protocol version 1 server key. - The minimum value is 512, and the default is 1024. -+.It Cm ShowPatchLevel -+Specifies whether -+.Nm sshd -+will display the patch level of the binary in the identification string. -+The patch level is set at compile-time. -+The default is -+.Dq no . -+This option applies to protocol version 1 only. - .It Cm StrictModes - Specifies whether - .Xr sshd 8 -diff -up openssh-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 --git a/openssh/patches/openssh-6.0p1-entropy.patch b/openssh/patches/openssh-6.0p1-entropy.patch new file mode 100644 index 0000000..79f05f4 --- /dev/null +++ b/openssh/patches/openssh-6.0p1-entropy.patch @@ -0,0 +1,272 @@ +diff -up openssh-6.0p1/entropy.c.entropy openssh-6.0p1/entropy.c +--- openssh-6.0p1/entropy.c.entropy 2012-08-06 20:51:59.131033413 +0200 ++++ openssh-6.0p1/entropy.c 2012-08-06 20:51:59.171033257 +0200 +@@ -237,6 +237,9 @@ seed_rng(void) + memset(buf, '\0', sizeof(buf)); + + #endif /* OPENSSL_PRNG_ONLY */ ++#ifdef __linux__ ++ linux_seed(); ++#endif /* __linux__ */ + if (RAND_status() != 1) + fatal("PRNG is not seeded"); + } +diff -up openssh-6.0p1/openbsd-compat/Makefile.in.entropy openssh-6.0p1/openbsd-compat/Makefile.in +--- openssh-6.0p1/openbsd-compat/Makefile.in.entropy 2012-08-06 20:51:59.100033534 +0200 ++++ openssh-6.0p1/openbsd-compat/Makefile.in 2012-08-06 20:51:59.171033257 +0200 +@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport + + COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o + +-PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o ++PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o + + .c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< +diff -up openssh-6.0p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.0p1/openbsd-compat/port-linux-prng.c +--- openssh-6.0p1/openbsd-compat/port-linux-prng.c.entropy 2012-08-06 20:51:59.171033257 +0200 ++++ openssh-6.0p1/openbsd-compat/port-linux-prng.c 2012-08-06 20:51:59.171033257 +0200 +@@ -0,0 +1,59 @@ ++/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ ++ ++/* ++ * Copyright (c) 2011 Jan F. Chadima jchadima@redhat.com ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/* ++ * Linux-specific portability code - prng support ++ */ ++ ++#include "includes.h" ++ ++#include <errno.h> ++#include <stdarg.h> ++#include <string.h> ++#include <stdio.h> ++#include <openssl/rand.h> ++ ++#include "log.h" ++#include "xmalloc.h" ++#include "servconf.h" ++#include "port-linux.h" ++#include "key.h" ++#include "hostfile.h" ++#include "auth.h" ++ ++void ++linux_seed(void) ++{ ++ int len; ++ char *env = getenv("SSH_USE_STRONG_RNG"); ++ char *random = "/dev/random"; ++ size_t ienv, randlen = 6; ++ ++ if (!env || !strcmp(env, "0")) ++ random = "/dev/urandom"; ++ else if ((ienv = atoi(env)) > 6) ++ randlen = ienv; ++ ++ errno = 0; ++ if ((len = RAND_load_file(random, randlen)) != randlen) { ++ if (errno) ++ fatal ("cannot read from %s, %s", random, strerror(errno)); ++ else ++ fatal ("EOF reading %s", random); ++ } ++} +diff -up openssh-6.0p1/ssh.1.entropy openssh-6.0p1/ssh.1 +--- openssh-6.0p1/ssh.1.entropy 2012-08-06 20:51:59.139033382 +0200 ++++ openssh-6.0p1/ssh.1 2012-08-06 20:51:59.174033245 +0200 +@@ -1269,6 +1269,23 @@ For more information, see the + .Cm PermitUserEnvironment + option in + .Xr sshd_config 5 . ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.It Ev SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 6 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh FILES + .Bl -tag -width Ds -compact + .It Pa ~/.rhosts +diff -up openssh-6.1p1/ssh-add.0.entropy openssh-6.1p1/ssh-add.0 +--- openssh-6.1p1/ssh-add.0.entropy 2012-11-12 13:11:42.717393364 +0100 ++++ openssh-6.1p1/ssh-add.0 2012-11-12 13:12:46.288108790 +0100 +@@ -81,6 +81,16 @@ ENVIRONMENT + Identifies the path of a UNIX-domain socket used to communicate + with the agent. + ++ SSH_USE_STRONG_RNG ++ The reseeding of the OpenSSL random generator is usually done ++ from /dev/urandom. If the SSH_USE_STRONG_RNG environment vari- ++ able is set to value other than 0 the OpenSSL random generator is ++ reseeded from /dev/random. The number of bytes read is defined ++ by the SSH_USE_STRONG_RNG value. Minimum is 6 bytes. This set- ++ ting is not recommended on the computers without the hardware ++ random generator because insufficient entropy causes the connec- ++ tion to be blocked until enough entropy is available. ++ + FILES + ~/.ssh/identity + Contains the protocol version 1 RSA authentication identity of +diff -up openssh-6.1p1/ssh-add.1.entropy openssh-6.1p1/ssh-add.1 +--- openssh-6.1p1/ssh-add.1.entropy 2011-10-18 07:06:33.000000000 +0200 ++++ openssh-6.1p1/ssh-add.1 2012-11-12 13:11:24.711476108 +0100 +@@ -160,6 +160,20 @@ to make this work.) + Identifies the path of a + .Ux Ns -domain + socket used to communicate with the agent. ++.It Ev SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 6 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. + .El + .Sh FILES + .Bl -tag -width Ds + .It Pa ~/.ssh/identity +diff -up openssh-6.0p1/ssh-agent.1.entropy openssh-6.0p1/ssh-agent.1 +--- openssh-6.0p1/ssh-agent.1.entropy 2010-12-01 01:50:35.000000000 +0100 ++++ openssh-6.0p1/ssh-agent.1 2012-08-06 20:51:59.172033253 +0200 +@@ -198,6 +198,24 @@ sockets used to contain the connection t + These sockets should only be readable by the owner. + The sockets should get automatically removed when the agent exits. + .El ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.Pp ++.It Pa SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 6 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh SEE ALSO + .Xr ssh 1 , + .Xr ssh-add 1 , +diff -up openssh-6.0p1/sshd.8.entropy openssh-6.0p1/sshd.8 +--- openssh-6.0p1/sshd.8.entropy 2012-08-06 20:51:59.139033382 +0200 ++++ openssh-6.0p1/sshd.8 2012-08-06 20:51:59.174033245 +0200 +@@ -943,6 +943,24 @@ concurrently for different ports, this c + started last). + The content of this file is not sensitive; it can be world-readable. + .El ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.Pp ++.It Pa SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 6 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh IPV6 + IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. + .Sh SEE ALSO +diff -up openssh-6.0p1/ssh-keygen.1.entropy openssh-6.0p1/ssh-keygen.1 +--- openssh-6.0p1/ssh-keygen.1.entropy 2011-10-18 07:05:21.000000000 +0200 ++++ openssh-6.0p1/ssh-keygen.1 2012-08-06 20:51:59.173033249 +0200 +@@ -675,6 +675,24 @@ Contains Diffie-Hellman groups used for + The file format is described in + .Xr moduli 5 . + .El ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.Pp ++.It Pa SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 6 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh SEE ALSO + .Xr ssh 1 , + .Xr ssh-add 1 , +diff -up openssh-6.0p1/ssh-keysign.8.entropy openssh-6.0p1/ssh-keysign.8 +--- openssh-6.0p1/ssh-keysign.8.entropy 2010-08-31 14:41:14.000000000 +0200 ++++ openssh-6.0p1/ssh-keysign.8 2012-08-06 20:51:59.173033249 +0200 +@@ -78,6 +78,24 @@ must be set-uid root if host-based authe + If these files exist they are assumed to contain public certificate + information corresponding with the private keys above. + .El ++.Sh ENVIRONMENT ++.Bl -tag -width Ds -compact ++.Pp ++.It Pa SSH_USE_STRONG_RNG ++The reseeding of the OpenSSL random generator is usually done from ++.Cm /dev/urandom . ++If the ++.Cm SSH_USE_STRONG_RNG ++environment variable is set to value other than ++.Cm 0 ++the OpenSSL random generator is reseeded from ++.Cm /dev/random . ++The number of bytes read is defined by the SSH_USE_STRONG_RNG value. ++Minimum is 6 bytes. ++This setting is not recommended on the computers without the hardware ++random generator because insufficient entropy causes the connection to ++be blocked until enough entropy is available. ++.El + .Sh SEE ALSO + .Xr ssh 1 , + .Xr ssh-keygen 1 , diff --git a/openssh/patches/openssh-6.1p1-akc.patch b/openssh/patches/openssh-6.1p1-akc.patch new file mode 100644 index 0000000..0401ba0 --- /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 <sys/types.h> + #include <sys/stat.h> ++#include <sys/wait.h> + ++#include <errno.h> + #include <fcntl.h> ++#include <paths.h> + #include <pwd.h> ++#include <signal.h> + #include <stdio.h> + #include <stdarg.h> + #include <string.h> +@@ -260,7 +264,7 @@ match_principals_file(char *file, struct + if (strcmp(cp, cert->principals[i]) == 0) { + debug3("matched principal "%.100s" " + "from file "%s" on line %lu", +- cert->principals[i], file, linenum); ++ cert->principals[i], file, linenum); + if (auth_parse_options(pw, line_opts, + file, linenum) != 1) + continue; +@@ -273,31 +277,22 @@ match_principals_file(char *file, struct + fclose(f); + restore_uid(); + return 0; +-} ++} + +-/* return 1 if user allows given key */ ++/* ++ * Checks whether key is allowed in authorized_keys-format file, ++ * returns 1 if the key is allowed or 0 otherwise. ++ */ + static int +-user_key_allowed2(struct passwd *pw, Key *key, char *file) ++check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) + { + char line[SSH_MAX_PUBKEY_BYTES]; + const char *reason; + int found_key = 0; +- FILE *f; + u_long linenum = 0; + Key *found; + char *fp; + +- /* Temporarily use the user's uid. */ +- temporarily_use_uid(pw); +- +- debug("trying public key file %s", file); +- f = auth_openkeyfile(file, pw, options.strict_modes); +- +- if (!f) { +- restore_uid(); +- return 0; +- } +- + found_key = 0; + found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); + +@@ -390,8 +385,6 @@ user_key_allowed2(struct passwd *pw, Key + break; + } + } +- restore_uid(); +- fclose(f); + key_free(found); + if (!found_key) + debug2("key not found"); +@@ -453,7 +446,173 @@ user_cert_trusted_ca(struct passwd *pw, + return ret; + } + +-/* check whether given key is in .ssh/authorized_keys* */ ++/* ++ * Checks whether key is allowed in file. ++ * returns 1 if the key is allowed or 0 otherwise. ++ */ ++static int ++user_key_allowed2(struct passwd *pw, Key *key, char *file) ++{ ++ FILE *f; ++ int found_key = 0; ++ ++ /* Temporarily use the user's uid. */ ++ temporarily_use_uid(pw); ++ ++ debug("trying public key file %s", file); ++ if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) { ++ found_key = check_authkeys_file(f, file, key, pw); ++ fclose(f); ++ } ++ ++ restore_uid(); ++ return found_key; ++} ++ ++/* ++ * Checks whether key is allowed in output of command. ++ * returns 1 if the key is allowed or 0 otherwise. ++ */ ++static int ++user_key_command_allowed2(struct passwd *user_pw, Key *key) ++{ ++ FILE *f; ++ int ok, found_key = 0; ++ struct passwd *pw; ++ struct stat st; ++ int status, devnull, p[2], i; ++ pid_t pid; ++ char errmsg[512]; ++ ++ if (options.authorized_keys_command == NULL || ++ options.authorized_keys_command[0] != '/') ++ return 0; ++ ++ /* If no user specified to run commands the default to target user */ ++ if (options.authorized_keys_command_user == NULL) ++ pw = user_pw; ++ else { ++ pw = getpwnam(options.authorized_keys_command_user); ++ if (pw == NULL) { ++ error("AuthorizedKeyCommandUser "%s" not found: %s", ++ options.authorized_keys_command, strerror(errno)); ++ return 0; ++ } ++ } ++ ++ temporarily_use_uid(pw); ++ if (stat(options.authorized_keys_command, &st) < 0) { ++ error("Could not stat AuthorizedKeysCommand "%s": %s", ++ options.authorized_keys_command, strerror(errno)); ++ goto out; ++ } ++ ++ if (auth_secure_path(options.authorized_keys_command, &st, NULL, 0, ++ errmsg, sizeof(errmsg)) != 0) { ++ error("Unsafe AuthorizedKeysCommand: %s", errmsg); ++ goto out; ++ } ++ ++ /* open the pipe and read the keys */ ++ if (pipe(p) != 0) { ++ error("%s: pipe: %s", __func__, strerror(errno)); ++ goto out; ++ } ++ ++ debug3("Running AuthorizedKeysCommand: "%s" as "%s"", ++ options.authorized_keys_command, pw->pw_name); ++ ++ /* ++ * Don't want to call this in the child, where it can fatal() and ++ * run cleanup_exit() code. ++ */ ++ restore_uid(); ++ ++ switch ((pid = fork())) { ++ case -1: /* error */ ++ error("%s: fork: %s", __func__, strerror(errno)); ++ close(p[0]); ++ close(p[1]); ++ return 0; ++ case 0: /* child */ ++ for (i = 0; i < NSIG; i++) ++ signal(i, SIG_DFL); ++ ++ /* Don't use permanently_set_uid() here to avoid fatal() */ ++ if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { ++ error("setresgid %u: %s", (u_int)pw->pw_gid, ++ strerror(errno)); ++ _exit(1); ++ } ++ if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) { ++ error("setresuid %u: %s", (u_int)pw->pw_uid, ++ strerror(errno)); ++ _exit(1); ++ } ++ ++ close(p[0]); ++ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { ++ error("%s: open %s: %s", __func__, _PATH_DEVNULL, ++ strerror(errno)); ++ _exit(1); ++ } ++ if (dup2(devnull, STDIN_FILENO) == -1 || ++ dup2(p[1], STDOUT_FILENO) == -1 || ++ dup2(devnull, STDERR_FILENO) == -1) { ++ error("%s: dup2: %s", __func__, strerror(errno)); ++ _exit(1); ++ } ++ closefrom(STDERR_FILENO + 1); ++ ++ execl(options.authorized_keys_command, ++ options.authorized_keys_command, pw->pw_name, NULL); ++ ++ error("AuthorizedKeysCommand %s exec failed: %s", ++ options.authorized_keys_command, strerror(errno)); ++ _exit(127); ++ default: /* parent */ ++ break; ++ } ++ ++ temporarily_use_uid(pw); ++ ++ close(p[1]); ++ if ((f = fdopen(p[0], "r")) == NULL) { ++ error("%s: fdopen: %s", __func__, strerror(errno)); ++ close(p[0]); ++ /* Don't leave zombie child */ ++ while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) ++ ; ++ goto out; ++ } ++ ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); ++ fclose(f); ++ ++ while (waitpid(pid, &status, 0) == -1) { ++ if (errno != EINTR) { ++ error("%s: waitpid: %s", __func__, strerror(errno)); ++ goto out; ++ } ++ } ++ if (WIFSIGNALED(status)) { ++ error("AuthorizedKeysCommand %s exited on signal %d", ++ options.authorized_keys_command, WTERMSIG(status)); ++ goto out; ++ } else if (WEXITSTATUS(status) != 0) { ++ error("AuthorizedKeysCommand %s returned status %d", ++ options.authorized_keys_command, WEXITSTATUS(status)); ++ goto out; ++ } ++ found_key = ok; ++ out: ++ restore_uid(); ++ ++ return found_key; ++} ++ ++/* ++ * Check whether key authenticates and authorises the user. ++ */ + int + user_key_allowed(struct passwd *pw, Key *key) + { +@@ -469,6 +628,10 @@ user_key_allowed(struct passwd *pw, Key + if (success) + return success; + ++ success = user_key_command_allowed2(pw, key); ++ if (success > 0) ++ return success; ++ + for (i = 0; !success && i < options.num_authkeys_files; i++) { + file = expand_authorized_keys( + options.authorized_keys_files[i], pw); +diff -up openssh-6.1p1/auth.c.akc openssh-6.1p1/auth.c +--- openssh-6.1p1/auth.c.akc 2012-11-28 17:12:43.187524558 +0100 ++++ openssh-6.1p1/auth.c 2012-11-28 17:12:43.263524297 +0100 +@@ -411,39 +411,41 @@ check_key_in_hostfiles(struct passwd *pw + + + /* +- * Check a given file for security. This is defined as all components ++ * Check a given path for security. This is defined as all components + * of the path to the file must be owned by either the owner of + * of the file or root and no directories must be group or world writable. + * + * XXX Should any specific check be done for sym links ? + * +- * Takes an open file descriptor, the file name, a uid and and ++ * Takes an the file name, its stat information (preferably from fstat() to ++ * avoid races), the uid of the expected owner, their home directory and an + * error buffer plus max size as arguments. + * + * Returns 0 on success and -1 on failure + */ +-static int +-secure_filename(FILE *f, const char *file, struct passwd *pw, +- char *err, size_t errlen) ++int ++auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, ++ uid_t uid, char *err, size_t errlen) + { +- uid_t uid = pw->pw_uid; + char buf[MAXPATHLEN], homedir[MAXPATHLEN]; + char *cp; + int comparehome = 0; + struct stat st; + +- if (realpath(file, buf) == NULL) { +- snprintf(err, errlen, "realpath %s failed: %s", file, ++ if (realpath(name, buf) == NULL) { ++ snprintf(err, errlen, "realpath %s failed: %s", name, + strerror(errno)); + return -1; + } +- if (realpath(pw->pw_dir, homedir) != NULL) ++ if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) + comparehome = 1; + +- /* check the open file to avoid races */ +- if (fstat(fileno(f), &st) < 0 || +- (st.st_uid != 0 && st.st_uid != uid) || +- (st.st_mode & 022) != 0) { ++ if (!S_ISREG(stp->st_mode)) { ++ snprintf(err, errlen, "%s is not a regular file", buf); ++ return -1; ++ } ++ if ((stp->st_uid != 0 && stp->st_uid != uid) || ++ (stp->st_mode & 022) != 0) { + snprintf(err, errlen, "bad ownership or modes for file %s", + buf); + return -1; +@@ -479,6 +481,31 @@ secure_filename(FILE *f, const char *fil + return 0; + } + ++/* ++ * Version of secure_path() that accepts an open file descriptor to ++ * avoid races. ++ * ++ * Returns 0 on success and -1 on failure ++ */ ++static int ++secure_filename(FILE *f, const char *file, struct passwd *pw, ++ char *err, size_t errlen) ++{ ++ uid_t uid = pw->pw_uid; ++ char buf[MAXPATHLEN], homedir[MAXPATHLEN]; ++ char *cp; ++ int comparehome = 0; ++ struct stat st; ++ ++ /* check the open file to avoid races */ ++ if (fstat(fileno(f), &st) < 0) { ++ snprintf(err, errlen, "cannot stat file %s: %s", ++ buf, strerror(errno)); ++ return -1; ++ } ++ return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); ++} ++ + static FILE * + auth_openfile(const char *file, struct passwd *pw, int strict_modes, + int log_missing, char *file_type) +diff -up openssh-6.1p1/auth.h.akc openssh-6.1p1/auth.h +--- openssh-6.1p1/auth.h.akc 2012-11-28 17:12:43.239524381 +0100 ++++ openssh-6.1p1/auth.h 2012-11-28 17:12:43.263524297 +0100 +@@ -125,6 +125,10 @@ int auth_rhosts_rsa_key_allowed(struct + int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); + int user_key_allowed(struct passwd *, Key *); + ++struct stat; ++int auth_secure_path(const char *, struct stat *, const char *, uid_t, ++ char *, size_t); ++ + #ifdef KRB5 + int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); + int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); +diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c +--- openssh-6.1p1/servconf.c.akc 2012-11-28 17:12:43.198524521 +0100 ++++ openssh-6.1p1/servconf.c 2012-11-28 17:14:50.314005026 +0100 +@@ -137,6 +137,8 @@ initialize_server_options(ServerOptions + options->num_permitted_opens = -1; + options->adm_forced_command = NULL; + options->chroot_directory = NULL; ++ options->authorized_keys_command = NULL; ++ options->authorized_keys_command_user = NULL; + options->zero_knowledge_password_authentication = -1; + options->revoked_keys_file = NULL; + options->trusted_user_ca_keys = NULL; +@@ -331,6 +333,7 @@ typedef enum { + sZeroKnowledgePasswordAuthentication, sHostCertificate, + sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, + sKexAlgorithms, sIPQoS, sVersionAddendum, ++ sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, + sAuthenticationMethods, + sDeprecated, sUnsupported + } ServerOpCodes; +@@ -457,6 +460,9 @@ static struct { + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, + { "ipqos", sIPQoS, SSHCFG_ALL }, + { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, ++ { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, ++ { "authorizedkeyscommandrunas", sAuthorizedKeysCommandUser, SSHCFG_ALL }, ++ { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, + { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, + { NULL, sBadOption, 0 } + }; +@@ -1520,6 +1526,26 @@ process_server_config_line(ServerOptions + } + return 0; + ++ case sAuthorizedKeysCommand: ++ len = strspn(cp, WHITESPACE); ++ if (*activep && options->authorized_keys_command == NULL) { ++ options->authorized_keys_command = xstrdup(cp + len); ++ if (*options->authorized_keys_command != '/') { ++ fatal("%.200s line %d: AuthorizedKeysCommand " ++ "must be an absolute path", ++ filename, linenum); ++ } ++ } ++ return 0; ++ ++ case sAuthorizedKeysCommandUser: ++ charptr = &options->authorized_keys_command_user; ++ ++ arg = strdelim(&cp); ++ if (*activep && *charptr == NULL) ++ *charptr = xstrdup(arg); ++ break; ++ + case sDeprecated: + logit("%s line %d: Deprecated option %s", + filename, linenum, arg); +@@ -1670,6 +1696,8 @@ copy_set_server_options(ServerOptions *d + M_CP_INTOPT(hostbased_uses_name_from_packet_only); + M_CP_INTOPT(kbd_interactive_authentication); + M_CP_INTOPT(zero_knowledge_password_authentication); ++ M_CP_STROPT(authorized_keys_command); ++ M_CP_STROPT(authorized_keys_command_user); + M_CP_INTOPT(permit_root_login); + M_CP_INTOPT(permit_empty_passwd); + +@@ -1930,6 +1958,8 @@ dump_config(ServerOptions *o) + dump_cfg_string(sAuthorizedPrincipalsFile, + o->authorized_principals_file); + dump_cfg_string(sVersionAddendum, o->version_addendum); ++ dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); ++ dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); + + /* string arguments requiring a lookup */ + dump_cfg_string(sLogLevel, log_level_name(o->log_level)); +diff -up openssh-6.1p1/servconf.h.akc openssh-6.1p1/servconf.h +--- openssh-6.1p1/servconf.h.akc 2012-11-28 17:12:43.000000000 +0100 ++++ openssh-6.1p1/servconf.h 2012-11-28 17:18:41.217055157 +0100 +@@ -167,6 +167,8 @@ typedef struct { + char *revoked_keys_file; + char *trusted_user_ca_keys; + char *authorized_principals_file; ++ char *authorized_keys_command; ++ char *authorized_keys_command_user; + + char *version_addendum; /* Appended to SSH banner */ + +diff -up openssh-6.1p1/sshd.c.akc openssh-6.1p1/sshd.c +--- openssh-6.1p1/sshd.c.akc 2012-11-28 17:12:43.245524360 +0100 ++++ openssh-6.1p1/sshd.c 2012-11-28 17:12:43.265524291 +0100 +@@ -366,9 +366,20 @@ main_sigchld_handler(int sig) + static void + grace_alarm_handler(int sig) + { ++ pid_t pgid; ++ + if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0) + kill(pmonitor->m_pid, SIGALRM); + ++ /* ++ * Try to kill any processes that we have spawned, E.g. authorized ++ * keys command helpers. ++ */ ++ if ((pgid = getpgid(0)) == getpid()) { ++ signal(SIGTERM, SIG_IGN); ++ killpg(pgid, SIGTERM); ++ } ++ + /* Log error and exit. */ + sigdie("Timeout before authentication for %s", get_remote_ipaddr()); + } +diff -up openssh-6.1p1/sshd_config.0.akc openssh-6.1p1/sshd_config.0 +--- openssh-6.1p1/sshd_config.0.akc 2012-08-29 02:53:04.000000000 +0200 ++++ openssh-6.1p1/sshd_config.0 2012-11-28 17:12:43.265524291 +0100 +@@ -71,6 +71,23 @@ DESCRIPTION + + See PATTERNS in ssh_config(5) for more information on patterns. + ++ AuthorizedKeysCommand ++ ++ Specifies a program to be used for lookup of the user's ++ public keys. The program will be invoked with its first ++ argument the name of the user being authorized, and should produce ++ on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS ++ in sshd(8)). By default (or when set to the empty string) there is no ++ AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully ++ authorize the user, authorization falls through to the ++ AuthorizedKeysFile. Note that this option has an effect ++ only with PubkeyAuthentication turned on. ++ ++ AuthorizedKeysCommandRunAs ++ Specifies the user under whose account the AuthorizedKeysCommand is run. ++ Empty string (the default value) means the user being authorized ++ is used. ++ + AuthorizedKeysFile + Specifies the file that contains the public keys that can be used + for user authentication. The format is described in the +@@ -402,7 +419,8 @@ DESCRIPTION + Only a subset of keywords may be used on the lines following a + Match keyword. Available keywords are AcceptEnv, + AllowAgentForwarding, AllowGroups, AllowTcpForwarding, +- AllowUsers, AuthorizedKeysFile, AuthorizedPrincipalsFile, Banner, ++ AllowUsers, AuthorizedKeysFile, AuthorizedKeysCommand, ++ AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile, Banner, + ChrootDirectory, DenyGroups, DenyUsers, ForceCommand, + GatewayPorts, GSSAPIAuthentication, HostbasedAuthentication, + HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication, +diff -up openssh-6.1p1/sshd_config.5.akc openssh-6.1p1/sshd_config.5 +--- openssh-6.1p1/sshd_config.5.akc 2012-11-28 17:12:43.199524517 +0100 ++++ openssh-6.1p1/sshd_config.5 2012-11-28 17:16:23.736624980 +0100 +@@ -173,6 +173,20 @@ Note that each authentication method lis + in the configuration. + The default is not to require multiple authentication; successful completion + of a single authentication method is sufficient. ++.It Cm AuthorizedKeysCommand ++Specifies a program to be used for lookup of the user's public keys. ++The program will be invoked with a single argument of the username ++being authenticated, and should produce on standard output zero or ++more lines of authorized_keys output (see AUTHORIZED_KEYS in ++.Xr sshd 8 ) ++If a key supplied by AuthorizedKeysCommand does not successfully authenticate ++and authorize the user then public key authentication continues using the usual ++.Cm AuthorizedKeysFile ++files. ++By default, no AuthorizedKeysCommand is run. ++.It Cm AuthorizedKeysCommandUser ++Specifies the user under whose account the AuthorizedKeysCommand is run. ++The default is the user being authenticated. + .It Cm AuthorizedKeysFile + Specifies the file that contains the public keys that can be used + for user authentication. +@@ -734,6 +748,8 @@ Available keywords are + .Cm AllowTcpForwarding , + .Cm AllowUsers , + .Cm AuthenticationMethods , ++.Cm AuthorizedKeysCommand , ++.Cm AuthorizedKeysCommandUser , + .Cm AuthorizedKeysFile , + .Cm AuthorizedPrincipalsFile , + .Cm Banner , +@@ -749,6 +765,7 @@ Available keywords are + .Cm KerberosAuthentication , + .Cm MaxAuthTries , + .Cm MaxSessions , ++.Cm PubkeyAuthentication , + .Cm PasswordAuthentication , + .Cm PermitEmptyPasswords , + .Cm PermitOpen , +diff -up openssh-6.1p1/sshd_config.akc openssh-6.1p1/sshd_config +--- openssh-6.1p1/sshd_config.akc 2012-07-31 04:21:34.000000000 +0200 ++++ openssh-6.1p1/sshd_config 2012-11-28 17:12:43.265524291 +0100 +@@ -49,6 +49,9 @@ + # but this is overridden so installations will only check .ssh/authorized_keys + AuthorizedKeysFile .ssh/authorized_keys + ++#AuthorizedKeysCommand none ++#AuthorizedKeysCommandUser nobody ++ + #AuthorizedPrincipalsFile none + + # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts diff --git a/openssh/patches/openssh-6.1p1-askpass-ld.patch b/openssh/patches/openssh-6.1p1-askpass-ld.patch new file mode 100644 index 0000000..f7a7fac --- /dev/null +++ b/openssh/patches/openssh-6.1p1-askpass-ld.patch @@ -0,0 +1,18 @@ +diff -up openssh-6.1p1/contrib/Makefile.askpass-ld openssh-6.1p1/contrib/Makefile +--- openssh-6.1p1/contrib/Makefile.askpass-ld 2012-05-19 07:24:37.000000000 +0200 ++++ openssh-6.1p1/contrib/Makefile 2012-09-14 20:35:47.565704718 +0200 +@@ -4,12 +4,12 @@ all: + @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" + + gnome-ssh-askpass1: gnome-ssh-askpass1.c +- $(CC) `gnome-config --cflags gnome gnomeui` \ ++ $(CC) ${CFLAGS} `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \ + `gnome-config --libs gnome gnomeui` + + gnome-ssh-askpass2: gnome-ssh-askpass2.c +- $(CC) `$(PKG_CONFIG) --cflags gtk+-2.0` \ ++ $(CC) ${CFLAGS} `$(PKG_CONFIG) --cflags gtk+-2.0` \ + gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ + `$(PKG_CONFIG) --libs gtk+-2.0 x11` + diff --git a/openssh/patches/openssh-6.1p1-authenticationmethods.patch b/openssh/patches/openssh-6.1p1-authenticationmethods.patch new file mode 100644 index 0000000..7b5a06a --- /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-6.1p1-coverity.patch b/openssh/patches/openssh-6.1p1-coverity.patch new file mode 100644 index 0000000..0c8fb23 --- /dev/null +++ b/openssh/patches/openssh-6.1p1-coverity.patch @@ -0,0 +1,806 @@ +diff -up openssh-6.1p1/auth-pam.c.coverity openssh-6.1p1/auth-pam.c +--- openssh-6.1p1/auth-pam.c.coverity 2009-07-12 14:07:21.000000000 +0200 ++++ openssh-6.1p1/auth-pam.c 2012-09-14 21:16:41.264906486 +0200 +@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void * + if (sshpam_thread_status != -1) + return (sshpam_thread_status); + signal(SIGCHLD, sshpam_oldsig); +- waitpid(thread, &status, 0); ++ while (waitpid(thread, &status, 0) < 0) { ++ if (errno == EINTR) ++ continue; ++ fatal("%s: waitpid: %s", __func__, ++ strerror(errno)); ++ } + return (status); + } + #endif +diff -up openssh-6.1p1/clientloop.c.coverity openssh-6.1p1/clientloop.c +--- openssh-6.1p1/clientloop.c.coverity 2012-06-20 14:31:27.000000000 +0200 ++++ openssh-6.1p1/clientloop.c 2012-09-14 21:16:41.267906501 +0200 +@@ -2006,14 +2006,15 @@ client_input_global_request(int type, u_ + char *rtype; + int want_reply; + int success = 0; ++/* success is still 0 the packet is allways SSH2_MSG_REQUEST_FAILURE, isn't it? */ + + rtype = packet_get_string(NULL); + want_reply = packet_get_char(); + debug("client_input_global_request: rtype %s want_reply %d", + rtype, want_reply); + if (want_reply) { +- packet_start(success ? +- SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); ++ packet_start(/*success ? ++ SSH2_MSG_REQUEST_SUCCESS :*/ SSH2_MSG_REQUEST_FAILURE); + packet_send(); + packet_write_wait(); + } +diff -up openssh-6.1p1/channels.c.coverity openssh-6.1p1/channels.c +--- openssh-6.1p1/channels.c.coverity 2012-04-23 10:21:05.000000000 +0200 ++++ openssh-6.1p1/channels.c 2012-09-14 21:16:41.272906528 +0200 +@@ -232,11 +232,11 @@ channel_register_fds(Channel *c, int rfd + channel_max_fd = MAX(channel_max_fd, wfd); + channel_max_fd = MAX(channel_max_fd, efd); + +- if (rfd != -1) ++ if (rfd >= 0) + fcntl(rfd, F_SETFD, FD_CLOEXEC); +- if (wfd != -1 && wfd != rfd) ++ if (wfd >= 0 && wfd != rfd) + fcntl(wfd, F_SETFD, FD_CLOEXEC); +- if (efd != -1 && efd != rfd && efd != wfd) ++ if (efd >= 0 && efd != rfd && efd != wfd) + fcntl(efd, F_SETFD, FD_CLOEXEC); + + c->rfd = rfd; +@@ -251,11 +251,11 @@ channel_register_fds(Channel *c, int rfd + + /* enable nonblocking mode */ + if (nonblock) { +- if (rfd != -1) ++ if (rfd >= 0) + set_nonblock(rfd); +- if (wfd != -1) ++ if (wfd >= 0) + set_nonblock(wfd); +- if (efd != -1) ++ if (efd >= 0) + set_nonblock(efd); + } + } +diff -up openssh-6.1p1/key.c.coverity openssh-6.1p1/key.c +--- openssh-6.1p1/key.c.coverity 2012-06-30 12:05:02.000000000 +0200 ++++ openssh-6.1p1/key.c 2012-09-14 21:16:41.274906537 +0200 +@@ -808,8 +808,10 @@ key_read(Key *ret, char **cpp) + success = 1; + /*XXXX*/ + key_free(k); ++/*XXXX + if (success != 1) + break; ++XXXX*/ + /* advance cp: skip whitespace and data */ + while (*cp == ' ' || *cp == '\t') + cp++; +diff -up openssh-6.1p1/monitor.c.coverity openssh-6.1p1/monitor.c +--- openssh-6.1p1/monitor.c.coverity 2012-06-30 00:33:17.000000000 +0200 ++++ openssh-6.1p1/monitor.c 2012-09-14 21:16:41.277906552 +0200 +@@ -420,7 +420,7 @@ monitor_child_preauth(Authctxt *_authctx + } + + /* Drain any buffered messages from the child */ +- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) ++ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) + ; + + if (!authctxt->valid) +@@ -1159,6 +1159,10 @@ mm_answer_keyallowed(int sock, Buffer *m + break; + } + } ++ ++ debug3("%s: key %p is %s", ++ __func__, key, allowed ? "allowed" : "not allowed"); ++ + if (key != NULL) + key_free(key); + +@@ -1180,9 +1184,6 @@ mm_answer_keyallowed(int sock, Buffer *m + xfree(chost); + } + +- debug3("%s: key %p is %s", +- __func__, key, allowed ? "allowed" : "not allowed"); +- + buffer_clear(m); + buffer_put_int(m, allowed); + buffer_put_int(m, forced_command != NULL); +diff -up openssh-6.1p1/monitor_wrap.c.coverity openssh-6.1p1/monitor_wrap.c +--- openssh-6.1p1/monitor_wrap.c.coverity 2011-06-20 06:42:23.000000000 +0200 ++++ openssh-6.1p1/monitor_wrap.c 2012-09-14 21:16:41.280906568 +0200 +@@ -707,10 +707,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, + if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || + (tmp2 = dup(pmonitor->m_recvfd)) == -1) { + error("%s: cannot allocate fds for pty", __func__); +- if (tmp1 > 0) ++ if (tmp1 >= 0) + close(tmp1); +- if (tmp2 > 0) +- close(tmp2); ++ /*DEAD CODE if (tmp2 >= 0) ++ close(tmp2);*/ + return 0; + } + close(tmp1); +diff -up openssh-6.1p1/openbsd-compat/bindresvport.c.coverity openssh-6.1p1/openbsd-compat/bindresvport.c +--- openssh-6.1p1/openbsd-compat/bindresvport.c.coverity 2010-12-03 00:50:26.000000000 +0100 ++++ openssh-6.1p1/openbsd-compat/bindresvport.c 2012-09-14 21:16:41.281906573 +0200 +@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr + struct sockaddr_in6 *in6; + u_int16_t *portp; + u_int16_t port; +- socklen_t salen; ++ socklen_t salen = sizeof(struct sockaddr_storage); + int i; + + if (sa == NULL) { +diff -up openssh-6.1p1/packet.c.coverity openssh-6.1p1/packet.c +--- openssh-6.1p1/packet.c.coverity 2012-03-09 00:28:07.000000000 +0100 ++++ openssh-6.1p1/packet.c 2012-09-14 21:16:41.284906588 +0200 +@@ -1177,6 +1177,7 @@ packet_read_poll1(void) + case DEATTACK_DETECTED: + packet_disconnect("crc32 compensation attack: " + "network attack detected"); ++ break; + case DEATTACK_DOS_DETECTED: + packet_disconnect("deattack denial of " + "service detected"); +@@ -1678,7 +1679,7 @@ void + packet_write_wait(void) + { + fd_set *setp; +- int ret, ms_remain; ++ int ret, ms_remain = 0; + struct timeval start, timeout, *timeoutp = NULL; + + setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, +diff -up openssh-6.1p1/progressmeter.c.coverity openssh-6.1p1/progressmeter.c +--- openssh-6.1p1/progressmeter.c.coverity 2006-08-05 04:39:40.000000000 +0200 ++++ openssh-6.1p1/progressmeter.c 2012-09-14 21:16:41.285906593 +0200 +@@ -65,7 +65,7 @@ static void update_progress_meter(int); + + static time_t start; /* start progress */ + static time_t last_update; /* last progress update */ +-static char *file; /* name of the file being transferred */ ++static const char *file; /* name of the file being transferred */ + static off_t end_pos; /* ending position of transfer */ + static off_t cur_pos; /* transfer position as of last refresh */ + static volatile off_t *counter; /* progress counter */ +@@ -247,7 +247,7 @@ update_progress_meter(int ignore) + } + + void +-start_progress_meter(char *f, off_t filesize, off_t *ctr) ++start_progress_meter(const char *f, off_t filesize, off_t *ctr) + { + start = last_update = time(NULL); + file = f; +diff -up openssh-6.1p1/progressmeter.h.coverity openssh-6.1p1/progressmeter.h +--- openssh-6.1p1/progressmeter.h.coverity 2006-03-26 05:30:02.000000000 +0200 ++++ openssh-6.1p1/progressmeter.h 2012-09-14 21:16:41.286906598 +0200 +@@ -23,5 +23,5 @@ + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +-void start_progress_meter(char *, off_t, off_t *); ++void start_progress_meter(const char *, off_t, off_t *); + void stop_progress_meter(void); +diff -up openssh-6.1p1/scp.c.coverity openssh-6.1p1/scp.c +--- openssh-6.1p1/scp.c.coverity 2011-09-22 13:38:01.000000000 +0200 ++++ openssh-6.1p1/scp.c 2012-09-14 21:16:41.288906608 +0200 +@@ -155,7 +155,7 @@ killchild(int signo) + { + if (do_cmd_pid > 1) { + kill(do_cmd_pid, signo ? signo : SIGTERM); +- waitpid(do_cmd_pid, NULL, 0); ++ (void) waitpid(do_cmd_pid, NULL, 0); + } + + if (signo) +diff -up openssh-6.1p1/servconf.c.coverity openssh-6.1p1/servconf.c +--- openssh-6.1p1/servconf.c.coverity 2012-07-31 04:22:38.000000000 +0200 ++++ openssh-6.1p1/servconf.c 2012-09-14 21:16:41.291906623 +0200 +@@ -1249,7 +1249,7 @@ process_server_config_line(ServerOptions + fatal("%s line %d: Missing subsystem name.", + filename, linenum); + if (!*activep) { +- arg = strdelim(&cp); ++ /*arg =*/ (void) strdelim(&cp); + break; + } + for (i = 0; i < options->num_subsystems; i++) +@@ -1340,8 +1340,9 @@ process_server_config_line(ServerOptions + if (*activep && *charptr == NULL) { + *charptr = tilde_expand_filename(arg, getuid()); + /* increase optional counter */ +- if (intptr != NULL) +- *intptr = *intptr + 1; ++ /* DEAD CODE intptr is still NULL ;) ++ if (intptr != NULL) ++ *intptr = *intptr + 1; */ + } + break; + +diff -up openssh-6.1p1/serverloop.c.coverity openssh-6.1p1/serverloop.c +--- openssh-6.1p1/serverloop.c.coverity 2012-06-20 14:31:27.000000000 +0200 ++++ openssh-6.1p1/serverloop.c 2012-09-14 21:16:41.294906638 +0200 +@@ -147,13 +147,13 @@ notify_setup(void) + static void + notify_parent(void) + { +- if (notify_pipe[1] != -1) ++ if (notify_pipe[1] >= 0) + write(notify_pipe[1], "", 1); + } + static void + notify_prepare(fd_set *readset) + { +- if (notify_pipe[0] != -1) ++ if (notify_pipe[0] >= 0) + FD_SET(notify_pipe[0], readset); + } + static void +@@ -161,8 +161,8 @@ notify_done(fd_set *readset) + { + char c; + +- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) +- while (read(notify_pipe[0], &c, 1) != -1) ++ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) ++ while (read(notify_pipe[0], &c, 1) >= 0) + debug2("notify_done: reading"); + } + +@@ -336,7 +336,7 @@ wait_until_can_do_something(fd_set **rea + * If we have buffered data, try to write some of that data + * to the program. + */ +- if (fdin != -1 && buffer_len(&stdin_buffer) > 0) ++ if (fdin >= 0 && buffer_len(&stdin_buffer) > 0) + FD_SET(fdin, *writesetp); + } + notify_prepare(*readsetp); +@@ -476,7 +476,7 @@ process_output(fd_set *writeset) + int len; + + /* Write buffered data to program stdin. */ +- if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { ++ if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) { + data = buffer_ptr(&stdin_buffer); + dlen = buffer_len(&stdin_buffer); + len = write(fdin, data, dlen); +@@ -589,7 +589,7 @@ server_loop(pid_t pid, int fdin_arg, int + set_nonblock(fdin); + set_nonblock(fdout); + /* we don't have stderr for interactive terminal sessions, see below */ +- if (fderr != -1) ++ if (fderr >= 0) + set_nonblock(fderr); + + if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) +@@ -613,7 +613,7 @@ server_loop(pid_t pid, int fdin_arg, int + max_fd = MAX(connection_in, connection_out); + max_fd = MAX(max_fd, fdin); + max_fd = MAX(max_fd, fdout); +- if (fderr != -1) ++ if (fderr >= 0) + max_fd = MAX(max_fd, fderr); + #endif + +@@ -643,7 +643,7 @@ server_loop(pid_t pid, int fdin_arg, int + * If we have received eof, and there is no more pending + * input data, cause a real eof by closing fdin. + */ +- if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { ++ if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) { + if (fdin != fdout) + close(fdin); + else +@@ -741,15 +741,15 @@ server_loop(pid_t pid, int fdin_arg, int + buffer_free(&stderr_buffer); + + /* Close the file descriptors. */ +- if (fdout != -1) ++ if (fdout >= 0) + close(fdout); + fdout = -1; + fdout_eof = 1; +- if (fderr != -1) ++ if (fderr >= 0) + close(fderr); + fderr = -1; + fderr_eof = 1; +- if (fdin != -1) ++ if (fdin >= 0) + close(fdin); + fdin = -1; + +@@ -943,7 +943,7 @@ server_input_window_size(int type, u_int + + debug("Window change received."); + packet_check_eom(); +- if (fdin != -1) ++ if (fdin >= 0) + pty_change_window_size(fdin, row, col, xpixel, ypixel); + } + +@@ -996,7 +996,7 @@ server_request_tun(void) + } + + tun = packet_get_int(); +- if (forced_tun_device != -1) { ++ if (forced_tun_device >= 0) { + if (tun != SSH_TUNID_ANY && forced_tun_device != tun) + goto done; + tun = forced_tun_device; +diff -up openssh-6.1p1/sftp.c.coverity openssh-6.1p1/sftp.c +--- openssh-6.1p1/sftp.c.coverity 2012-06-30 00:33:32.000000000 +0200 ++++ openssh-6.1p1/sftp.c 2012-09-14 21:16:41.297906653 +0200 +@@ -206,7 +206,7 @@ killchild(int signo) + { + if (sshpid > 1) { + kill(sshpid, SIGTERM); +- waitpid(sshpid, NULL, 0); ++ (void) waitpid(sshpid, NULL, 0); + } + + _exit(1); +@@ -316,7 +316,7 @@ local_do_ls(const char *args) + + /* Strip one path (usually the pwd) from the start of another */ + static char * +-path_strip(char *path, char *strip) ++path_strip(const char *path, const char *strip) + { + size_t len; + +@@ -334,7 +334,7 @@ path_strip(char *path, char *strip) + } + + static char * +-make_absolute(char *p, char *pwd) ++make_absolute(char *p, const char *pwd) + { + char *abs_str; + +@@ -482,7 +482,7 @@ parse_df_flags(const char *cmd, char **a + } + + static int +-is_dir(char *path) ++is_dir(const char *path) + { + struct stat sb; + +@@ -494,7 +494,7 @@ is_dir(char *path) + } + + static int +-remote_is_dir(struct sftp_conn *conn, char *path) ++remote_is_dir(struct sftp_conn *conn, const char *path) + { + Attrib *a; + +@@ -508,7 +508,7 @@ remote_is_dir(struct sftp_conn *conn, ch + + /* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ + static int +-pathname_is_dir(char *pathname) ++pathname_is_dir(const char *pathname) + { + size_t l = strlen(pathname); + +@@ -516,7 +516,7 @@ pathname_is_dir(char *pathname) + } + + static int +-process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, ++process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, + int pflag, int rflag) + { + char *abs_src = NULL; +@@ -590,7 +590,7 @@ out: + } + + static int +-process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, ++process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, + int pflag, int rflag) + { + char *tmp_dst = NULL; +@@ -695,7 +695,7 @@ sdirent_comp(const void *aa, const void + + /* sftp ls.1 replacement for directories */ + static int +-do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) ++do_ls_dir(struct sftp_conn *conn, const char *path, const char *strip_path, int lflag) + { + int n; + u_int c = 1, colspace = 0, columns = 1; +@@ -780,7 +780,7 @@ do_ls_dir(struct sftp_conn *conn, char * + + /* sftp ls.1 replacement which handles path globs */ + static int +-do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, ++do_globbed_ls(struct sftp_conn *conn, const char *path, const char *strip_path, + int lflag) + { + char *fname, *lname; +@@ -861,7 +861,7 @@ do_globbed_ls(struct sftp_conn *conn, ch + } + + static int +-do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) ++do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) + { + struct sftp_statvfs st; + char s_used[FMT_SCALED_STRSIZE]; +diff -up openssh-6.1p1/sftp-client.c.coverity openssh-6.1p1/sftp-client.c +--- openssh-6.1p1/sftp-client.c.coverity 2012-07-02 14:15:39.000000000 +0200 ++++ openssh-6.1p1/sftp-client.c 2012-09-14 21:18:16.891332281 +0200 +@@ -149,7 +149,7 @@ get_msg(struct sftp_conn *conn, Buffer * + } + + static void +-send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, ++send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s, + u_int len) + { + Buffer msg; +@@ -165,7 +165,7 @@ send_string_request(struct sftp_conn *co + + static void + send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, +- char *s, u_int len, Attrib *a) ++ const char *s, u_int len, Attrib *a) + { + Buffer msg; + +@@ -422,7 +422,7 @@ sftp_proto_version(struct sftp_conn *con + } + + int +-do_close(struct sftp_conn *conn, char *handle, u_int handle_len) ++do_close(struct sftp_conn *conn, const char *handle, u_int handle_len) + { + u_int id, status; + Buffer msg; +@@ -447,7 +447,7 @@ do_close(struct sftp_conn *conn, char *h + + + static int +-do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, ++do_lsreaddir(struct sftp_conn *conn, const char *path, int printflag, + SFTP_DIRENT ***dir) + { + Buffer msg; +@@ -572,7 +572,7 @@ do_lsreaddir(struct sftp_conn *conn, cha + } + + int +-do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir) ++do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir) + { + return(do_lsreaddir(conn, path, 0, dir)); + } +@@ -590,7 +590,7 @@ void free_sftp_dirents(SFTP_DIRENT **s) + } + + int +-do_rm(struct sftp_conn *conn, char *path) ++do_rm(struct sftp_conn *conn, const char *path) + { + u_int status, id; + +@@ -605,7 +605,7 @@ do_rm(struct sftp_conn *conn, char *path + } + + int +-do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) ++do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int printflag) + { + u_int status, id; + +@@ -621,7 +621,7 @@ do_mkdir(struct sftp_conn *conn, char *p + } + + int +-do_rmdir(struct sftp_conn *conn, char *path) ++do_rmdir(struct sftp_conn *conn, const char *path) + { + u_int status, id; + +@@ -637,7 +637,7 @@ do_rmdir(struct sftp_conn *conn, char *p + } + + Attrib * +-do_stat(struct sftp_conn *conn, char *path, int quiet) ++do_stat(struct sftp_conn *conn, const char *path, int quiet) + { + u_int id; + +@@ -651,7 +651,7 @@ do_stat(struct sftp_conn *conn, char *pa + } + + Attrib * +-do_lstat(struct sftp_conn *conn, char *path, int quiet) ++do_lstat(struct sftp_conn *conn, const char *path, int quiet) + { + u_int id; + +@@ -685,7 +685,7 @@ do_fstat(struct sftp_conn *conn, char *h + #endif + + int +-do_setstat(struct sftp_conn *conn, char *path, Attrib *a) ++do_setstat(struct sftp_conn *conn, const char *path, Attrib *a) + { + u_int status, id; + +@@ -702,7 +702,7 @@ do_setstat(struct sftp_conn *conn, char + } + + int +-do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, ++do_fsetstat(struct sftp_conn *conn, const char *handle, u_int handle_len, + Attrib *a) + { + u_int status, id; +@@ -719,7 +719,7 @@ do_fsetstat(struct sftp_conn *conn, char + } + + char * +-do_realpath(struct sftp_conn *conn, char *path) ++do_realpath(struct sftp_conn *conn, const char *path) + { + Buffer msg; + u_int type, expected_id, count, id; +@@ -768,7 +768,7 @@ do_realpath(struct sftp_conn *conn, char + } + + int +-do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) ++do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath) + { + Buffer msg; + u_int status, id; +@@ -802,7 +802,7 @@ do_rename(struct sftp_conn *conn, char * + } + + int +-do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) ++do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) + { + Buffer msg; + u_int status, id; +@@ -835,7 +835,7 @@ do_hardlink(struct sftp_conn *conn, char + } + + int +-do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) ++do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) + { + Buffer msg; + u_int status, id; +@@ -987,7 +987,7 @@ send_read_request(struct sftp_conn *conn + } + + int +-do_download(struct sftp_conn *conn, char *remote_path, char *local_path, ++do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path, + Attrib *a, int pflag) + { + Attrib junk; +@@ -1226,7 +1226,7 @@ do_download(struct sftp_conn *conn, char + } + + static int +-download_dir_internal(struct sftp_conn *conn, char *src, char *dst, ++download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, + Attrib *dirattrib, int pflag, int printflag, int depth) + { + int i, ret = 0; +@@ -1316,7 +1316,7 @@ download_dir_internal(struct sftp_conn * + } + + int +-download_dir(struct sftp_conn *conn, char *src, char *dst, ++download_dir(struct sftp_conn *conn, const char *src, const char *dst, + Attrib *dirattrib, int pflag, int printflag) + { + char *src_canon; +@@ -1334,7 +1334,7 @@ download_dir(struct sftp_conn *conn, cha + } + + int +-do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, ++do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path, + int pflag) + { + int local_fd; +@@ -1517,7 +1517,7 @@ do_upload(struct sftp_conn *conn, char * + } + + static int +-upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, ++upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, + int pflag, int printflag, int depth) + { + int ret = 0, status; +@@ -1608,7 +1608,7 @@ upload_dir_internal(struct sftp_conn *co + } + + int +-upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag, ++upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int printflag, + int pflag) + { + char *dst_canon; +@@ -1625,7 +1625,7 @@ upload_dir(struct sftp_conn *conn, char + } + + char * +-path_append(char *p1, char *p2) ++path_append(const char *p1, const char *p2) + { + char *ret; + size_t len = strlen(p1) + strlen(p2) + 2; +diff -up openssh-6.1p1/sftp-client.h.coverity openssh-6.1p1/sftp-client.h +--- openssh-6.1p1/sftp-client.h.coverity 2010-12-04 23:02:48.000000000 +0100 ++++ openssh-6.1p1/sftp-client.h 2012-09-14 21:16:41.301906674 +0200 +@@ -56,49 +56,49 @@ struct sftp_conn *do_init(int, int, u_in + u_int sftp_proto_version(struct sftp_conn *); + + /* Close file referred to by 'handle' */ +-int do_close(struct sftp_conn *, char *, u_int); ++int do_close(struct sftp_conn *, const char *, u_int); + + /* Read contents of 'path' to NULL-terminated array 'dir' */ +-int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***); ++int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***); + + /* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */ + void free_sftp_dirents(SFTP_DIRENT **); + + /* Delete file 'path' */ +-int do_rm(struct sftp_conn *, char *); ++int do_rm(struct sftp_conn *, const char *); + + /* Create directory 'path' */ +-int do_mkdir(struct sftp_conn *, char *, Attrib *, int); ++int do_mkdir(struct sftp_conn *, const char *, Attrib *, int); + + /* Remove directory 'path' */ +-int do_rmdir(struct sftp_conn *, char *); ++int do_rmdir(struct sftp_conn *, const char *); + + /* Get file attributes of 'path' (follows symlinks) */ +-Attrib *do_stat(struct sftp_conn *, char *, int); ++Attrib *do_stat(struct sftp_conn *, const char *, int); + + /* Get file attributes of 'path' (does not follow symlinks) */ +-Attrib *do_lstat(struct sftp_conn *, char *, int); ++Attrib *do_lstat(struct sftp_conn *, const char *, int); + + /* Set file attributes of 'path' */ +-int do_setstat(struct sftp_conn *, char *, Attrib *); ++int do_setstat(struct sftp_conn *, const char *, Attrib *); + + /* Set file attributes of open file 'handle' */ +-int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); ++int do_fsetstat(struct sftp_conn *, const char *, u_int, Attrib *); + + /* Canonicalise 'path' - caller must free result */ +-char *do_realpath(struct sftp_conn *, char *); ++char *do_realpath(struct sftp_conn *, const char *); + + /* Get statistics for filesystem hosting file at "path" */ + int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); + + /* Rename 'oldpath' to 'newpath' */ +-int do_rename(struct sftp_conn *, char *, char *); ++int do_rename(struct sftp_conn *, const char *, const char *); + + /* Link 'oldpath' to 'newpath' */ +-int do_hardlink(struct sftp_conn *, char *, char *); ++int do_hardlink(struct sftp_conn *, const char *, const char *); + +-/* Rename 'oldpath' to 'newpath' */ +-int do_symlink(struct sftp_conn *, char *, char *); ++/* Symlink 'oldpath' to 'newpath' */ ++int do_symlink(struct sftp_conn *, const char *, const char *); + + /* XXX: add callbacks to do_download/do_upload so we can do progress meter */ + +@@ -106,27 +106,27 @@ int do_symlink(struct sftp_conn *, char + * Download 'remote_path' to 'local_path'. Preserve permissions and times + * if 'pflag' is set + */ +-int do_download(struct sftp_conn *, char *, char *, Attrib *, int); ++int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int); + + /* + * Recursively download 'remote_directory' to 'local_directory'. Preserve + * times if 'pflag' is set + */ +-int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int); ++int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, int); + + /* + * Upload 'local_path' to 'remote_path'. Preserve permissions and times + * if 'pflag' is set + */ +-int do_upload(struct sftp_conn *, char *, char *, int); ++int do_upload(struct sftp_conn *, const char *, const char *, int); + + /* + * Recursively upload 'local_directory' to 'remote_directory'. Preserve + * times if 'pflag' is set + */ +-int upload_dir(struct sftp_conn *, char *, char *, int, int); ++int upload_dir(struct sftp_conn *, const char *, const char *, int, int); + + /* Concatenate paths, taking care of slashes. Caller must free result. */ +-char *path_append(char *, char *); ++char *path_append(const char *, const char *); + + #endif +diff -up openssh-6.1p1/ssh-agent.c.coverity openssh-6.1p1/ssh-agent.c +--- openssh-6.1p1/ssh-agent.c.coverity 2011-06-03 06:14:16.000000000 +0200 ++++ openssh-6.1p1/ssh-agent.c 2012-09-14 21:16:41.303906683 +0200 +@@ -1147,8 +1147,8 @@ main(int ac, char **av) + sanitise_stdfd(); + + /* drop */ +- setegid(getgid()); +- setgid(getgid()); ++ (void) setegid(getgid()); ++ (void) setgid(getgid()); + + #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) + /* Disable ptrace on Linux without sgid bit */ +diff -up openssh-6.1p1/sshd.c.coverity openssh-6.1p1/sshd.c +--- openssh-6.1p1/sshd.c.coverity 2012-07-31 04:21:34.000000000 +0200 ++++ openssh-6.1p1/sshd.c 2012-09-14 21:16:41.307906705 +0200 +@@ -682,8 +682,10 @@ privsep_preauth(Authctxt *authctxt) + if (getuid() == 0 || geteuid() == 0) + privsep_preauth_child(); + setproctitle("%s", "[net]"); +- if (box != NULL) ++ if (box != NULL) { + ssh_sandbox_child(box); ++ xfree(box); ++ } + + return 0; + } +@@ -1311,6 +1313,9 @@ server_accept_loop(int *sock_in, int *so + if (num_listen_socks < 0) + break; + } ++ ++ if (fdset != NULL) ++ xfree(fdset); + } + + +@@ -1768,7 +1773,7 @@ main(int ac, char **av) + + /* Chdir to the root directory so that the current disk can be + unmounted if desired. */ +- chdir("/"); ++ (void) chdir("/"); + + /* ignore SIGPIPE */ + signal(SIGPIPE, SIG_IGN); diff --git a/openssh/patches/openssh-6.1p1-kuserok.patch b/openssh/patches/openssh-6.1p1-kuserok.patch new file mode 100644 index 0000000..7b695e0 --- /dev/null +++ b/openssh/patches/openssh-6.1p1-kuserok.patch @@ -0,0 +1,167 @@ +diff -up openssh-6.1p1/auth-krb5.c.kuserok openssh-6.1p1/auth-krb5.c +--- openssh-6.1p1/auth-krb5.c.kuserok 2012-09-14 21:08:16.941496194 +0200 ++++ openssh-6.1p1/auth-krb5.c 2012-09-14 21:08:17.063496896 +0200 +@@ -55,6 +55,20 @@ + + extern ServerOptions options; + ++int ++ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client) ++{ ++ if (options.use_kuserok) ++ return krb5_kuserok(krb5_ctx, krb5_user, client); ++ else { ++ char kuser[65]; ++ ++ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) ++ return 0; ++ return strcmp(kuser, client) == 0; ++ } ++} ++ + static int + krb5_init(void *context) + { +@@ -147,7 +161,7 @@ auth_krb5_password(Authctxt *authctxt, c + if (problem) + goto out; + +- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { ++ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { + problem = -1; + goto out; + } +diff -up openssh-6.1p1/gss-serv-krb5.c.kuserok openssh-6.1p1/gss-serv-krb5.c +--- openssh-6.1p1/gss-serv-krb5.c.kuserok 2012-09-14 21:08:17.019496642 +0200 ++++ openssh-6.1p1/gss-serv-krb5.c 2012-09-14 21:08:17.065496906 +0200 +@@ -68,6 +68,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr + int); + + static krb5_context krb_context = NULL; ++extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *); + + /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ + +@@ -115,7 +116,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client + /* NOTE: .k5login and .k5users must opened as root, not the user, + * because if they are on a krb5-protected filesystem, user credentials + * to access these files aren't available yet. */ +- if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) { ++ if (ssh_krb5_kuserok(krb_context, princ, luser) && k5login_exists) { + retval = 1; + logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", + luser, (char *)client->displayname.value); +diff -up openssh-6.1p1/servconf.c.kuserok openssh-6.1p1/servconf.c +--- openssh-6.1p1/servconf.c.kuserok 2012-09-14 21:08:16.989496471 +0200 ++++ openssh-6.1p1/servconf.c 2012-09-14 21:09:30.864868698 +0200 +@@ -152,6 +152,7 @@ initialize_server_options(ServerOptions + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->version_addendum = NULL; ++ options->use_kuserok = -1; + } + + void +@@ -301,6 +302,8 @@ fill_default_server_options(ServerOption + options->version_addendum = xstrdup(""); + if (options->show_patchlevel == -1) + options->show_patchlevel = 0; ++ if (options->use_kuserok == -1) ++ options->use_kuserok = 1; + + /* Turn privilege separation on by default */ + if (use_privsep == -1) +@@ -327,7 +330,7 @@ typedef enum { + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsRSAAuthentication, sRSAAuthentication, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +- sKerberosGetAFSToken, ++ sKerberosGetAFSToken, sKerberosUseKuserok, + sKerberosTgtPassing, sChallengeResponseAuthentication, + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, +@@ -399,11 +402,13 @@ static struct { + #else + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, + #endif ++ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, + #else + { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, + { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, ++ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, + #endif + { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, + { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, +@@ -1486,6 +1491,10 @@ process_server_config_line(ServerOptions + *activep = value; + break; + ++ case sKerberosUseKuserok: ++ intptr = &options->use_kuserok; ++ goto parse_flag; ++ + case sPermitOpen: + arg = strdelim(&cp); + if (!arg || *arg == '\0') +@@ -1769,6 +1778,7 @@ copy_set_server_options(ServerOptions *d + M_CP_INTOPT(max_authtries); + M_CP_INTOPT(ip_qos_interactive); + M_CP_INTOPT(ip_qos_bulk); ++ M_CP_INTOPT(use_kuserok); + + /* See comment in servconf.h */ + COPY_MATCH_STRING_OPTS(); +@@ -2005,6 +2015,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sUseDNS, o->use_dns); + dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); ++ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); +diff -up openssh-6.1p1/servconf.h.kuserok openssh-6.1p1/servconf.h +--- openssh-6.1p1/servconf.h.kuserok 2012-09-14 21:08:16.990496476 +0200 ++++ openssh-6.1p1/servconf.h 2012-09-14 21:08:17.071496942 +0200 +@@ -169,6 +169,7 @@ typedef struct { + + int num_permitted_opens; + ++ int use_kuserok; + char *chroot_directory; + char *revoked_keys_file; + char *trusted_user_ca_keys; +diff -up openssh-6.1p1/sshd_config.kuserok openssh-6.1p1/sshd_config +--- openssh-6.1p1/sshd_config.kuserok 2012-09-14 21:08:17.002496545 +0200 ++++ openssh-6.1p1/sshd_config 2012-09-14 21:08:17.074496957 +0200 +@@ -79,6 +79,7 @@ ChallengeResponseAuthentication no + #KerberosOrLocalPasswd yes + #KerberosTicketCleanup yes + #KerberosGetAFSToken no ++#KerberosUseKuserok yes + + # GSSAPI options + #GSSAPIAuthentication no +diff -up openssh-6.1p1/sshd_config.5.kuserok openssh-6.1p1/sshd_config.5 +--- openssh-6.1p1/sshd_config.5.kuserok 2012-09-14 21:08:17.004496556 +0200 ++++ openssh-6.1p1/sshd_config.5 2012-09-14 21:08:17.073496952 +0200 +@@ -618,6 +618,10 @@ Specifies whether to automatically destr + file on logout. + The default is + .Dq yes . ++.It Cm KerberosUseKuserok ++Specifies whether to look at .k5login file for user's aliases. ++The default is ++.Dq yes . + .It Cm KexAlgorithms + Specifies the available KEX (Key Exchange) algorithms. + Multiple algorithms must be comma-separated. +@@ -767,6 +771,7 @@ Available keywords are + .Cm HostbasedUsesNameFromPacketOnly , + .Cm KbdInteractiveAuthentication , + .Cm KerberosAuthentication , ++.Cm KerberosUseKuserok , + .Cm MaxAuthTries , + .Cm MaxSessions , + .Cm PubkeyAuthentication , diff --git a/openssh/patches/openssh-6.1p1-required-authentications.patch b/openssh/patches/openssh-6.1p1-required-authentications.patch new file mode 100644 index 0000000..bfc28ee --- /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-6.1p1-role-mls.patch b/openssh/patches/openssh-6.1p1-role-mls.patch new file mode 100644 index 0000000..4de3dae --- /dev/null +++ b/openssh/patches/openssh-6.1p1-role-mls.patch @@ -0,0 +1,934 @@ +diff -up openssh-6.1p1/auth1.c.role-mls openssh-6.1p1/auth1.c +--- openssh-6.1p1/auth1.c.role-mls 2012-11-28 17:06:43.657990103 +0100 ++++ openssh-6.1p1/auth1.c 2012-11-28 17:06:43.699989959 +0100 +@@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt) + { + u_int ulen; + char *user, *style = NULL; ++#ifdef WITH_SELINUX ++ char *role=NULL; ++#endif + + /* Get the name of the user that we wish to log in as. */ + packet_read_expect(SSH_CMSG_USER); +@@ -392,11 +395,24 @@ do_authentication(Authctxt *authctxt) + user = packet_get_cstring(&ulen); + packet_check_eom(); + ++#ifdef WITH_SELINUX ++ if ((role = strchr(user, '/')) != NULL) ++ *role++ = '\0'; ++#endif ++ + if ((style = strchr(user, ':')) != NULL) + *style++ = '\0'; ++#ifdef WITH_SELINUX ++ else ++ if (role && (style = strchr(role, ':')) != NULL) ++ *style++ = '\0'; ++#endif + + authctxt->user = user; + authctxt->style = style; ++#ifdef WITH_SELINUX ++ authctxt->role = role; ++#endif + + /* Verify that the user is a valid user. */ + if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) +diff -up openssh-6.1p1/auth2.c.role-mls openssh-6.1p1/auth2.c +--- openssh-6.1p1/auth2.c.role-mls 2012-11-28 17:06:43.661990089 +0100 ++++ openssh-6.1p1/auth2.c 2012-11-28 17:11:09.058916613 +0100 +@@ -218,6 +218,9 @@ input_userauth_request(int type, u_int32 + Authctxt *authctxt = ctxt; + Authmethod *m = NULL; + char *user, *service, *method, *style = NULL; ++#ifdef WITH_SELINUX ++ char *role = NULL; ++#endif + int authenticated = 0; + + if (authctxt == NULL) +@@ -229,6 +232,11 @@ input_userauth_request(int type, u_int32 + debug("userauth-request for user %s service %s method %s", user, service, method); + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + ++#ifdef WITH_SELINUX ++ if ((role = strchr(user, '/')) != NULL) ++ *role++ = 0; ++#endif ++ + if ((style = strchr(user, ':')) != NULL) + *style++ = 0; + +@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32 + use_privsep ? " [net]" : ""); + authctxt->service = xstrdup(service); + authctxt->style = style ? xstrdup(style) : NULL; +- if (use_privsep) ++#ifdef WITH_SELINUX ++ authctxt->role = role ? xstrdup(role) : NULL; ++#endif ++ if (use_privsep) { + mm_inform_authserv(service, style); ++#ifdef WITH_SELINUX ++ mm_inform_authrole(role); ++#endif ++ } + userauth_banner(); + if (auth2_setup_methods_lists(authctxt) != 0) + packet_disconnect("no authentication methods enabled"); +diff -up openssh-6.1p1/auth2-gss.c.role-mls openssh-6.1p1/auth2-gss.c +--- openssh-6.1p1/auth2-gss.c.role-mls 2011-05-05 06:04:11.000000000 +0200 ++++ openssh-6.1p1/auth2-gss.c 2012-11-28 17:06:43.700989956 +0100 +@@ -260,6 +260,7 @@ input_gssapi_mic(int type, u_int32_t ple + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + int authenticated = 0; ++ char *micuser; + Buffer b; + gss_buffer_desc mic, gssbuf; + u_int len; +@@ -272,7 +273,13 @@ input_gssapi_mic(int type, u_int32_t ple + mic.value = packet_get_string(&len); + mic.length = len; + +- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, ++#ifdef WITH_SELINUX ++ if (authctxt->role && (strlen(authctxt->role) > 0)) ++ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); ++ else ++#endif ++ micuser = authctxt->user; ++ ssh_gssapi_buildmic(&b, micuser, authctxt->service, + "gssapi-with-mic"); + + gssbuf.value = buffer_ptr(&b); +@@ -284,6 +291,8 @@ input_gssapi_mic(int type, u_int32_t ple + logit("GSSAPI MIC check failed"); + + buffer_free(&b); ++ if (micuser != authctxt->user) ++ xfree(micuser); + xfree(mic.value); + + authctxt->postponed = 0; +diff -up openssh-6.1p1/auth2-hostbased.c.role-mls openssh-6.1p1/auth2-hostbased.c +--- openssh-6.1p1/auth2-hostbased.c.role-mls 2012-11-28 17:06:43.669990062 +0100 ++++ openssh-6.1p1/auth2-hostbased.c 2012-11-28 17:06:43.700989956 +0100 +@@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt) + buffer_put_string(&b, session_id2, session_id2_len); + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); +- buffer_put_cstring(&b, authctxt->user); ++#ifdef WITH_SELINUX ++ if (authctxt->role) { ++ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); ++ buffer_append(&b, authctxt->user, strlen(authctxt->user)); ++ buffer_put_char(&b, '/'); ++ buffer_append(&b, authctxt->role, strlen(authctxt->role)); ++ } else ++#endif ++ buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, "hostbased"); + buffer_put_string(&b, pkalg, alen); +diff -up openssh-6.1p1/auth2-pubkey.c.role-mls openssh-6.1p1/auth2-pubkey.c +--- openssh-6.1p1/auth2-pubkey.c.role-mls 2012-11-28 17:06:43.669990062 +0100 ++++ openssh-6.1p1/auth2-pubkey.c 2012-11-28 17:06:43.700989956 +0100 +@@ -121,7 +121,15 @@ userauth_pubkey(Authctxt *authctxt) + } + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); +- buffer_put_cstring(&b, authctxt->user); ++#ifdef WITH_SELINUX ++ if (authctxt->role) { ++ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); ++ buffer_append(&b, authctxt->user, strlen(authctxt->user)); ++ buffer_put_char(&b, '/'); ++ buffer_append(&b, authctxt->role, strlen(authctxt->role)); ++ } else ++#endif ++ buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PKSERVICE ? + "ssh-userauth" : +diff -up openssh-6.1p1/auth.h.role-mls openssh-6.1p1/auth.h +--- openssh-6.1p1/auth.h.role-mls 2012-11-28 17:06:43.669990062 +0100 ++++ openssh-6.1p1/auth.h 2012-11-28 17:06:43.699989959 +0100 +@@ -59,6 +59,9 @@ struct Authctxt { + char *service; + struct passwd *pw; /* set if 'valid' */ + char *style; ++#ifdef WITH_SELINUX ++ char *role; ++#endif + void *kbdintctxt; + void *jpake_ctx; + #ifdef BSD_AUTH +diff -up openssh-6.1p1/auth-pam.c.role-mls openssh-6.1p1/auth-pam.c +--- openssh-6.1p1/auth-pam.c.role-mls 2012-11-28 17:06:43.638990168 +0100 ++++ openssh-6.1p1/auth-pam.c 2012-11-28 17:06:43.699989959 +0100 +@@ -1074,7 +1074,7 @@ is_pam_session_open(void) + * during the ssh authentication process. + */ + int +-do_pam_putenv(char *name, char *value) ++do_pam_putenv(char *name, const char *value) + { + int ret = 1; + #ifdef HAVE_PAM_PUTENV +diff -up openssh-6.1p1/auth-pam.h.role-mls openssh-6.1p1/auth-pam.h +--- openssh-6.1p1/auth-pam.h.role-mls 2004-09-11 14:17:26.000000000 +0200 ++++ openssh-6.1p1/auth-pam.h 2012-11-28 17:06:43.699989959 +0100 +@@ -38,7 +38,7 @@ void do_pam_session(void); + void do_pam_set_tty(const char *); + void do_pam_setcred(int ); + void do_pam_chauthtok(void); +-int do_pam_putenv(char *, char *); ++int do_pam_putenv(char *, const char *); + char ** fetch_pam_environment(void); + char ** fetch_pam_child_environment(void); + void free_pam_environment(char **); +diff -up openssh-6.1p1/misc.c.role-mls openssh-6.1p1/misc.c +--- openssh-6.1p1/misc.c.role-mls 2011-09-22 13:34:36.000000000 +0200 ++++ openssh-6.1p1/misc.c 2012-11-28 17:06:43.701989952 +0100 +@@ -427,6 +427,7 @@ char * + colon(char *cp) + { + int flag = 0; ++ int start = 1; + + if (*cp == ':') /* Leading colon is part of file name. */ + return NULL; +@@ -442,6 +443,13 @@ colon(char *cp) + return (cp); + if (*cp == '/') + return NULL; ++ if (start) { ++ /* Slash on beginning or after dots only denotes file name. */ ++ if (*cp == '/') ++ return (0); ++ if (*cp != '.') ++ start = 0; ++ } + } + return NULL; + } +diff -up openssh-6.1p1/monitor.c.role-mls openssh-6.1p1/monitor.c +--- openssh-6.1p1/monitor.c.role-mls 2012-11-28 17:06:43.686990004 +0100 ++++ openssh-6.1p1/monitor.c 2012-11-28 17:06:43.701989952 +0100 +@@ -148,6 +148,9 @@ int mm_answer_sign(int, Buffer *); + int mm_answer_pwnamallow(int, Buffer *); + int mm_answer_auth2_read_banner(int, Buffer *); + int mm_answer_authserv(int, Buffer *); ++#ifdef WITH_SELINUX ++int mm_answer_authrole(int, Buffer *); ++#endif + int mm_answer_authpassword(int, Buffer *); + int mm_answer_bsdauthquery(int, Buffer *); + int mm_answer_bsdauthrespond(int, Buffer *); +@@ -231,6 +234,9 @@ struct mon_table mon_dispatch_proto20[] + {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, + {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, + {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, ++#ifdef WITH_SELINUX ++ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, ++#endif + {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, + {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, + #ifdef USE_PAM +@@ -838,6 +844,9 @@ mm_answer_pwnamallow(int sock, Buffer *m + else { + /* Allow service/style information on the auth context */ + monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); ++#ifdef WITH_SELINUX ++ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); ++#endif + monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); + } + #ifdef USE_PAM +@@ -881,6 +890,25 @@ mm_answer_authserv(int sock, Buffer *m) + return (0); + } + ++#ifdef WITH_SELINUX ++int ++mm_answer_authrole(int sock, Buffer *m) ++{ ++ monitor_permit_authentications(1); ++ ++ authctxt->role = buffer_get_string(m, NULL); ++ debug3("%s: role=%s", ++ __func__, authctxt->role); ++ ++ if (strlen(authctxt->role) == 0) { ++ xfree(authctxt->role); ++ authctxt->role = NULL; ++ } ++ ++ return (0); ++} ++#endif ++ + int + mm_answer_authpassword(int sock, Buffer *m) + { +@@ -1251,7 +1279,7 @@ static int + monitor_valid_userblob(u_char *data, u_int datalen) + { + Buffer b; +- char *p; ++ char *p, *r; + u_int len; + int fail = 0; + +@@ -1277,6 +1305,8 @@ monitor_valid_userblob(u_char *data, u_i + if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + fail++; + p = buffer_get_string(&b, NULL); ++ if ((r = strchr(p, '/')) != NULL) ++ *r = '\0'; + if (strcmp(authctxt->user, p) != 0) { + logit("wrong user name passed to monitor: expected %s != %.100s", + authctxt->user, p); +@@ -1308,7 +1338,7 @@ monitor_valid_hostbasedblob(u_char *data + char *chost) + { + Buffer b; +- char *p; ++ char *p, *r; + u_int len; + int fail = 0; + +@@ -1325,6 +1355,8 @@ monitor_valid_hostbasedblob(u_char *data + if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + fail++; + p = buffer_get_string(&b, NULL); ++ if ((r = strchr(p, '/')) != NULL) ++ *r = '\0'; + if (strcmp(authctxt->user, p) != 0) { + logit("wrong user name passed to monitor: expected %s != %.100s", + authctxt->user, p); +diff -up openssh-6.1p1/monitor.h.role-mls openssh-6.1p1/monitor.h +--- openssh-6.1p1/monitor.h.role-mls 2012-11-28 17:06:43.686990004 +0100 ++++ openssh-6.1p1/monitor.h 2012-11-28 17:06:43.701989952 +0100 +@@ -31,6 +31,9 @@ + enum monitor_reqtype { + MONITOR_REQ_MODULI, MONITOR_ANS_MODULI, + MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, ++#ifdef WITH_SELINUX ++ MONITOR_REQ_AUTHROLE, ++#endif + MONITOR_REQ_SIGN, MONITOR_ANS_SIGN, + MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM, + MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER, +diff -up openssh-6.1p1/monitor_wrap.c.role-mls openssh-6.1p1/monitor_wrap.c +--- openssh-6.1p1/monitor_wrap.c.role-mls 2012-11-28 17:06:43.686990004 +0100 ++++ openssh-6.1p1/monitor_wrap.c 2012-11-28 17:06:43.702989948 +0100 +@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char * + buffer_free(&m); + } + ++/* Inform the privileged process about role */ ++ ++#ifdef WITH_SELINUX ++void ++mm_inform_authrole(char *role) ++{ ++ Buffer m; ++ ++ debug3("%s entering", __func__); ++ ++ buffer_init(&m); ++ buffer_put_cstring(&m, role ? role : ""); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); ++ ++ buffer_free(&m); ++} ++#endif ++ + /* Do the password authentication */ + int + mm_auth_password(Authctxt *authctxt, char *password) +diff -up openssh-6.1p1/monitor_wrap.h.role-mls openssh-6.1p1/monitor_wrap.h +--- openssh-6.1p1/monitor_wrap.h.role-mls 2012-11-28 17:06:43.686990004 +0100 ++++ openssh-6.1p1/monitor_wrap.h 2012-11-28 17:06:43.702989948 +0100 +@@ -42,6 +42,9 @@ int mm_is_monitor(void); + DH *mm_choose_dh(int, int, int); + int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); + void mm_inform_authserv(char *, char *); ++#ifdef WITH_SELINUX ++void mm_inform_authrole(char *); ++#endif + struct passwd *mm_getpwnamallow(const char *); + char *mm_auth2_read_banner(void); + int mm_auth_password(struct Authctxt *, char *); +diff -up openssh-6.1p1/openbsd-compat/Makefile.in.role-mls openssh-6.1p1/openbsd-compat/Makefile.in +--- openssh-6.1p1/openbsd-compat/Makefile.in.role-mls 2011-11-04 01:25:25.000000000 +0100 ++++ openssh-6.1p1/openbsd-compat/Makefile.in 2012-11-28 17:06:43.702989948 +0100 +@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport + + COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o + +-PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o ++PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o + + .c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< +diff -up openssh-6.1p1/openbsd-compat/port-linux.c.role-mls openssh-6.1p1/openbsd-compat/port-linux.c +--- openssh-6.1p1/openbsd-compat/port-linux.c.role-mls 2012-03-09 00:25:18.000000000 +0100 ++++ openssh-6.1p1/openbsd-compat/port-linux.c 2012-11-28 17:06:43.702989948 +0100 +@@ -31,68 +31,271 @@ + + #include "log.h" + #include "xmalloc.h" ++#include "servconf.h" + #include "port-linux.h" ++#include "key.h" ++#include "hostfile.h" ++#include "auth.h" + + #ifdef WITH_SELINUX + #include <selinux/selinux.h> + #include <selinux/flask.h> ++#include <selinux/context.h> + #include <selinux/get_context_list.h> ++#include <selinux/get_default_type.h> ++#include <selinux/av_permissions.h> ++ ++#ifdef HAVE_LINUX_AUDIT ++#include <libaudit.h> ++#include <unistd.h> ++#endif + + #ifndef SSH_SELINUX_UNCONFINED_TYPE + # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" + #endif + +-/* Wrapper around is_selinux_enabled() to log its return value once only */ +-int +-ssh_selinux_enabled(void) ++extern ServerOptions options; ++extern Authctxt *the_authctxt; ++extern int inetd_flag; ++extern int rexeced_flag; ++ ++/* Send audit message */ ++static int ++send_audit_message(int success, security_context_t default_context, ++ security_context_t selected_context) ++{ ++ int rc=0; ++#ifdef HAVE_LINUX_AUDIT ++ char *msg = NULL; ++ int audit_fd = audit_open(); ++ security_context_t default_raw=NULL; ++ security_context_t selected_raw=NULL; ++ rc = -1; ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return 0; /* No audit support in kernel */ ++ error("Error connecting to audit system."); ++ return rc; ++ } ++ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { ++ error("Error translating default context."); ++ default_raw = NULL; ++ } ++ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { ++ error("Error translating selected context."); ++ selected_raw = NULL; ++ } ++ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s", ++ default_raw ? default_raw : (default_context ? default_context: "?"), ++ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) { ++ error("Error allocating memory."); ++ goto out; ++ } ++ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, ++ msg, NULL, NULL, NULL, success) <= 0) { ++ error("Error sending audit message."); ++ goto out; ++ } ++ rc = 0; ++ out: ++ free(msg); ++ freecon(default_raw); ++ freecon(selected_raw); ++ close(audit_fd); ++#endif ++ return rc; ++} ++ ++static int ++mls_range_allowed(security_context_t src, security_context_t dst) + { +- static int enabled = -1; ++ struct av_decision avd; ++ int retval; ++ unsigned int bit = CONTEXT__CONTAINS; ++ ++ debug("%s: src:%s dst:%s", __func__, src, dst); ++ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); ++ if (retval || ((bit & avd.allowed) != bit)) ++ return 0; ++ ++ return 1; ++} ++ ++static int ++get_user_context(const char *sename, const char *role, const char *lvl, ++ security_context_t *sc) { ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) { ++ /* User may have requested a level completely outside of his ++ allowed range. We get a context just for auditing as the ++ range check below will certainly fail for default context. */ ++#endif ++ if (get_default_context(sename, NULL, sc) != 0) { ++ *sc = NULL; ++ return -1; ++ } ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ } ++#endif ++ if (role != NULL && role[0]) { ++ context_t con; ++ char *type=NULL; ++ if (get_default_type(role, &type) != 0) { ++ error("get_default_type: failed to get default type for '%s'", ++ role); ++ goto out; ++ } ++ con = context_new(*sc); ++ if (!con) { ++ goto out; ++ } ++ context_role_set(con, role); ++ context_type_set(con, type); ++ freecon(*sc); ++ *sc = strdup(context_str(con)); ++ context_free(con); ++ if (!*sc) ++ return -1; ++ } ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ if (lvl != NULL && lvl[0]) { ++ /* verify that the requested range is obtained */ ++ context_t con; ++ security_context_t obtained_raw; ++ security_context_t requested_raw; ++ con = context_new(*sc); ++ if (!con) { ++ goto out; ++ } ++ context_range_set(con, lvl); ++ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) { ++ context_free(con); ++ goto out; ++ } ++ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) { ++ freecon(obtained_raw); ++ context_free(con); ++ goto out; ++ } + +- if (enabled == -1) { +- enabled = (is_selinux_enabled() == 1); +- debug("SELinux support %s", enabled ? "enabled" : "disabled"); ++ debug("get_user_context: obtained context '%s' requested context '%s'", ++ obtained_raw, requested_raw); ++ if (strcmp(obtained_raw, requested_raw)) { ++ /* set the context to the real requested one but fail */ ++ freecon(requested_raw); ++ freecon(obtained_raw); ++ freecon(*sc); ++ *sc = strdup(context_str(con)); ++ context_free(con); ++ return -1; ++ } ++ freecon(requested_raw); ++ freecon(obtained_raw); ++ context_free(con); + } ++#endif ++ return 0; ++ out: ++ freecon(*sc); ++ *sc = NULL; ++ return -1; ++} + +- return (enabled); ++static void ++ssh_selinux_get_role_level(char **role, const char **level) ++{ ++ *role = NULL; ++ *level = NULL; ++ if (the_authctxt) { ++ if (the_authctxt->role != NULL) { ++ char *slash; ++ *role = xstrdup(the_authctxt->role); ++ if ((slash = strchr(*role, '/')) != NULL) { ++ *slash = '\0'; ++ *level = slash + 1; ++ } ++ } ++ } + } + + /* Return the default security context for the given username */ + static security_context_t +-ssh_selinux_getctxbyname(char *pwname) ++ssh_selinux_getctxbyname(char *pwname, ++ security_context_t *default_sc, security_context_t *user_sc) + { +- security_context_t sc = NULL; +- char *sename = NULL, *lvl = NULL; +- int r; ++ char *sename, *lvl; ++ char *role; ++ const char *reqlvl; ++ int r = 0; ++ context_t con = NULL; ++ ++ ssh_selinux_get_role_level(&role, &reqlvl); + + #ifdef HAVE_GETSEUSERBYNAME +- if (getseuserbyname(pwname, &sename, &lvl) != 0) +- return NULL; ++ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { ++ sename = NULL; ++ lvl = NULL; ++ } + #else + sename = pwname; +- lvl = NULL; ++ lvl = ""; + #endif + ++ if (r == 0) { + #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL +- r = get_default_context_with_level(sename, lvl, NULL, &sc); ++ r = get_default_context_with_level(sename, lvl, NULL, default_sc); + #else +- r = get_default_context(sename, NULL, &sc); ++ r = get_default_context(sename, NULL, default_sc); + #endif ++ } ++ ++ if (r == 0) { ++ /* If launched from xinetd, we must use current level */ ++ if (inetd_flag && !rexeced_flag) { ++ security_context_t sshdsc=NULL; ++ ++ if (getcon_raw(&sshdsc) < 0) ++ fatal("failed to allocate security context"); ++ ++ if ((con=context_new(sshdsc)) == NULL) ++ fatal("failed to allocate selinux context"); ++ reqlvl = context_range_get(con); ++ freecon(sshdsc); ++ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0) ++ /* we actually don't change level */ ++ reqlvl = ""; ++ ++ debug("%s: current connection level '%s'", __func__, reqlvl); + +- if (r != 0) { +- switch (security_getenforce()) { +- case -1: +- fatal("%s: ssh_selinux_getctxbyname: " +- "security_getenforce() failed", __func__); +- case 0: +- error("%s: Failed to get default SELinux security " +- "context for %s", __func__, pwname); +- sc = NULL; +- break; +- default: +- fatal("%s: Failed to get default SELinux security " +- "context for %s (in enforcing mode)", +- __func__, pwname); + } ++ ++ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { ++ r = get_user_context(sename, role, reqlvl, user_sc); ++ ++ if (r == 0 && reqlvl != NULL && reqlvl[0]) { ++ security_context_t default_level_sc = *default_sc; ++ if (role != NULL && role[0]) { ++ if (get_user_context(sename, role, lvl, &default_level_sc) < 0) ++ default_level_sc = *default_sc; ++ } ++ /* verify that the requested range is contained in the user range */ ++ if (mls_range_allowed(default_level_sc, *user_sc)) { ++ logit("permit MLS level %s (user range %s)", reqlvl, lvl); ++ } else { ++ r = -1; ++ error("deny MLS level %s (user range %s)", reqlvl, lvl); ++ } ++ if (default_level_sc != *default_sc) ++ freecon(default_level_sc); ++ } ++ } else { ++ *user_sc = *default_sc; ++ } ++ } ++ if (r != 0) { ++ error("%s: Failed to get default SELinux security " ++ "context for %s", __func__, pwname); + } + + #ifdef HAVE_GETSEUSERBYNAME +@@ -102,7 +305,42 @@ ssh_selinux_getctxbyname(char *pwname) + xfree(lvl); + #endif + +- return sc; ++ if (role != NULL) ++ xfree(role); ++ if (con) ++ context_free(con); ++ ++ return (r); ++} ++ ++/* Setup environment variables for pam_selinux */ ++static int ++ssh_selinux_setup_pam_variables(void) ++{ ++ const char *reqlvl; ++ char *role; ++ char *use_current; ++ int rv; ++ ++ debug3("%s: setting execution context", __func__); ++ ++ ssh_selinux_get_role_level(&role, &reqlvl); ++ ++ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); ++ ++ if (inetd_flag && !rexeced_flag) { ++ use_current = "1"; ++ } else { ++ use_current = ""; ++ rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); ++ } ++ ++ rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); ++ ++ if (role != NULL) ++ xfree(role); ++ ++ return rv; + } + + /* Set the execution context to the default for the specified user */ +@@ -110,28 +348,71 @@ void + ssh_selinux_setup_exec_context(char *pwname) + { + security_context_t user_ctx = NULL; ++ int r = 0; ++ security_context_t default_ctx = NULL; + + if (!ssh_selinux_enabled()) + return; + ++ if (options.use_pam) { ++ /* do not compute context, just setup environment for pam_selinux */ ++ if (ssh_selinux_setup_pam_variables()) { ++ switch (security_getenforce()) { ++ case -1: ++ fatal("%s: security_getenforce() failed", __func__); ++ case 0: ++ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", ++ __func__); ++ break; ++ default: ++ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", ++ __func__); ++ } ++ } ++ return; ++ } ++ + debug3("%s: setting execution context", __func__); + +- user_ctx = ssh_selinux_getctxbyname(pwname); +- if (setexeccon(user_ctx) != 0) { ++ r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); ++ if (r >= 0) { ++ r = setexeccon(user_ctx); ++ if (r < 0) { ++ error("%s: Failed to set SELinux execution context %s for %s", ++ __func__, user_ctx, pwname); ++ } ++#ifdef HAVE_SETKEYCREATECON ++ else if (setkeycreatecon(user_ctx) < 0) { ++ error("%s: Failed to set SELinux keyring creation context %s for %s", ++ __func__, user_ctx, pwname); ++ } ++#endif ++ } ++ if (user_ctx == NULL) { ++ user_ctx = default_ctx; ++ } ++ if (r < 0 || user_ctx != default_ctx) { ++ /* audit just the case when user changed a role or there was ++ a failure */ ++ send_audit_message(r >= 0, default_ctx, user_ctx); ++ } ++ if (r < 0) { + switch (security_getenforce()) { + case -1: + fatal("%s: security_getenforce() failed", __func__); + case 0: +- error("%s: Failed to set SELinux execution " +- "context for %s", __func__, pwname); ++ error("%s: SELinux failure. Continuing in permissive mode.", ++ __func__); + break; + default: +- fatal("%s: Failed to set SELinux execution context " +- "for %s (in enforcing mode)", __func__, pwname); ++ fatal("%s: SELinux failure. Aborting connection.", ++ __func__); + } + } +- if (user_ctx != NULL) ++ if (user_ctx != NULL && user_ctx != default_ctx) + freecon(user_ctx); ++ if (default_ctx != NULL) ++ freecon(default_ctx); + + debug3("%s: done", __func__); + } +@@ -149,7 +430,10 @@ ssh_selinux_setup_pty(char *pwname, cons + + debug3("%s: setting TTY context on %s", __func__, tty); + +- user_ctx = ssh_selinux_getctxbyname(pwname); ++ if (getexeccon(&user_ctx) < 0) { ++ error("%s: getexeccon: %s", __func__, strerror(errno)); ++ goto out; ++ } + + /* XXX: should these calls fatal() upon failure in enforcing mode? */ + +@@ -221,21 +505,6 @@ ssh_selinux_change_context(const char *n + xfree(newctx); + } + +-void +-ssh_selinux_setfscreatecon(const char *path) +-{ +- security_context_t context; +- +- if (!ssh_selinux_enabled()) +- return; +- if (path == NULL) { +- setfscreatecon(NULL); +- return; +- } +- if (matchpathcon(path, 0700, &context) == 0) +- setfscreatecon(context); +-} +- + #endif /* WITH_SELINUX */ + + #ifdef LINUX_OOM_ADJUST +diff -up openssh-6.1p1/openbsd-compat/port-linux_part_2.c.role-mls openssh-6.1p1/openbsd-compat/port-linux_part_2.c +--- openssh-6.1p1/openbsd-compat/port-linux_part_2.c.role-mls 2012-11-28 17:06:43.703989944 +0100 ++++ openssh-6.1p1/openbsd-compat/port-linux_part_2.c 2012-11-28 17:06:43.703989944 +0100 +@@ -0,0 +1,75 @@ ++/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ ++ ++/* ++ * Copyright (c) 2005 Daniel Walsh dwalsh@redhat.com ++ * Copyright (c) 2006 Damien Miller djm@openbsd.org ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/* ++ * Linux-specific portability code - just SELinux support at present ++ */ ++ ++#include "includes.h" ++ ++#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) ++#include <errno.h> ++#include <stdarg.h> ++#include <string.h> ++#include <stdio.h> ++ ++#include "log.h" ++#include "xmalloc.h" ++#include "port-linux.h" ++#include "key.h" ++#include "hostfile.h" ++#include "auth.h" ++ ++#ifdef WITH_SELINUX ++#include <selinux/selinux.h> ++#include <selinux/flask.h> ++#include <selinux/get_context_list.h> ++ ++/* Wrapper around is_selinux_enabled() to log its return value once only */ ++int ++ssh_selinux_enabled(void) ++{ ++ static int enabled = -1; ++ ++ if (enabled == -1) { ++ enabled = (is_selinux_enabled() == 1); ++ debug("SELinux support %s", enabled ? "enabled" : "disabled"); ++ } ++ ++ return (enabled); ++} ++ ++void ++ssh_selinux_setfscreatecon(const char *path) ++{ ++ security_context_t context; ++ ++ if (!ssh_selinux_enabled()) ++ return; ++ if (path == NULL) { ++ setfscreatecon(NULL); ++ return; ++ } ++ if (matchpathcon(path, 0700, &context) == 0) ++ setfscreatecon(context); ++} ++ ++#endif /* WITH_SELINUX */ ++ ++#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ +diff -up openssh-6.1p1/sshd.c.role-mls openssh-6.1p1/sshd.c +--- openssh-6.1p1/sshd.c.role-mls 2012-11-28 17:06:43.688989996 +0100 ++++ openssh-6.1p1/sshd.c 2012-11-28 17:06:43.703989944 +0100 +@@ -2101,6 +2101,9 @@ main(int ac, char **av) + restore_uid(); + } + #endif ++#ifdef WITH_SELINUX ++ ssh_selinux_setup_exec_context(authctxt->pw->pw_name); ++#endif + #ifdef USE_PAM + if (options.use_pam) { + do_pam_setcred(1); diff --git a/openssh/patches/openssh-6.1p1-vendor.patch b/openssh/patches/openssh-6.1p1-vendor.patch new file mode 100644 index 0000000..9cb326d --- /dev/null +++ b/openssh/patches/openssh-6.1p1-vendor.patch @@ -0,0 +1,158 @@ +diff -up openssh-6.1p1/configure.ac.vendor openssh-6.1p1/configure.ac +--- openssh-6.1p1/configure.ac.vendor 2012-09-14 20:36:49.153085211 +0200 ++++ openssh-6.1p1/configure.ac 2012-09-14 20:36:49.559088133 +0200 +@@ -4303,6 +4303,12 @@ AC_ARG_WITH([lastlog], + fi + ] + ) ++AC_ARG_ENABLE(vendor-patchlevel, ++ [ --enable-vendor-patchlevel=TAG specify a vendor patch level], ++ [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.]) ++ SSH_VENDOR_PATCHLEVEL="$enableval"], ++ [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.]) ++ SSH_VENDOR_PATCHLEVEL=none]) + + dnl lastlog, [uw]tmpx? detection + dnl NOTE: set the paths in the platform section to avoid the +@@ -4529,6 +4535,7 @@ echo " Translate v4 in v6 hack + echo " BSD Auth support: $BSD_AUTH_MSG" + echo " Random number source: $RAND_MSG" + echo " Privsep sandbox style: $SANDBOX_STYLE" ++echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL" + + echo "" + +diff -up openssh-6.1p1/servconf.c.vendor openssh-6.1p1/servconf.c +--- openssh-6.1p1/servconf.c.vendor 2012-09-14 20:36:49.124085002 +0200 ++++ openssh-6.1p1/servconf.c 2012-09-14 20:50:34.995972516 +0200 +@@ -128,6 +128,7 @@ initialize_server_options(ServerOptions + options->max_authtries = -1; + options->max_sessions = -1; + options->banner = NULL; ++ options->show_patchlevel = -1; + options->use_dns = -1; + options->client_alive_interval = -1; + options->client_alive_count_max = -1; +@@ -289,6 +290,9 @@ fill_default_server_options(ServerOption + options->ip_qos_bulk = IPTOS_THROUGHPUT; + if (options->version_addendum == NULL) + options->version_addendum = xstrdup(""); ++ if (options->show_patchlevel == -1) ++ options->show_patchlevel = 0; ++ + /* Turn privilege separation on by default */ + if (use_privsep == -1) + use_privsep = PRIVSEP_NOSANDBOX; +@@ -326,7 +330,7 @@ typedef enum { + sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, + sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, + sMaxStartups, sMaxAuthTries, sMaxSessions, +- sBanner, sUseDNS, sHostbasedAuthentication, ++ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, + sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, + sClientAliveCountMax, sAuthorizedKeysFile, + sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, +@@ -441,6 +445,7 @@ static struct { + { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, + { "maxsessions", sMaxSessions, SSHCFG_ALL }, + { "banner", sBanner, SSHCFG_ALL }, ++ { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL }, + { "usedns", sUseDNS, SSHCFG_GLOBAL }, + { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, + { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, +@@ -1162,6 +1167,10 @@ process_server_config_line(ServerOptions + multistate_ptr = multistate_privsep; + goto parse_multistate; + ++ case sShowPatchLevel: ++ intptr = &options->show_patchlevel; ++ goto parse_flag; ++ + case sAllowUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_allow_users >= MAX_ALLOW_USERS) +@@ -1956,6 +1965,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sUseLogin, o->use_login); + dump_cfg_fmtint(sCompression, o->compression); + dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); ++ dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); + dump_cfg_fmtint(sUseDNS, o->use_dns); + dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); +diff -up openssh-6.1p1/servconf.h.vendor openssh-6.1p1/servconf.h +--- openssh-6.1p1/servconf.h.vendor 2012-09-14 20:36:49.125085009 +0200 ++++ openssh-6.1p1/servconf.h 2012-09-14 20:36:49.564088168 +0200 +@@ -140,6 +140,7 @@ typedef struct { + int max_authtries; + int max_sessions; + char *banner; /* SSH-2 banner message */ ++ int show_patchlevel; /* Show vendor patch level to clients */ + int use_dns; + int client_alive_interval; /* + * poke the client this often to +diff -up openssh-6.1p1/sshd_config.vendor openssh-6.1p1/sshd_config +--- openssh-6.1p1/sshd_config.vendor 2012-09-14 20:36:49.507087759 +0200 ++++ openssh-6.1p1/sshd_config 2012-09-14 20:36:49.565088175 +0200 +@@ -114,6 +114,7 @@ UsePrivilegeSeparation sandbox # Defaul + #Compression delayed + #ClientAliveInterval 0 + #ClientAliveCountMax 3 ++#ShowPatchLevel no + #UseDNS yes + #PidFile /var/run/sshd.pid + #MaxStartups 10 +diff -up openssh-6.1p1/sshd_config.0.vendor openssh-6.1p1/sshd_config.0 +--- openssh-6.1p1/sshd_config.0.vendor 2012-09-14 20:36:49.510087780 +0200 ++++ openssh-6.1p1/sshd_config.0 2012-09-14 20:36:49.567088190 +0200 +@@ -558,6 +558,11 @@ DESCRIPTION + Defines the number of bits in the ephemeral protocol version 1 + server key. The minimum value is 512, and the default is 1024. + ++ ShowPatchLevel ++ Specifies whether sshd will display the specific patch level of ++ the binary in the server identification string. The patch level ++ is set at compile-time. The default is M-bM-^@M-^\noM-bM-^@M-^]. ++ + StrictModes + Specifies whether sshd(8) should check file modes and ownership + of the user's files and home directory before accepting login. +diff -up openssh-6.1p1/sshd_config.5.vendor openssh-6.1p1/sshd_config.5 +--- openssh-6.1p1/sshd_config.5.vendor 2012-09-14 20:36:49.512087794 +0200 ++++ openssh-6.1p1/sshd_config.5 2012-09-14 20:36:49.568088198 +0200 +@@ -978,6 +978,14 @@ This option applies to protocol version + .It Cm ServerKeyBits + Defines the number of bits in the ephemeral protocol version 1 server key. + The minimum value is 512, and the default is 1024. ++.It Cm ShowPatchLevel ++Specifies whether ++.Nm sshd ++will display the patch level of the binary in the identification string. ++The patch level is set at compile-time. ++The default is ++.Dq no . ++This option applies to protocol version 1 only. + .It Cm StrictModes + Specifies whether + .Xr sshd 8 +diff -up openssh-6.1p1/sshd.c.vendor openssh-6.1p1/sshd.c +--- openssh-6.1p1/sshd.c.vendor 2012-09-14 20:36:49.399086981 +0200 ++++ openssh-6.1p1/sshd.c 2012-09-14 20:47:30.696088744 +0200 +@@ -433,7 +433,7 @@ sshd_exchange_identification(int sock_in + } + + xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", +- major, minor, SSH_VERSION, ++ major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, + *options.version_addendum == '\0' ? "" : " ", + options.version_addendum, newline); + +@@ -1635,7 +1635,8 @@ main(int ac, char **av) + exit(1); + } + +- debug("sshd version %.100s", SSH_RELEASE); ++ debug("sshd version %.100s", ++ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_RELEASE); + + /* Store privilege separation user for later use if required. */ + if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
hooks/post-receive -- IPFire 3.x development tree