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 a529ab92ff5d35fdfe4119f3bbb80ca423af114e (commit) via 0570d29f6663bae85fe3bf35ac21df781fade278 (commit) via 9d8fd3adf9b94fe838a4baa3a6d7814dcc89b9cd (commit) from 216547eae7ead212bf6176561a6de69e227b1b2b (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 a529ab92ff5d35fdfe4119f3bbb80ca423af114e Merge: 0570d29 216547e Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Oct 31 23:54:34 2011 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/ipfire-3.x
commit 0570d29f6663bae85fe3bf35ac21df781fade278 Merge: 2763814 9d8fd3a Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Oct 31 22:05:58 2011 +0100
Merge remote-tracking branch 'stevee/openssh'
commit 9d8fd3adf9b94fe838a4baa3a6d7814dcc89b9cd Author: Stefan Schantl stefan.schantl@ipfire.org Date: Sat Oct 29 20:27:18 2011 +0200
openssh: Update to 5.9p1.
Fixes #248.
-----------------------------------------------------------------------
Summary of changes: openssh/openssh.nm | 51 +- openssh/patches/openssh-5.6p1-keygen.patch | 80 -- openssh/patches/openssh-5.6p1-redhat.patch | 4 +- openssh/patches/openssh-5.8p1-getaddrinfo.patch | 11 + openssh/patches/openssh-5.8p1-keyperm.patch | 25 + openssh/patches/openssh-5.8p1-localdomain.patch | 14 + openssh/patches/openssh-5.8p1-packet.patch | 12 + openssh/patches/openssh-5.8p1-randclean.patch | 13 - openssh/patches/openssh-5.8p1-selinux.patch | 12 - openssh/patches/openssh-5.8p2-askpass-ld.patch | 18 + openssh/patches/openssh-5.8p2-force_krb.patch | 288 +++++++ ...openssh-5.8p2-remove-stale-control-socket.patch | 13 + openssh/patches/openssh-5.8p2-sigpipe.patch | 12 + openssh/patches/openssh-5.9p1-2auth.patch | 354 ++++++++ ...-keys-command.patch => openssh-5.9p1-akc.patch} | 109 ++-- openssh/patches/openssh-5.9p1-coverity.patch | 844 ++++++++++++++++++++ ...h-5.2p1-edns.patch => openssh-5.9p1-edns.patch} | 24 +- openssh/patches/openssh-5.9p1-entropy.patch | 251 ++++++ ...6p1-redhat.patch => openssh-5.9p1-ipfire.patch} | 59 +- openssh/patches/openssh-5.9p1-ipv6man.patch | 24 + openssh/patches/openssh-5.9p1-keygen.patch | 80 ++ ...1-kuserok.patch => openssh-5.9p1-kuserok.patch} | 90 +- ...ssh-5.8p1-mls.patch => openssh-5.9p1-mls.patch} | 56 +- openssh/patches/openssh-5.9p1-randclean.patch | 13 + ...selinux-role.patch => openssh-5.9p1-role.patch} | 266 +++--- openssh/patches/openssh-5.9p1-sftp-chroot.patch | 63 ++ openssh/patches/openssh-5.9p1-vendor.patch | 157 ++++ 27 files changed, 2526 insertions(+), 417 deletions(-) delete mode 100644 openssh/patches/openssh-5.6p1-keygen.patch create mode 100644 openssh/patches/openssh-5.8p1-getaddrinfo.patch create mode 100644 openssh/patches/openssh-5.8p1-keyperm.patch create mode 100644 openssh/patches/openssh-5.8p1-localdomain.patch create mode 100644 openssh/patches/openssh-5.8p1-packet.patch delete mode 100644 openssh/patches/openssh-5.8p1-randclean.patch delete mode 100644 openssh/patches/openssh-5.8p1-selinux.patch create mode 100644 openssh/patches/openssh-5.8p2-askpass-ld.patch create mode 100644 openssh/patches/openssh-5.8p2-force_krb.patch create mode 100644 openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch create mode 100644 openssh/patches/openssh-5.8p2-sigpipe.patch create mode 100644 openssh/patches/openssh-5.9p1-2auth.patch rename openssh/patches/{openssh-5.8p1-authorized-keys-command.patch => openssh-5.9p1-akc.patch} (81%) create mode 100644 openssh/patches/openssh-5.9p1-coverity.patch rename openssh/patches/{openssh-5.2p1-edns.patch => openssh-5.9p1-edns.patch} (62%) create mode 100644 openssh/patches/openssh-5.9p1-entropy.patch copy openssh/patches/{openssh-5.6p1-redhat.patch => openssh-5.9p1-ipfire.patch} (67%) create mode 100644 openssh/patches/openssh-5.9p1-ipv6man.patch create mode 100644 openssh/patches/openssh-5.9p1-keygen.patch rename openssh/patches/{openssh-5.8p1-kuserok.patch => openssh-5.9p1-kuserok.patch} (60%) rename openssh/patches/{openssh-5.8p1-mls.patch => openssh-5.9p1-mls.patch} (89%) create mode 100644 openssh/patches/openssh-5.9p1-randclean.patch rename openssh/patches/{openssh-5.8p1-selinux-role.patch => openssh-5.9p1-role.patch} (77%) create mode 100644 openssh/patches/openssh-5.9p1-sftp-chroot.patch create mode 100644 openssh/patches/openssh-5.9p1-vendor.patch
Difference in files: diff --git a/openssh/openssh.nm b/openssh/openssh.nm index 55bf24d..2555f7e 100644 --- a/openssh/openssh.nm +++ b/openssh/openssh.nm @@ -4,27 +4,28 @@ ###############################################################################
name = openssh -version = 5.8p1 -release = 9 +version = 5.9p1 +release = 1
-maintainer = groups = Application/Internet url = http://www.openssh.com/portable.html license = MIT summary = An open source implementation of SSH protocol versions 1 and 2.
description - SSH (Secure SHell) is a program for logging into and executing \ - commands on a remote machine. SSH is intended to replace rlogin and \ - rsh, and to provide secure encrypted communications between two \ + SSH (Secure SHell) is a program for logging into and executing + commands on a remote machine. SSH is intended to replace rlogin and + rsh, and to provide secure encrypted communications between two untrusted hosts over an insecure network. end
-source_dl = +source_dl = http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/
build requires audit-devel + autoconf + automake libselinux-devel nss-devel openssl-devel>=1.0.0d-2 @@ -34,22 +35,35 @@ build
# Apply patches in a special order patches - openssh-5.6p1-redhat.patch + openssh-5.9p1-coverity.patch openssh-5.8p1-fingerprint.patch - openssh-5.8p1-authorized-keys-command.patch - openssh-5.8p1-selinux.patch - openssh-5.8p1-selinux-role.patch - openssh-5.8p1-mls.patch - openssh-5.6p1-keygen.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-5.9p1-sftp-chroot.patch + openssh-5.9p1-akc.patch + openssh-5.9p1-keygen.patch openssh-5.2p1-allow-ip-opts.patch - openssh-5.8p1-randclean.patch - openssh-5.8p1-kuserok.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-5.5p1-x11.patch openssh-5.6p1-exit-deadlock.patch openssh-5.1p1-askpass-progress.patch openssh-4.3p2-askpass-grab-info.patch - openssh-5.2p1-edns.patch + openssh-5.9p1-edns.patch 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-5.8p2-force_krb.patch + openssh-5.9p1-kuserok.patch end
configure_options += \ @@ -60,9 +74,12 @@ build --with-privsep-path=/var/lib/sshd \ --with-pam \ --with-selinux \ - --with-nss \ --with-audit=linux
+ prepare_cmds + autoreconf + end + install_cmds mkdir -pv %{BUILDROOT}/etc/ssh cp -vf %{DIR_SOURCE}/sshd_config %{BUILDROOT}/etc/ssh/sshd_config diff --git a/openssh/patches/openssh-5.2p1-edns.patch b/openssh/patches/openssh-5.2p1-edns.patch deleted file mode 100644 index f3e431e..0000000 --- a/openssh/patches/openssh-5.2p1-edns.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff -up openssh-5.2p1/dns.c.rh205842 openssh-5.2p1/dns.c ---- openssh-5.2p1/dns.c.rh205842 2009-07-27 16:25:28.000000000 +0200 -+++ openssh-5.2p1/dns.c 2009-07-27 16:40:59.000000000 +0200 -@@ -176,6 +176,7 @@ verify_host_key_dns(const char *hostname - { - u_int counter; - int result; -+ unsigned int rrset_flags = 0; - struct rrsetinfo *fingerprints = NULL; - - u_int8_t hostkey_algorithm; -@@ -199,8 +200,19 @@ verify_host_key_dns(const char *hostname - return -1; - } - -+ /* -+ * Original getrrsetbyname function, found on OpenBSD for example, -+ * doesn't accept any flag and prerequisite for obtaining AD bit in -+ * DNS response is set by "options edns0" in resolv.conf. -+ * -+ * Our version is more clever and use RRSET_FORCE_EDNS0 flag. -+ */ -+#ifndef HAVE_GETRRSETBYNAME -+ rrset_flags |= RRSET_FORCE_EDNS0; -+#endif - result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, -- DNS_RDATATYPE_SSHFP, 0, &fingerprints); -+ DNS_RDATATYPE_SSHFP, rrset_flags, &fingerprints); -+ - if (result) { - verbose("DNS lookup error: %s", dns_result_totext(result)); - return -1; -diff -up openssh-5.2p1/openbsd-compat/getrrsetbyname.c.rh205842 openssh-5.2p1/openbsd-compat/getrrsetbyname.c ---- openssh-5.2p1/openbsd-compat/getrrsetbyname.c.rh205842 2009-07-27 16:22:23.000000000 +0200 -+++ openssh-5.2p1/openbsd-compat/getrrsetbyname.c 2009-07-27 16:41:55.000000000 +0200 -@@ -209,8 +209,8 @@ getrrsetbyname(const char *hostname, uns - goto fail; - } - -- /* don't allow flags yet, unimplemented */ -- if (flags) { -+ /* Allow RRSET_FORCE_EDNS0 flag only. */ -+ if ((flags & !RRSET_FORCE_EDNS0) != 0) { - result = ERRSET_INVAL; - goto fail; - } -@@ -226,9 +226,9 @@ getrrsetbyname(const char *hostname, uns - #endif /* DEBUG */ - - #ifdef RES_USE_DNSSEC -- /* turn on DNSSEC if EDNS0 is configured */ -- if (_resp->options & RES_USE_EDNS0) -- _resp->options |= RES_USE_DNSSEC; -+ /* turn on DNSSEC if required */ -+ if (flags & RRSET_FORCE_EDNS0) -+ _resp->options |= (RES_USE_EDNS0|RES_USE_DNSSEC); - #endif /* RES_USE_DNSEC */ - - /* make query */ -diff -up openssh-5.2p1/openbsd-compat/getrrsetbyname.h.rh205842 openssh-5.2p1/openbsd-compat/getrrsetbyname.h ---- openssh-5.2p1/openbsd-compat/getrrsetbyname.h.rh205842 2009-07-27 16:35:02.000000000 +0200 -+++ openssh-5.2p1/openbsd-compat/getrrsetbyname.h 2009-07-27 16:36:09.000000000 +0200 -@@ -72,6 +72,9 @@ - #ifndef RRSET_VALIDATED - # define RRSET_VALIDATED 1 - #endif -+#ifndef RRSET_FORCE_EDNS0 -+# define RRSET_FORCE_EDNS0 0x0001 -+#endif - - /* - * Return codes for getrrsetbyname() diff --git a/openssh/patches/openssh-5.6p1-keygen.patch b/openssh/patches/openssh-5.6p1-keygen.patch deleted file mode 100644 index 9d7fce2..0000000 --- a/openssh/patches/openssh-5.6p1-keygen.patch +++ /dev/null @@ -1,80 +0,0 @@ -diff -up openssh-5.6p1/ssh-keygen.0.keygen openssh-5.6p1/ssh-keygen.0 ---- openssh-5.6p1/ssh-keygen.0.keygen 2010-08-22 16:30:03.000000000 +0200 -+++ openssh-5.6p1/ssh-keygen.0 2010-08-23 12:37:19.000000000 +0200 -@@ -4,7 +4,7 @@ NAME - ssh-keygen - authentication key generation, management and conversion - - SYNOPSIS -- ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment] -+ ssh-keygen [-q] [-o] [-b bits] -t type [-N new_passphrase] [-C comment] - [-f output_keyfile] - ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] - ssh-keygen -i [-m key_format] [-f input_keyfile] -@@ -232,6 +232,8 @@ DESCRIPTION - - -q Silence ssh-keygen. Used by /etc/rc when creating a new key. - -+ -o Overwrite the key without prompting user. -+ - -R hostname - Removes all keys belonging to hostname from a known_hosts file. - This option is useful to delete hashed hosts (see the -H option -diff -up openssh-5.6p1/ssh-keygen.1.keygen openssh-5.6p1/ssh-keygen.1 ---- openssh-5.6p1/ssh-keygen.1.keygen 2010-08-05 05:05:32.000000000 +0200 -+++ openssh-5.6p1/ssh-keygen.1 2010-08-23 12:36:25.000000000 +0200 -@@ -47,6 +47,7 @@ - .Bk -words - .Nm ssh-keygen - .Op Fl q -+.Op Fl o - .Op Fl b Ar bits - .Fl t Ar type - .Op Fl N Ar new_passphrase -@@ -397,6 +398,8 @@ Silence - Used by - .Pa /etc/rc - when creating a new key. -+.It Fl o -+Overwrite the key without prompting user. - .It Fl R Ar hostname - Removes all keys belonging to - .Ar hostname -diff -up openssh-5.6p1/ssh-keygen.c.keygen openssh-5.6p1/ssh-keygen.c ---- openssh-5.6p1/ssh-keygen.c.keygen 2010-08-05 05:05:32.000000000 +0200 -+++ openssh-5.6p1/ssh-keygen.c 2010-08-23 12:34:40.000000000 +0200 -@@ -72,6 +72,7 @@ int change_passphrase = 0; - int change_comment = 0; - - int quiet = 0; -+int overwrite = 0; - - int log_level = SYSLOG_LEVEL_INFO; - -@@ -1798,7 +1799,7 @@ main(int argc, char **argv) - exit(1); - } - -- while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:" -+ while ((opt = getopt(argc, argv, "degiqopclBHLhvxXyF:b:f:t:D:I:P:m:N:n:" - "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) { - switch (opt) { - case 'b': -@@ -1878,6 +1879,9 @@ main(int argc, char **argv) - case 'q': - quiet = 1; - break; -+ case 'o': -+ overwrite = 1; -+ break; - case 'e': - case 'x': - /* export key */ -@@ -2124,7 +2128,7 @@ main(int argc, char **argv) - } - } - /* If the file already exists, ask the user to confirm. */ -- if (stat(identity_file, &st) >= 0) { -+ if (!overwrite && stat(identity_file, &st) >= 0) { - char yesno[3]; - printf("%s already exists.\n", identity_file); - printf("Overwrite (y/n)? "); diff --git a/openssh/patches/openssh-5.6p1-redhat.patch b/openssh/patches/openssh-5.6p1-redhat.patch index f4560a9..d1df8c1 100644 --- a/openssh/patches/openssh-5.6p1-redhat.patch +++ b/openssh/patches/openssh-5.6p1-redhat.patch @@ -1,7 +1,7 @@ diff -up openssh-5.6p1/ssh_config.redhat openssh-5.6p1/ssh_config --- openssh-5.6p1/ssh_config.redhat 2010-01-12 09:40:27.000000000 +0100 +++ openssh-5.6p1/ssh_config 2010-09-03 15:21:17.000000000 +0200 -@@ -45,3 +45,14 @@ +@@ -45,3 +45,16 @@ # PermitLocalCommand no # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com @@ -11,6 +11,8 @@ diff -up openssh-5.6p1/ssh_config.redhat openssh-5.6p1/ssh_config +# to the original X11 display. As virtually no X11 client supports the untrusted +# mode correctly we set this to yes. + ForwardX11Trusted yes ++# Look up the host key SSHFP records ++ VerifyHostKeyDNS ask +# Send locale-related environment variables + SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES + SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT diff --git a/openssh/patches/openssh-5.8p1-authorized-keys-command.patch b/openssh/patches/openssh-5.8p1-authorized-keys-command.patch deleted file mode 100644 index 356adfa..0000000 --- a/openssh/patches/openssh-5.8p1-authorized-keys-command.patch +++ /dev/null @@ -1,447 +0,0 @@ -diff -up openssh-5.8p1/auth2-pubkey.c.akc openssh-5.8p1/auth2-pubkey.c ---- openssh-5.8p1/auth2-pubkey.c.akc 2011-02-10 13:21:27.000000000 +0100 -+++ openssh-5.8p1/auth2-pubkey.c 2011-02-10 13:21:28.000000000 +0100 -@@ -27,6 +27,7 @@ - - #include <sys/types.h> - #include <sys/stat.h> -+#include <sys/wait.h> - - #include <fcntl.h> - #include <pwd.h> -@@ -268,27 +269,15 @@ match_principals_file(char *file, struct - - /* return 1 if user allows given key */ - static int --user_key_allowed2(struct passwd *pw, Key *key, char *file) -+user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw) - { - char line[SSH_MAX_PUBKEY_BYTES]; - const char *reason; - int found_key = 0; -- FILE *f; - u_long linenum = 0; - Key *found; - char *fp; - -- /* Temporarily use the user's uid. */ -- temporarily_use_uid(pw); -- -- debug("trying public key file %s", file); -- f = auth_openkeyfile(file, pw, options.strict_modes); -- -- if (!f) { -- restore_uid(); -- return 0; -- } -- - found_key = 0; - found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); - -@@ -381,8 +370,6 @@ user_key_allowed2(struct passwd *pw, Key - break; - } - } -- restore_uid(); -- fclose(f); - key_free(found); - if (!found_key) - debug2("key not found"); -@@ -444,13 +431,191 @@ user_cert_trusted_ca(struct passwd *pw, - return ret; - } - --/* check whether given key is in .ssh/authorized_keys* */ -+/* return 1 if user allows given key */ -+static int -+user_key_allowed2(struct passwd *pw, Key *key, char *file) -+{ -+ FILE *f; -+ int found_key = 0; -+ -+ /* Temporarily use the user's uid. */ -+ temporarily_use_uid(pw); -+ -+ debug("trying public key file %s", file); -+ f = auth_openkeyfile(file, pw, options.strict_modes); -+ -+ if (f) { -+ found_key = user_search_key_in_file (f, file, key, pw); -+ fclose(f); -+ } -+ -+ restore_uid(); -+ return found_key; -+} -+ -+#ifdef WITH_AUTHORIZED_KEYS_COMMAND -+ -+#define WHITESPACE " \t\r\n" -+ -+/* return 1 if user allows given key */ -+static int -+user_key_via_command_allowed2(struct passwd *pw, Key *key) -+{ -+ FILE *f; -+ int found_key = 0; -+ char *progname = NULL; -+ char *cp; -+ struct passwd *runas_pw; -+ struct stat st; -+ int childdescriptors[2], i; -+ pid_t pstat, pid, child; -+ -+ if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/') -+ return -1; -+ -+ /* get the run as identity from config */ -+ runas_pw = (options.authorized_keys_command_runas == NULL)? pw -+ : getpwnam (options.authorized_keys_command_runas); -+ if (!runas_pw) { -+ error("%s: getpwnam("%s"): %s", __func__, -+ options.authorized_keys_command_runas, strerror(errno)); -+ return 0; -+ } -+ -+ /* Temporarily use the specified uid. */ -+ if (runas_pw->pw_uid != 0) -+ temporarily_use_uid(runas_pw); -+ -+ progname = xstrdup(options.authorized_keys_command); -+ -+ debug3("%s: checking program '%s'", __func__, progname); -+ -+ if (stat (progname, &st) < 0) { -+ error("%s: stat("%s"): %s", __func__, -+ progname, strerror(errno)); -+ goto go_away; -+ } -+ -+ if (st.st_uid != 0 || (st.st_mode & 022) != 0) { -+ error("bad ownership or modes for AuthorizedKeysCommand "%s"", -+ progname); -+ goto go_away; -+ } -+ -+ if (!S_ISREG(st.st_mode)) { -+ error("AuthorizedKeysCommand "%s" is not a regular file", -+ progname); -+ goto go_away; -+ } -+ -+ /* -+ * Descend the path, checking that each component is a -+ * root-owned directory with strict permissions. -+ */ -+ do { -+ if ((cp = strrchr(progname, '/')) == NULL) -+ break; -+ else -+ *cp = '\0'; -+ -+ debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname)); -+ -+ if (stat((*progname == '\0' ? "/" : progname), &st) != 0) { -+ error("%s: stat("%s"): %s", __func__, -+ progname, strerror(errno)); -+ goto go_away; -+ } -+ if (st.st_uid != 0 || (st.st_mode & 022) != 0) { -+ error("bad ownership or modes for AuthorizedKeysCommand path component "%s"", -+ progname); -+ goto go_away; -+ } -+ if (!S_ISDIR(st.st_mode)) { -+ error("AuthorizedKeysCommand path component "%s" is not a directory", -+ progname); -+ goto go_away; -+ } -+ } while (1); -+ -+ /* open the pipe and read the keys */ -+ if (pipe(childdescriptors)) { -+ error("failed to pipe(2) for AuthorizedKeysCommand: %s", -+ strerror(errno)); -+ goto go_away; -+ } -+ -+ child = fork(); -+ if (child == -1) { -+ error("failed to fork(2) for AuthorizedKeysCommand: %s", -+ strerror(errno)); -+ goto go_away; -+ } else if (child == 0) { -+ /* we're in the child process here -- we should never return from this block. */ -+ /* permanently drop privs in child process */ -+ if (runas_pw->pw_uid != 0) { -+ restore_uid(); -+ permanently_set_uid(runas_pw); -+ } -+ -+ close(childdescriptors[0]); -+ /* put the write end of the pipe on stdout (FD 1) */ -+ if (dup2(childdescriptors[1], 1) == -1) { -+ error("failed to dup2(2) from AuthorizedKeysCommand: %s", -+ strerror(errno)); -+ _exit(127); -+ } -+ -+ debug3("about to execl() AuthorizedKeysCommand: "%s" "%s"", options.authorized_keys_command, pw->pw_name); -+ /* see session.c:child_close_fds() */ -+ for (i = 3; i < 64; ++i) { -+ close(i); -+ } -+ -+ execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL); -+ -+ /* if we got here, it didn't work */ -+ error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */ -+ _exit(127); -+ } -+ -+ close(childdescriptors[1]); -+ f = fdopen(childdescriptors[0], "r"); -+ if (!f) { -+ error("%s: could not buffer FDs from AuthorizedKeysCommand ("%s", "r"): %s", __func__, -+ options.authorized_keys_command, strerror (errno)); -+ goto go_away; -+ } -+ -+ found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw); -+ fclose (f); -+ do { -+ pid = waitpid(child, &pstat, 0); -+ } while (pid == -1 && errno == EINTR); -+ -+ /* what about the return value from the child process? */ -+go_away: -+ if (progname) -+ xfree (progname); -+ -+ if (runas_pw->pw_uid != 0) -+ restore_uid(); -+ return found_key; -+} -+#endif -+ -+/* check whether given key is in <AuthorizedKeysCommand or .ssh/authorized_keys* */ - int - user_key_allowed(struct passwd *pw, Key *key) - { - int success; - char *file; - -+#ifdef WITH_AUTHORIZED_KEYS_COMMAND -+ success = user_key_via_command_allowed2(pw, key); -+ if (success > 0) -+ return success; -+#endif -+ - if (auth_key_is_revoked(key)) - return 0; - if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key)) -diff -up openssh-5.8p1/configure.ac.akc openssh-5.8p1/configure.ac ---- openssh-5.8p1/configure.ac.akc 2011-02-10 13:21:28.000000000 +0100 -+++ openssh-5.8p1/configure.ac 2011-02-10 13:21:28.000000000 +0100 -@@ -1422,6 +1422,18 @@ AC_ARG_WITH(audit, - esac ] - ) - -+# Check whether user wants AuthorizedKeysCommand support -+AKC_MSG="no" -+AC_ARG_WITH(authorized-keys-command, -+ [ --with-authorized-keys-command Enable AuthorizedKeysCommand support], -+ [ -+ if test "x$withval" != "xno" ; then -+ AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support]) -+ AKC_MSG="yes" -+ fi -+ ] -+) -+ - dnl Checks for library functions. Please keep in alphabetical order - AC_CHECK_FUNCS( \ - arc4random \ -@@ -4325,6 +4337,7 @@ echo " SELinux support - echo " Smartcard support: $SCARD_MSG" - echo " S/KEY support: $SKEY_MSG" - echo " TCP Wrappers support: $TCPW_MSG" -+echo " AuthorizedKeysCommand support: $AKC_MSG" - echo " MD5 password support: $MD5_MSG" - echo " libedit support: $LIBEDIT_MSG" - echo " Solaris process contract support: $SPC_MSG" -diff -up openssh-5.8p1/servconf.c.akc openssh-5.8p1/servconf.c ---- openssh-5.8p1/servconf.c.akc 2011-02-10 13:21:28.000000000 +0100 -+++ openssh-5.8p1/servconf.c 2011-02-10 13:28:21.000000000 +0100 -@@ -134,6 +134,8 @@ initialize_server_options(ServerOptions - options->num_permitted_opens = -1; - options->adm_forced_command = NULL; - options->chroot_directory = NULL; -+ options->authorized_keys_command = NULL; -+ options->authorized_keys_command_runas = NULL; - options->zero_knowledge_password_authentication = -1; - options->revoked_keys_file = NULL; - options->trusted_user_ca_keys = NULL; -@@ -331,6 +333,7 @@ typedef enum { - sZeroKnowledgePasswordAuthentication, sHostCertificate, - sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, - sKexAlgorithms, sIPQoS, -+ sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs, - sDeprecated, sUnsupported - } ServerOpCodes; - -@@ -456,6 +459,13 @@ static struct { - { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, - { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, - { "ipqos", sIPQoS, SSHCFG_ALL }, -+#ifdef WITH_AUTHORIZED_KEYS_COMMAND -+ { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, -+ { "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL }, -+#else -+ { "authorizedkeyscommand", sUnsupported, SSHCFG_ALL }, -+ { "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL }, -+#endif - { NULL, sBadOption, 0 } - }; - -@@ -1406,6 +1416,20 @@ process_server_config_line(ServerOptions - } - break; - -+ case sAuthorizedKeysCommand: -+ len = strspn(cp, WHITESPACE); -+ if (*activep && options->authorized_keys_command == NULL) -+ options->authorized_keys_command = xstrdup(cp + len); -+ return 0; -+ -+ case sAuthorizedKeysCommandRunAs: -+ charptr = &options->authorized_keys_command_runas; -+ -+ arg = strdelim(&cp); -+ if (*activep && *charptr == NULL) -+ *charptr = xstrdup(arg); -+ break; -+ - case sDeprecated: - logit("%s line %d: Deprecated option %s", - filename, linenum, arg); -@@ -1499,6 +1523,8 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(gss_authentication); - M_CP_INTOPT(rsa_authentication); - M_CP_INTOPT(pubkey_authentication); -+ M_CP_STROPT(authorized_keys_command); -+ M_CP_STROPT(authorized_keys_command_runas); - M_CP_INTOPT(kerberos_authentication); - M_CP_INTOPT(hostbased_authentication); - M_CP_INTOPT(hostbased_uses_name_from_packet_only); -@@ -1753,6 +1779,8 @@ dump_config(ServerOptions *o) - dump_cfg_string(sRevokedKeys, o->revoked_keys_file); - dump_cfg_string(sAuthorizedPrincipalsFile, - o->authorized_principals_file); -+ dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); -+ dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas); - - /* string arguments requiring a lookup */ - dump_cfg_string(sLogLevel, log_level_name(o->log_level)); -diff -up openssh-5.8p1/servconf.h.akc openssh-5.8p1/servconf.h ---- openssh-5.8p1/servconf.h.akc 2011-02-10 13:21:28.000000000 +0100 -+++ openssh-5.8p1/servconf.h 2011-02-10 13:21:28.000000000 +0100 -@@ -161,6 +161,8 @@ typedef struct { - char *revoked_keys_file; - char *trusted_user_ca_keys; - char *authorized_principals_file; -+ char *authorized_keys_command; -+ char *authorized_keys_command_runas; - } ServerOptions; - - void initialize_server_options(ServerOptions *); -diff -up openssh-5.8p1/sshd_config.0.akc openssh-5.8p1/sshd_config.0 ---- openssh-5.8p1/sshd_config.0.akc 2011-02-10 13:21:28.000000000 +0100 -+++ openssh-5.8p1/sshd_config.0 2011-02-10 13:21:28.000000000 +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 -@@ -398,7 +415,8 @@ DESCRIPTION - - Only a subset of keywords may be used on the lines following a - Match keyword. Available keywords are AllowAgentForwarding, -- AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile, -+ AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand, -+ AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile, - Banner, ChrootDirectory, ForceCommand, GatewayPorts, - GSSAPIAuthentication, HostbasedAuthentication, - HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication, -diff -up openssh-5.8p1/sshd_config.5.akc openssh-5.8p1/sshd_config.5 ---- openssh-5.8p1/sshd_config.5.akc 2011-02-10 13:21:28.000000000 +0100 -+++ openssh-5.8p1/sshd_config.5 2011-02-10 13:21:28.000000000 +0100 -@@ -703,6 +703,8 @@ Available keywords are - .Cm AllowAgentForwarding , - .Cm AllowTcpForwarding , - .Cm AuthorizedKeysFile , -+.Cm AuthorizedKeysCommand , -+.Cm AuthorizedKeysCommandRunAs , - .Cm AuthorizedPrincipalsFile , - .Cm Banner , - .Cm ChrootDirectory , -@@ -715,6 +717,7 @@ Available keywords are - .Cm KerberosAuthentication , - .Cm MaxAuthTries , - .Cm MaxSessions , -+.Cm PubkeyAuthentication , - .Cm PasswordAuthentication , - .Cm PermitEmptyPasswords , - .Cm PermitOpen , -@@ -917,6 +920,20 @@ Specifies a list of revoked public keys. - Keys listed in this file will be refused for public key authentication. - Note that if this file is not readable, then public key authentication will - be refused for all users. -+.It Cm AuthorizedKeysCommand -+Specifies a program to be used for lookup of the user's -+public keys. The program will be invoked with its first -+argument the name of the user being authorized, and should produce -+on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS -+in sshd(8)). By default (or when set to the empty string) there is no -+AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully -+authorize the user, authorization falls through to the -+AuthorizedKeysFile. Note that this option has an effect -+only with PubkeyAuthentication turned on. -+.It Cm AuthorizedKeysCommandRunAs -+Specifies the user under whose account the AuthorizedKeysCommand is run. Empty -+string (the default value) means the user being authorized is used. -+.Dq - .It Cm RhostsRSAAuthentication - Specifies whether rhosts or /etc/hosts.equiv authentication together - with successful RSA host authentication is allowed. -diff -up openssh-5.8p1/sshd_config.akc openssh-5.8p1/sshd_config ---- openssh-5.8p1/sshd_config.akc 2011-02-10 13:21:28.000000000 +0100 -+++ openssh-5.8p1/sshd_config 2011-02-10 13:21:28.000000000 +0100 -@@ -46,6 +46,8 @@ SyslogFacility AUTHPRIV - #RSAAuthentication yes - #PubkeyAuthentication yes - #AuthorizedKeysFile .ssh/authorized_keys -+#AuthorizedKeysCommand none -+#AuthorizedKeysCommandRunAs nobody - - # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts - #RhostsRSAAuthentication no diff --git a/openssh/patches/openssh-5.8p1-getaddrinfo.patch b/openssh/patches/openssh-5.8p1-getaddrinfo.patch new file mode 100644 index 0000000..6f64067 --- /dev/null +++ b/openssh/patches/openssh-5.8p1-getaddrinfo.patch @@ -0,0 +1,11 @@ +diff -up openssh-5.8p1/sshconnect.c.getaddrinfo openssh-5.8p1/sshconnect.c +--- openssh-5.8p1/sshconnect.c.getaddrinfo 2011-04-27 09:51:44.521384633 +0200 ++++ openssh-5.8p1/sshconnect.c 2011-04-27 09:53:21.224443308 +0200 +@@ -355,6 +355,7 @@ ssh_connect(const char *host, struct soc + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = SOCK_STREAM; ++ hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; + snprintf(strport, sizeof strport, "%u", port); + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) + fatal("%s: Could not resolve hostname %.100s: %s", __progname, diff --git a/openssh/patches/openssh-5.8p1-keyperm.patch b/openssh/patches/openssh-5.8p1-keyperm.patch new file mode 100644 index 0000000..6167c14 --- /dev/null +++ b/openssh/patches/openssh-5.8p1-keyperm.patch @@ -0,0 +1,25 @@ +diff -up openssh-5.8p1/authfile.c.keyperm openssh-5.8p1/authfile.c +--- openssh-5.8p1/authfile.c.keyperm 2010-12-01 02:03:39.000000000 +0100 ++++ openssh-5.8p1/authfile.c 2011-04-21 16:43:36.859648916 +0200 +@@ -57,6 +57,7 @@ + #include <stdlib.h> + #include <string.h> + #include <unistd.h> ++#include <grp.h> + + #include "xmalloc.h" + #include "cipher.h" +@@ -600,6 +612,13 @@ key_perm_ok(int fd, const char *filename + #ifdef HAVE_CYGWIN + if (check_ntsec(filename)) + #endif ++ if (st.st_mode & 040) { ++ struct group *gr; ++ ++ if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid)) ++ st.st_mode &= ~040; ++ } ++ + if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); diff --git a/openssh/patches/openssh-5.8p1-kuserok.patch b/openssh/patches/openssh-5.8p1-kuserok.patch deleted file mode 100644 index fcd05d7..0000000 --- a/openssh/patches/openssh-5.8p1-kuserok.patch +++ /dev/null @@ -1,167 +0,0 @@ -diff -up openssh-5.8p1/auth-krb5.c.kuserok openssh-5.8p1/auth-krb5.c ---- openssh-5.8p1/auth-krb5.c.kuserok 2009-12-21 00:49:22.000000000 +0100 -+++ openssh-5.8p1/auth-krb5.c 2011-02-14 09:15:12.000000000 +0100 -@@ -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.8p1/gss-serv-krb5.c.kuserok openssh-5.8p1/gss-serv-krb5.c ---- openssh-5.8p1/gss-serv-krb5.c.kuserok 2006-09-01 07:38:36.000000000 +0200 -+++ openssh-5.8p1/gss-serv-krb5.c 2011-02-14 09:15:12.000000000 +0100 -@@ -57,6 +57,7 @@ extern ServerOptions options; - #endif - - 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 */ - -@@ -97,7 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - krb5_get_err_text(krb_context, retval)); - return 0; - } -- if (krb5_kuserok(krb_context, princ, name)) { -+ if (ssh_krb5_kuserok(krb_context, princ, name)) { - retval = 1; - logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", - name, (char *)client->displayname.value); -diff -up openssh-5.8p1/servconf.c.kuserok openssh-5.8p1/servconf.c ---- openssh-5.8p1/servconf.c.kuserok 2011-02-14 09:15:12.000000000 +0100 -+++ openssh-5.8p1/servconf.c 2011-02-14 09:20:22.000000000 +0100 -@@ -142,6 +142,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 - if (use_privsep == -1) - use_privsep = 1; - -+ if (options->use_kuserok == -1) -+ options->use_kuserok = 1; - #ifndef HAVE_MMAP - if (use_privsep && options->compression == 1) { - error("This platform does not support both privilege " -@@ -312,7 +315,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, -+ sKerberosGetAFSToken, sKerberosUseKuserok, - sKerberosTgtPassing, sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, -@@ -381,11 +384,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 }, -@@ -1341,6 +1346,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') -@@ -1544,6 +1553,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); - - M_CP_STROPT(banner); - if (preauth) -@@ -1764,6 +1774,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.8p1/servconf.h.kuserok openssh-5.8p1/servconf.h ---- openssh-5.8p1/servconf.h.kuserok 2011-02-14 09:15:12.000000000 +0100 -+++ openssh-5.8p1/servconf.h 2011-02-14 09:15:12.000000000 +0100 -@@ -157,6 +157,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.8p1/sshd_config.5.kuserok openssh-5.8p1/sshd_config.5 ---- openssh-5.8p1/sshd_config.5.kuserok 2011-02-14 09:15:12.000000000 +0100 -+++ openssh-5.8p1/sshd_config.5 2011-02-14 09:17:11.000000000 +0100 -@@ -574,6 +574,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. -@@ -715,6 +719,7 @@ Available keywords are - .Cm HostbasedUsesNameFromPacketOnly , - .Cm KbdInteractiveAuthentication , - .Cm KerberosAuthentication , -+.Cm KerberosUseKuserok , - .Cm MaxAuthTries , - .Cm MaxSessions , - .Cm PubkeyAuthentication , -diff -up openssh-5.8p1/sshd_config.kuserok openssh-5.8p1/sshd_config ---- openssh-5.8p1/sshd_config.kuserok 2011-02-14 09:15:12.000000000 +0100 -+++ openssh-5.8p1/sshd_config 2011-02-14 09:15:12.000000000 +0100 -@@ -73,6 +73,7 @@ ChallengeResponseAuthentication no - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok yes - - # GSSAPI options - #GSSAPIAuthentication no diff --git a/openssh/patches/openssh-5.8p1-localdomain.patch b/openssh/patches/openssh-5.8p1-localdomain.patch new file mode 100644 index 0000000..2f21658 --- /dev/null +++ b/openssh/patches/openssh-5.8p1-localdomain.patch @@ -0,0 +1,14 @@ +diff -up openssh-5.8p1/sshd_config.localdomain openssh-5.8p1/sshd_config +--- openssh-5.8p1/sshd_config.localdomain 2011-04-22 11:37:49.273648812 +0200 ++++ openssh-5.8p1/sshd_config 2011-04-22 11:39:31.758648401 +0200 +@@ -130,6 +130,10 @@ X11Forwarding yes + # override default of no subsystems + Subsystem sftp /usr/libexec/sftp-server + ++# Uncomment this if you want to use .local domain ++#Host *.local ++# CheckHostIP no ++ + # Example of overriding settings on a per-user basis + #Match User anoncvs + # X11Forwarding no diff --git a/openssh/patches/openssh-5.8p1-mls.patch b/openssh/patches/openssh-5.8p1-mls.patch deleted file mode 100644 index 525e6b5..0000000 --- a/openssh/patches/openssh-5.8p1-mls.patch +++ /dev/null @@ -1,400 +0,0 @@ -diff -up openssh-5.8p1/misc.c.mls openssh-5.8p1/misc.c ---- openssh-5.8p1/misc.c.mls 2011-01-13 02:21:36.000000000 +0100 -+++ openssh-5.8p1/misc.c 2011-02-12 15:05:06.000000000 +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-5.8p1/openbsd-compat/port-linux.c.mls openssh-5.8p1/openbsd-compat/port-linux.c ---- openssh-5.8p1/openbsd-compat/port-linux.c.mls 2011-02-12 15:05:06.000000000 +0100 -+++ openssh-5.8p1/openbsd-compat/port-linux.c 2011-02-12 15:09:23.000000000 +0100 -@@ -40,13 +40,164 @@ - #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 - - 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) -+{ -+ 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) - { -@@ -65,14 +216,16 @@ 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; - - ssh_selinux_get_role_level(&role, &reqlvl); - #ifdef HAVE_GETSEUSERBYNAME -@@ -82,38 +235,63 @@ 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 - if (sename != NULL) -@@ -121,8 +299,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 */ -@@ -160,6 +342,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; -@@ -184,22 +368,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__); - } -@@ -217,7 +424,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.8p1/sshd.c.mls openssh-5.8p1/sshd.c ---- openssh-5.8p1/sshd.c.mls 2011-02-12 15:05:05.000000000 +0100 -+++ openssh-5.8p1/sshd.c 2011-02-12 15:05:06.000000000 +0100 -@@ -2011,6 +2011,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.8p1-packet.patch b/openssh/patches/openssh-5.8p1-packet.patch new file mode 100644 index 0000000..4951af6 --- /dev/null +++ b/openssh/patches/openssh-5.8p1-packet.patch @@ -0,0 +1,12 @@ +diff -up openssh-5.8p1/packet.c.packet openssh-5.8p1/packet.c +--- openssh-5.8p1/packet.c.packet 2011-04-05 13:29:06.998648899 +0200 ++++ openssh-5.8p1/packet.c 2011-04-05 13:30:32.967648596 +0200 +@@ -294,6 +294,8 @@ packet_connection_is_on_socket(void) + struct sockaddr_storage from, to; + socklen_t fromlen, tolen; + ++ if (!active_state) ++ return 0; + /* filedescriptors in and out are the same, so it's a socket */ + if (active_state->connection_in == active_state->connection_out) + return 1; diff --git a/openssh/patches/openssh-5.8p1-randclean.patch b/openssh/patches/openssh-5.8p1-randclean.patch deleted file mode 100644 index 378f367..0000000 --- a/openssh/patches/openssh-5.8p1-randclean.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up openssh-5.8p1/entropy.c.randclean openssh-5.8p1/entropy.c ---- openssh-5.8p1/entropy.c.randclean 2011-01-13 11:05:29.000000000 +0100 -+++ openssh-5.8p1/entropy.c 2011-02-14 00:26:31.000000000 +0100 -@@ -159,6 +159,9 @@ init_rng(void) - fatal("OpenSSL version mismatch. Built against %lx, you " - "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); - -+ /* clean the PRNG status when exiting the program */ -+ atexit(RAND_cleanup); -+ - #ifndef OPENSSL_PRNG_ONLY - original_uid = getuid(); - original_euid = geteuid(); diff --git a/openssh/patches/openssh-5.8p1-selinux-role.patch b/openssh/patches/openssh-5.8p1-selinux-role.patch deleted file mode 100644 index f29ad9a..0000000 --- a/openssh/patches/openssh-5.8p1-selinux-role.patch +++ /dev/null @@ -1,611 +0,0 @@ -diff -up openssh-5.8p1/auth1.c.role openssh-5.8p1/auth1.c ---- openssh-5.8p1/auth1.c.role 2010-08-31 14:36:39.000000000 +0200 -+++ openssh-5.8p1/auth1.c 2011-02-12 14:34:11.000000000 +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-5.8p1/auth2.c.role openssh-5.8p1/auth2.c ---- openssh-5.8p1/auth2.c.role 2010-08-31 14:36:39.000000000 +0200 -+++ openssh-5.8p1/auth2.c 2011-02-12 14:34:11.000000000 +0100 -@@ -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; - -@@ -252,8 +260,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.8p1/auth2-gss.c.role openssh-5.8p1/auth2-gss.c ---- openssh-5.8p1/auth2-gss.c.role 2007-12-02 12:59:45.000000000 +0100 -+++ openssh-5.8p1/auth2-gss.c 2011-02-12 14:34:11.000000000 +0100 -@@ -258,6 +258,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; -@@ -270,7 +271,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); -@@ -282,6 +289,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.8p1/auth2-hostbased.c.role openssh-5.8p1/auth2-hostbased.c ---- openssh-5.8p1/auth2-hostbased.c.role 2011-02-12 14:34:10.000000000 +0100 -+++ openssh-5.8p1/auth2-hostbased.c 2011-02-12 14:34:11.000000000 +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-5.8p1/auth2-pubkey.c.role openssh-5.8p1/auth2-pubkey.c ---- openssh-5.8p1/auth2-pubkey.c.role 2011-02-12 14:34:11.000000000 +0100 -+++ openssh-5.8p1/auth2-pubkey.c 2011-02-12 14:34:11.000000000 +0100 -@@ -122,7 +122,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.8p1/auth.h.role openssh-5.8p1/auth.h ---- openssh-5.8p1/auth.h.role 2011-02-12 14:34:10.000000000 +0100 -+++ openssh-5.8p1/auth.h 2011-02-12 14:34:11.000000000 +0100 -@@ -58,6 +58,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.8p1/auth-pam.c.role openssh-5.8p1/auth-pam.c ---- openssh-5.8p1/auth-pam.c.role 2009-07-12 14:07:21.000000000 +0200 -+++ openssh-5.8p1/auth-pam.c 2011-02-12 14:34:11.000000000 +0100 -@@ -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.8p1/auth-pam.h.role openssh-5.8p1/auth-pam.h ---- openssh-5.8p1/auth-pam.h.role 2004-09-11 14:17:26.000000000 +0200 -+++ openssh-5.8p1/auth-pam.h 2011-02-12 14:34:11.000000000 +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-5.8p1/monitor.c.role openssh-5.8p1/monitor.c ---- openssh-5.8p1/monitor.c.role 2011-02-12 14:34:11.000000000 +0100 -+++ openssh-5.8p1/monitor.c 2011-02-12 14:34:11.000000000 +0100 -@@ -138,6 +138,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 *); -@@ -218,6 +221,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 -@@ -703,6 +709,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); - } - -@@ -747,6 +756,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) - { -@@ -1112,7 +1140,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; - -@@ -1138,6 +1166,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); -@@ -1169,7 +1199,7 @@ monitor_valid_hostbasedblob(u_char *data - char *chost) - { - Buffer b; -- char *p; -+ char *p, *r; - u_int len; - int fail = 0; - -@@ -1186,6 +1216,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.8p1/monitor.h.role openssh-5.8p1/monitor.h ---- openssh-5.8p1/monitor.h.role 2011-02-12 14:34:11.000000000 +0100 -+++ openssh-5.8p1/monitor.h 2011-02-12 14:34:11.000000000 +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-5.8p1/monitor_wrap.c.role openssh-5.8p1/monitor_wrap.c ---- openssh-5.8p1/monitor_wrap.c.role 2011-02-12 14:34:11.000000000 +0100 -+++ openssh-5.8p1/monitor_wrap.c 2011-02-12 14:34:11.000000000 +0100 -@@ -298,6 +298,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.8p1/monitor_wrap.h.role openssh-5.8p1/monitor_wrap.h ---- openssh-5.8p1/monitor_wrap.h.role 2011-02-12 14:34:11.000000000 +0100 -+++ openssh-5.8p1/monitor_wrap.h 2011-02-12 14:34:11.000000000 +0100 -@@ -41,6 +41,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.8p1/openbsd-compat/Makefile.in.role openssh-5.8p1/openbsd-compat/Makefile.in ---- openssh-5.8p1/openbsd-compat/Makefile.in.role 2010-10-07 13:19:24.000000000 +0200 -+++ openssh-5.8p1/openbsd-compat/Makefile.in 2011-02-12 14:34:11.000000000 +0100 -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport - - COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o - --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.8p1/openbsd-compat/port-linux.c.role openssh-5.8p1/openbsd-compat/port-linux.c ---- openssh-5.8p1/openbsd-compat/port-linux.c.role 2011-02-12 14:34:11.000000000 +0100 -+++ openssh-5.8p1/openbsd-compat/port-linux.c 2011-02-12 14:37:31.000000000 +0100 -@@ -31,48 +31,73 @@ - - #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/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; -+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()) { -@@ -100,6 +125,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) -@@ -109,6 +164,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); -@@ -206,21 +279,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.8p1/openbsd-compat/port-linux_part_2.c.role openssh-5.8p1/openbsd-compat/port-linux_part_2.c ---- openssh-5.8p1/openbsd-compat/port-linux_part_2.c.role 2011-02-12 14:34:11.000000000 +0100 -+++ openssh-5.8p1/openbsd-compat/port-linux_part_2.c 2011-02-12 14:34:11.000000000 +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 --git a/openssh/patches/openssh-5.8p1-selinux.patch b/openssh/patches/openssh-5.8p1-selinux.patch deleted file mode 100644 index 6967cbd..0000000 --- a/openssh/patches/openssh-5.8p1-selinux.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh-5.8p1/openbsd-compat/port-linux.c.selinux openssh-5.8p1/openbsd-compat/port-linux.c ---- openssh-5.8p1/openbsd-compat/port-linux.c.selinux 2011-02-12 09:38:45.000000000 +0100 -+++ openssh-5.8p1/openbsd-compat/port-linux.c 2011-02-12 09:39:10.000000000 +0100 -@@ -213,7 +213,7 @@ ssh_selinux_setfscreatecon(const char *p - - if (!ssh_selinux_enabled()) - return; -- if (path == NULL) -+ if (path == NULL) { - setfscreatecon(NULL); - return; - } diff --git a/openssh/patches/openssh-5.8p2-askpass-ld.patch b/openssh/patches/openssh-5.8p2-askpass-ld.patch new file mode 100644 index 0000000..5b85c80 --- /dev/null +++ b/openssh/patches/openssh-5.8p2-askpass-ld.patch @@ -0,0 +1,18 @@ +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.8p2-force_krb.patch b/openssh/patches/openssh-5.8p2-force_krb.patch new file mode 100644 index 0000000..1842ce4 --- /dev/null +++ b/openssh/patches/openssh-5.8p2-force_krb.patch @@ -0,0 +1,288 @@ +diff -up openssh-5.8p2/gss-serv-krb5.c.force_krb openssh-5.8p2/gss-serv-krb5.c +--- openssh-5.8p2/gss-serv-krb5.c.force_krb 2006-09-01 07:38:36.000000000 +0200 ++++ openssh-5.8p2/gss-serv-krb5.c 2011-05-19 03:41:45.801109545 +0200 +@@ -32,7 +32,9 @@ + #include <sys/types.h> + + #include <stdarg.h> ++#include <stdio.h> + #include <string.h> ++#include <unistd.h> + + #include "xmalloc.h" + #include "key.h" +@@ -40,12 +42,11 @@ + #include "auth.h" + #include "log.h" + #include "servconf.h" ++#include "misc.h" + + #include "buffer.h" + #include "ssh-gss.h" + +-extern ServerOptions options; +- + #ifdef HEIMDAL + # include <krb5.h> + #else +@@ -56,6 +57,16 @@ extern ServerOptions options; + # endif + #endif + ++extern Authctxt *the_authctxt; ++extern ServerOptions options; ++ ++/* all commands are allowed by default */ ++char **k5users_allowed_cmds = NULL; ++ ++static int ssh_gssapi_k5login_exists(); ++static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, ++ int); ++ + static krb5_context krb_context = NULL; + + /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ +@@ -83,10 +94,11 @@ ssh_gssapi_krb5_init(void) + */ + + static int +-ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) ++ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *luser) + { + krb5_principal princ; + int retval; ++ int k5login_exists; + + if (ssh_gssapi_krb5_init() == 0) + return 0; +@@ -97,10 +109,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client + krb5_get_err_text(krb_context, retval)); + return 0; + } +- if (krb5_kuserok(krb_context, princ, name)) { ++ /* krb5_kuserok() returns 1 if .k5login DNE and this is self-login. ++ * We have to make sure to check .k5users in that case. */ ++ k5login_exists = ssh_gssapi_k5login_exists(); ++ /* NOTE: .k5login and .k5users must opened as root, not the user, ++ * because if they are on a krb5-protected filesystem, user credentials ++ * to access these files aren't available yet. */ ++ if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) { + retval = 1; + logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", +- name, (char *)client->displayname.value); ++ luser, (char *)client->displayname.value); ++ } else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value, ++ luser, k5login_exists)) { ++ retval = 1; ++ logit("Authorized to %s, krb5 principal %s " ++ "(ssh_gssapi_krb5_cmdok)", ++ luser, (char *)client->displayname.value); + } else + retval = 0; + +@@ -108,6 +132,134 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client + return retval; + } + ++/* Test for existence of .k5login. ++ * We need this as part of our .k5users check, because krb5_kuserok() ++ * returns success if .k5login DNE and user is logging in as himself. ++ * With .k5login absent and .k5users present, we don't want absence ++ * of .k5login to authorize self-login. (absence of both is required) ++ * Returns 1 if .k5login is available, 0 otherwise. ++ */ ++static int ++ssh_gssapi_k5login_exists() ++{ ++ char file[MAXPATHLEN]; ++ struct passwd *pw = the_authctxt->pw; ++ ++ snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); ++ return access(file, F_OK) == 0; ++} ++ ++/* check .k5users for login or command authorization ++ * Returns 1 if principal is authorized, 0 otherwise. ++ * If principal is authorized, (global) k5users_allowed_cmds may be populated. ++ */ ++static int ++ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, ++ const char *luser, int k5login_exists) ++{ ++ FILE *fp; ++ char file[MAXPATHLEN]; ++ char line[BUFSIZ]; ++ char kuser[65]; /* match krb5_kuserok() */ ++ struct stat st; ++ struct passwd *pw = the_authctxt->pw; ++ int found_principal = 0; ++ int ncommands = 0, allcommands = 0; ++ u_long linenum; ++ ++ snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); ++ /* If both .k5login and .k5users DNE, self-login is ok. */ ++ if (!k5login_exists && (access(file, F_OK) == -1)) { ++ return (krb5_aname_to_localname(krb_context, principal, ++ sizeof(kuser), kuser) == 0) && ++ (strcmp(kuser, luser) == 0); ++ } ++ if ((fp = fopen(file, "r")) == NULL) { ++ int saved_errno = errno; ++ /* 2nd access check to ease debugging if file perms are wrong. ++ * But we don't want to report this if .k5users simply DNE. */ ++ if (access(file, F_OK) == 0) { ++ logit("User %s fopen %s failed: %s", ++ pw->pw_name, file, strerror(saved_errno)); ++ } ++ return 0; ++ } ++ /* .k5users must be owned either by the user or by root */ ++ if (fstat(fileno(fp), &st) == -1) { ++ /* can happen, but very wierd error so report it */ ++ logit("User %s fstat %s failed: %s", ++ pw->pw_name, file, strerror(errno)); ++ fclose(fp); ++ return 0; ++ } ++ if (!(st.st_uid == pw->pw_uid || st.st_uid == 0)) { ++ logit("User %s %s is not owned by root or user", ++ pw->pw_name, file); ++ fclose(fp); ++ return 0; ++ } ++ /* .k5users must be a regular file. krb5_kuserok() doesn't do this ++ * check, but we don't want to be deficient if they add a check. */ ++ if (!S_ISREG(st.st_mode)) { ++ logit("User %s %s is not a regular file", pw->pw_name, file); ++ fclose(fp); ++ return 0; ++ } ++ /* file exists; initialize k5users_allowed_cmds (to none!) */ ++ k5users_allowed_cmds = xcalloc(++ncommands, ++ sizeof(*k5users_allowed_cmds)); ++ ++ /* Check each line. ksu allows unlimited length lines. We don't. */ ++ while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line), ++ &linenum) != -1) { ++ char *token; ++ ++ /* we parse just like ksu, even though we could do better */ ++ token = strtok(line, " \t\n"); ++ if (strcmp(name, token) == 0) { ++ /* we matched on client principal */ ++ found_principal = 1; ++ if ((token = strtok(NULL, " \t\n")) == NULL) { ++ /* only shell is allowed */ ++ k5users_allowed_cmds[ncommands-1] = ++ xstrdup(pw->pw_shell); ++ k5users_allowed_cmds = ++ xrealloc(k5users_allowed_cmds, ++ncommands, ++ sizeof(*k5users_allowed_cmds)); ++ break; ++ } ++ /* process the allowed commands */ ++ while (token) { ++ if (strcmp(token, "*") == 0) { ++ allcommands = 1; ++ break; ++ } ++ k5users_allowed_cmds[ncommands-1] = ++ xstrdup(token); ++ k5users_allowed_cmds = ++ xrealloc(k5users_allowed_cmds, ++ncommands, ++ sizeof(*k5users_allowed_cmds)); ++ token = strtok(NULL, " \t\n"); ++ } ++ } ++ } ++ if (k5users_allowed_cmds) { ++ /* terminate vector */ ++ k5users_allowed_cmds[ncommands-1] = NULL; ++ /* if all commands are allowed, free vector */ ++ if (allcommands) { ++ int i; ++ for (i = 0; i < ncommands; i++) { ++ free(k5users_allowed_cmds[i]); ++ } ++ free(k5users_allowed_cmds); ++ k5users_allowed_cmds = NULL; ++ } ++ } ++ fclose(fp); ++ return found_principal; ++} ++ + + /* This writes out any forwarded credentials from the structure populated + * during userauth. Called after we have setuid to the user */ +diff -up openssh-5.8p2/session.c.force_krb openssh-5.8p2/session.c +--- openssh-5.8p2/session.c.force_krb 2011-05-19 03:41:41.000000000 +0200 ++++ openssh-5.8p2/session.c 2011-05-19 03:43:32.437173662 +0200 +@@ -816,6 +816,29 @@ do_exec(Session *s, const char *command) + debug("Forced command (key option) '%.900s'", command); + } + ++#ifdef GSSAPI ++#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */ ++ else if (k5users_allowed_cmds) { ++ const char *match = command; ++ int allowed = 0, i = 0; ++ ++ if (!match) ++ match = s->pw->pw_shell; ++ while (k5users_allowed_cmds[i]) { ++ if (strcmp(match, k5users_allowed_cmds[i++]) == 0) { ++ debug("Allowed command '%.900s'", match); ++ allowed = 1; ++ break; ++ } ++ } ++ if (!allowed) { ++ debug("command '%.900s' not allowed", match); ++ return 1; ++ } ++ } ++#endif ++#endif ++ + #ifdef SSH_AUDIT_EVENTS + if (s->command != NULL || s->command_handle != -1) + fatal("do_exec: command already set"); +diff -up openssh-5.8p2/sshd.8.force_krb openssh-5.8p2/sshd.8 +--- openssh-5.8p2/sshd.8.force_krb 2011-05-19 03:41:30.582114401 +0200 ++++ openssh-5.8p2/sshd.8 2011-05-19 03:41:46.159106308 +0200 +@@ -320,6 +320,7 @@ Finally, the server and the client enter + The client tries to authenticate itself using + host-based authentication, + public key authentication, ++GSSAPI authentication, + challenge-response authentication, + or password authentication. + .Pp +@@ -788,6 +789,12 @@ This file is used in exactly the same wa + but allows host-based authentication without permitting login with + rlogin/rsh. + .Pp ++.It Pa ~/.k5login ++.It Pa ~/.k5users ++These files enforce GSSAPI/Kerberos authentication access control. ++Further details are described in ++.Xr ksu 1 . ++.Pp + .It Pa ~/.ssh/ + This directory is the default location for all user-specific configuration + and authentication information. +diff -up openssh-5.8p2/ssh-gss.h.force_krb openssh-5.8p2/ssh-gss.h +--- openssh-5.8p2/ssh-gss.h.force_krb 2007-06-12 15:40:39.000000000 +0200 ++++ openssh-5.8p2/ssh-gss.h 2011-05-19 03:41:46.302234118 +0200 +@@ -48,6 +48,10 @@ + #define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name + #endif /* GSS_C_NT_... */ + #endif /* !HEIMDAL */ ++ ++/* .k5users support */ ++extern char **k5users_allowed_cmds; ++ + #endif /* KRB5 */ + + /* draft-ietf-secsh-gsskeyex-06 */ diff --git a/openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch b/openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch new file mode 100644 index 0000000..4a25d9e --- /dev/null +++ b/openssh/patches/openssh-5.8p2-remove-stale-control-socket.patch @@ -0,0 +1,13 @@ +diff -up openssh-5.8p2/mux.c.remove_stale openssh-5.8p2/mux.c +--- openssh-5.8p2/mux.c.remove_stale 2011-01-14 02:01:32.000000000 +0100 ++++ openssh-5.8p2/mux.c 2011-06-09 15:27:42.556360291 +0200 +@@ -1867,6 +1867,9 @@ muxclient(const char *path) + unlink(path); + } else if (errno == ENOENT) { + debug("Control socket "%.100s" does not exist", path); ++ } else if (errno == ECONNREFUSED) { ++ debug("Removing stale control socket "%.100s"", path); ++ unlink(path); + } else { + error("Control socket connect(%.100s): %s", path, + strerror(errno)); diff --git a/openssh/patches/openssh-5.8p2-sigpipe.patch b/openssh/patches/openssh-5.8p2-sigpipe.patch new file mode 100644 index 0000000..56af045 --- /dev/null +++ b/openssh/patches/openssh-5.8p2-sigpipe.patch @@ -0,0 +1,12 @@ +diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c +--- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200 ++++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200 +@@ -715,6 +715,8 @@ main(int argc, char **argv) + fdlim_set(maxfd); + fdcon = xcalloc(maxfd, sizeof(con)); + ++ signal(SIGPIPE, SIG_IGN); ++ + read_wait_nfdset = howmany(maxfd, NFDBITS); + read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); + diff --git a/openssh/patches/openssh-5.9p1-2auth.patch b/openssh/patches/openssh-5.9p1-2auth.patch new file mode 100644 index 0000000..b19d2ac --- /dev/null +++ b/openssh/patches/openssh-5.9p1-2auth.patch @@ -0,0 +1,354 @@ +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-akc.patch b/openssh/patches/openssh-5.9p1-akc.patch new file mode 100644 index 0000000..62a478b --- /dev/null +++ b/openssh/patches/openssh-5.9p1-akc.patch @@ -0,0 +1,452 @@ +diff -up openssh-5.9p1/auth2-pubkey.c.akc openssh-5.9p1/auth2-pubkey.c +--- openssh-5.9p1/auth2-pubkey.c.akc 2011-09-14 07:24:40.876512251 +0200 ++++ openssh-5.9p1/auth2-pubkey.c 2011-09-14 07:24:43.318458515 +0200 +@@ -27,6 +27,7 @@ + + #include <sys/types.h> + #include <sys/stat.h> ++#include <sys/wait.h> + + #include <fcntl.h> + #include <pwd.h> +@@ -276,27 +277,15 @@ match_principals_file(char *file, struct + + /* return 1 if user allows given key */ + static int +-user_key_allowed2(struct passwd *pw, Key *key, char *file) ++user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw) + { + char line[SSH_MAX_PUBKEY_BYTES]; + const char *reason; + int found_key = 0; +- FILE *f; + u_long linenum = 0; + Key *found; + char *fp; + +- /* Temporarily use the user's uid. */ +- temporarily_use_uid(pw); +- +- debug("trying public key file %s", file); +- f = auth_openkeyfile(file, pw, options.strict_modes); +- +- if (!f) { +- restore_uid(); +- return 0; +- } +- + found_key = 0; + found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); + +@@ -389,8 +378,6 @@ user_key_allowed2(struct passwd *pw, Key + break; + } + } +- restore_uid(); +- fclose(f); + key_free(found); + if (!found_key) + debug2("key not found"); +@@ -452,13 +439,191 @@ user_cert_trusted_ca(struct passwd *pw, + return ret; + } + +-/* check whether given key is in .ssh/authorized_keys* */ ++/* return 1 if user allows given key */ ++static int ++user_key_allowed2(struct passwd *pw, Key *key, char *file) ++{ ++ FILE *f; ++ int found_key = 0; ++ ++ /* Temporarily use the user's uid. */ ++ temporarily_use_uid(pw); ++ ++ debug("trying public key file %s", file); ++ f = auth_openkeyfile(file, pw, options.strict_modes); ++ ++ if (f) { ++ found_key = user_search_key_in_file (f, file, key, pw); ++ fclose(f); ++ } ++ ++ restore_uid(); ++ return found_key; ++} ++ ++#ifdef WITH_AUTHORIZED_KEYS_COMMAND ++ ++#define WHITESPACE " \t\r\n" ++ ++/* return 1 if user allows given key */ ++static int ++user_key_via_command_allowed2(struct passwd *pw, Key *key) ++{ ++ FILE *f; ++ int found_key = 0; ++ char *progname = NULL; ++ char *cp; ++ struct passwd *runas_pw; ++ struct stat st; ++ int childdescriptors[2], i; ++ pid_t pstat, pid, child; ++ ++ if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/') ++ return 0; ++ ++ /* get the run as identity from config */ ++ runas_pw = (options.authorized_keys_command_runas == NULL)? pw ++ : getpwnam (options.authorized_keys_command_runas); ++ if (!runas_pw) { ++ error("%s: getpwnam("%s"): %s", __func__, ++ options.authorized_keys_command_runas, strerror(errno)); ++ return 0; ++ } ++ ++ /* Temporarily use the specified uid. */ ++ if (runas_pw->pw_uid != 0) ++ temporarily_use_uid(runas_pw); ++ ++ progname = xstrdup(options.authorized_keys_command); ++ ++ debug3("%s: checking program '%s'", __func__, progname); ++ ++ if (stat (progname, &st) < 0) { ++ error("%s: stat("%s"): %s", __func__, ++ progname, strerror(errno)); ++ goto go_away; ++ } ++ ++ if (st.st_uid != 0 || (st.st_mode & 022) != 0) { ++ error("bad ownership or modes for AuthorizedKeysCommand "%s"", ++ progname); ++ goto go_away; ++ } ++ ++ if (!S_ISREG(st.st_mode)) { ++ error("AuthorizedKeysCommand "%s" is not a regular file", ++ progname); ++ goto go_away; ++ } ++ ++ /* ++ * Descend the path, checking that each component is a ++ * root-owned directory with strict permissions. ++ */ ++ do { ++ if ((cp = strrchr(progname, '/')) == NULL) ++ break; ++ else ++ *cp = '\0'; ++ ++ debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname)); ++ ++ if (stat((*progname == '\0' ? "/" : progname), &st) != 0) { ++ error("%s: stat("%s"): %s", __func__, ++ progname, strerror(errno)); ++ goto go_away; ++ } ++ if (st.st_uid != 0 || (st.st_mode & 022) != 0) { ++ error("bad ownership or modes for AuthorizedKeysCommand path component "%s"", ++ progname); ++ goto go_away; ++ } ++ if (!S_ISDIR(st.st_mode)) { ++ error("AuthorizedKeysCommand path component "%s" is not a directory", ++ progname); ++ goto go_away; ++ } ++ } while (1); ++ ++ /* open the pipe and read the keys */ ++ if (pipe(childdescriptors)) { ++ error("failed to pipe(2) for AuthorizedKeysCommand: %s", ++ strerror(errno)); ++ goto go_away; ++ } ++ ++ child = fork(); ++ if (child == -1) { ++ error("failed to fork(2) for AuthorizedKeysCommand: %s", ++ strerror(errno)); ++ goto go_away; ++ } else if (child == 0) { ++ /* we're in the child process here -- we should never return from this block. */ ++ /* permanently drop privs in child process */ ++ if (runas_pw->pw_uid != 0) { ++ restore_uid(); ++ permanently_set_uid(runas_pw); ++ } ++ ++ close(childdescriptors[0]); ++ /* put the write end of the pipe on stdout (FD 1) */ ++ if (dup2(childdescriptors[1], 1) == -1) { ++ error("failed to dup2(2) from AuthorizedKeysCommand: %s", ++ strerror(errno)); ++ _exit(127); ++ } ++ ++ debug3("about to execl() AuthorizedKeysCommand: "%s" "%s"", options.authorized_keys_command, pw->pw_name); ++ /* see session.c:child_close_fds() */ ++ for (i = 3; i < 64; ++i) { ++ close(i); ++ } ++ ++ execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL); ++ ++ /* if we got here, it didn't work */ ++ error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */ ++ _exit(127); ++ } ++ ++ close(childdescriptors[1]); ++ f = fdopen(childdescriptors[0], "r"); ++ if (!f) { ++ error("%s: could not buffer FDs from AuthorizedKeysCommand ("%s", "r"): %s", __func__, ++ options.authorized_keys_command, strerror (errno)); ++ goto go_away; ++ } ++ ++ found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw); ++ fclose (f); ++ do { ++ pid = waitpid(child, &pstat, 0); ++ } while (pid == -1 && errno == EINTR); ++ ++ /* what about the return value from the child process? */ ++go_away: ++ if (progname) ++ xfree (progname); ++ ++ if (runas_pw->pw_uid != 0) ++ restore_uid(); ++ return found_key; ++} ++#endif ++ ++/* check whether given key is in <AuthorizedKeysCommand or .ssh/authorized_keys* */ + int + user_key_allowed(struct passwd *pw, Key *key) + { + u_int success, i; + char *file; + ++#ifdef WITH_AUTHORIZED_KEYS_COMMAND ++ success = user_key_via_command_allowed2(pw, key); ++ if (success > 0) ++ return success; ++#endif ++ + if (auth_key_is_revoked(key)) + return 0; + if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key)) +diff -up openssh-5.9p1/configure.ac.akc openssh-5.9p1/configure.ac +--- openssh-5.9p1/configure.ac.akc 2011-09-14 07:24:42.863494886 +0200 ++++ openssh-5.9p1/configure.ac 2011-09-14 07:24:43.441583848 +0200 +@@ -1421,6 +1421,18 @@ AC_ARG_WITH([audit], + esac ] + ) + ++# Check whether user wants AuthorizedKeysCommand support ++AKC_MSG="no" ++AC_ARG_WITH(authorized-keys-command, ++ [ --with-authorized-keys-command Enable AuthorizedKeysCommand support], ++ [ ++ if test "x$withval" != "xno" ; then ++ AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support]) ++ AKC_MSG="yes" ++ fi ++ ] ++) ++ + dnl Checks for library functions. Please keep in alphabetical order + AC_CHECK_FUNCS([ \ + arc4random \ +@@ -4239,6 +4251,7 @@ echo " SELinux support + echo " Smartcard support: $SCARD_MSG" + echo " S/KEY support: $SKEY_MSG" + echo " TCP Wrappers support: $TCPW_MSG" ++echo " AuthorizedKeysCommand support: $AKC_MSG" + echo " MD5 password support: $MD5_MSG" + echo " libedit support: $LIBEDIT_MSG" + echo " Solaris process contract support: $SPC_MSG" +diff -up openssh-5.9p1/servconf.c.akc openssh-5.9p1/servconf.c +--- openssh-5.9p1/servconf.c.akc 2011-09-14 07:24:29.402475399 +0200 ++++ openssh-5.9p1/servconf.c 2011-09-14 07:56:27.158585590 +0200 +@@ -139,6 +139,8 @@ initialize_server_options(ServerOptions + options->num_permitted_opens = -1; + options->adm_forced_command = NULL; + options->chroot_directory = NULL; ++ options->authorized_keys_command = NULL; ++ options->authorized_keys_command_runas = NULL; + options->zero_knowledge_password_authentication = -1; + options->revoked_keys_file = NULL; + options->trusted_user_ca_keys = NULL; +@@ -348,6 +350,7 @@ typedef enum { + sZeroKnowledgePasswordAuthentication, sHostCertificate, + sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, + sKexAlgorithms, sIPQoS, ++ sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs, + sDeprecated, sUnsupported + } ServerOpCodes; + +@@ -487,6 +490,13 @@ static struct { + { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, + { "ipqos", sIPQoS, SSHCFG_ALL }, ++#ifdef WITH_AUTHORIZED_KEYS_COMMAND ++ { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, ++ { "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL }, ++#else ++ { "authorizedkeyscommand", sUnsupported, SSHCFG_ALL }, ++ { "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL }, ++#endif + { NULL, sBadOption, 0 } + }; + +@@ -1462,6 +1472,24 @@ process_server_config_line(ServerOptions + } + break; + ++ case sAuthorizedKeysCommand: ++ len = strspn(cp, WHITESPACE); ++ if (*activep && options->authorized_keys_command == NULL) ++ options->authorized_keys_command = xstrdup(cp + len); ++ return 0; ++ ++ case sAuthorizedKeysCommandRunAs: ++ charptr = &options->authorized_keys_command_runas; ++ ++ arg = strdelim(&cp); ++ if (!arg || *arg == '\0') ++ fatal("%s line %d: missing account.", ++ filename, linenum); ++ ++ if (*activep && *charptr == NULL) ++ *charptr = xstrdup(arg); ++ break; ++ + case sDeprecated: + logit("%s line %d: Deprecated option %s", + filename, linenum, arg); +@@ -1573,6 +1601,8 @@ copy_set_server_options(ServerOptions *d + M_CP_INTOPT(zero_knowledge_password_authentication); + M_CP_INTOPT(second_zero_knowledge_password_authentication); + M_CP_INTOPT(two_factor_authentication); ++ M_CP_STROPT(authorized_keys_command); ++ M_CP_STROPT(authorized_keys_command_runas); + M_CP_INTOPT(permit_root_login); + M_CP_INTOPT(permit_empty_passwd); + +@@ -1839,6 +1869,8 @@ dump_config(ServerOptions *o) + dump_cfg_string(sRevokedKeys, o->revoked_keys_file); + dump_cfg_string(sAuthorizedPrincipalsFile, + o->authorized_principals_file); ++ dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); ++ dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas); + + /* string arguments requiring a lookup */ + dump_cfg_string(sLogLevel, log_level_name(o->log_level)); +diff -up openssh-5.9p1/servconf.h.akc openssh-5.9p1/servconf.h +--- openssh-5.9p1/servconf.h.akc 2011-09-14 07:24:29.511480441 +0200 ++++ openssh-5.9p1/servconf.h 2011-09-14 07:24:43.678459183 +0200 +@@ -174,6 +174,8 @@ typedef struct { + char *revoked_keys_file; + char *trusted_user_ca_keys; + char *authorized_principals_file; ++ char *authorized_keys_command; ++ char *authorized_keys_command_runas; + } ServerOptions; + + /* +diff -up openssh-5.9p1/sshd_config.0.akc openssh-5.9p1/sshd_config.0 +--- openssh-5.9p1/sshd_config.0.akc 2011-09-07 01:16:30.000000000 +0200 ++++ openssh-5.9p1/sshd_config.0 2011-09-14 07:24:43.791460201 +0200 +@@ -71,6 +71,23 @@ DESCRIPTION + + See PATTERNS in ssh_config(5) for more information on patterns. + ++ AuthorizedKeysCommand ++ ++ Specifies a program to be used for lookup of the user's ++ public keys. The program will be invoked with its first ++ argument the name of the user being authorized, and should produce ++ on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS ++ in sshd(8)). By default (or when set to the empty string) there is no ++ AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully ++ authorize the user, authorization falls through to the ++ AuthorizedKeysFile. Note that this option has an effect ++ only with PubkeyAuthentication turned on. ++ ++ AuthorizedKeysCommandRunAs ++ Specifies the user under whose account the AuthorizedKeysCommand is run. ++ Empty string (the default value) means the user being authorized ++ is used. ++ + AuthorizedKeysFile + Specifies the file that contains the public keys that can be used + for user authentication. The format is described in the +@@ -401,7 +418,8 @@ DESCRIPTION + + Only a subset of keywords may be used on the lines following a + Match keyword. Available keywords are AllowAgentForwarding, +- AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile, ++ AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand, ++ AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile, + Banner, ChrootDirectory, ForceCommand, GatewayPorts, + GSSAPIAuthentication, HostbasedAuthentication, + HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication, +diff -up openssh-5.9p1/sshd_config.5.akc openssh-5.9p1/sshd_config.5 +--- openssh-5.9p1/sshd_config.5.akc 2011-09-14 07:24:29.793520372 +0200 ++++ openssh-5.9p1/sshd_config.5 2011-09-14 07:24:43.912583678 +0200 +@@ -706,6 +706,8 @@ Available keywords are + .Cm AllowAgentForwarding , + .Cm AllowTcpForwarding , + .Cm AuthorizedKeysFile , ++.Cm AuthorizedKeysCommand , ++.Cm AuthorizedKeysCommandRunAs , + .Cm AuthorizedPrincipalsFile , + .Cm Banner , + .Cm ChrootDirectory , +@@ -718,6 +720,7 @@ Available keywords are + .Cm KerberosAuthentication , + .Cm MaxAuthTries , + .Cm MaxSessions , ++.Cm PubkeyAuthentication , + .Cm PasswordAuthentication , + .Cm PermitEmptyPasswords , + .Cm PermitOpen , +@@ -926,6 +929,20 @@ Specifies a list of revoked public keys. + Keys listed in this file will be refused for public key authentication. + Note that if this file is not readable, then public key authentication will + be refused for all users. ++.It Cm AuthorizedKeysCommand ++Specifies a program to be used for lookup of the user's ++public keys. The program will be invoked with its first ++argument the name of the user being authorized, and should produce ++on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS ++in sshd(8)). By default (or when set to the empty string) there is no ++AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully ++authorize the user, authorization falls through to the ++AuthorizedKeysFile. Note that this option has an effect ++only with PubkeyAuthentication turned on. ++.It Cm AuthorizedKeysCommandRunAs ++Specifies the user under whose account the AuthorizedKeysCommand is run. Empty ++string (the default value) means the user being authorized is used. ++.Dq + .It Cm RhostsRSAAuthentication + Specifies whether rhosts or /etc/hosts.equiv authentication together + with successful RSA host authentication is allowed. +diff -up openssh-5.9p1/sshd_config.akc openssh-5.9p1/sshd_config +--- openssh-5.9p1/sshd_config.akc 2011-09-14 07:24:29.620461608 +0200 ++++ openssh-5.9p1/sshd_config 2011-09-14 07:24:44.034462546 +0200 +@@ -49,6 +49,9 @@ + # but this is overridden so installations will only check .ssh/authorized_keys + AuthorizedKeysFile .ssh/authorized_keys + ++#AuthorizedKeysCommand none ++#AuthorizedKeysCommandRunAs nobody ++ + # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts + #RhostsRSAAuthentication no + # similar for protocol version 2 diff --git a/openssh/patches/openssh-5.9p1-coverity.patch b/openssh/patches/openssh-5.9p1-coverity.patch new file mode 100644 index 0000000..f3524e3 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-coverity.patch @@ -0,0 +1,844 @@ +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-edns.patch b/openssh/patches/openssh-5.9p1-edns.patch new file mode 100644 index 0000000..34f3851 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-edns.patch @@ -0,0 +1,72 @@ +diff -up openssh-5.9p1/dns.c.edns openssh-5.9p1/dns.c +--- openssh-5.9p1/dns.c.edns 2010-08-31 14:41:14.000000000 +0200 ++++ openssh-5.9p1/dns.c 2011-09-09 08:05:27.782440497 +0200 +@@ -177,6 +177,7 @@ verify_host_key_dns(const char *hostname + { + u_int counter; + int result; ++ unsigned int rrset_flags = 0; + struct rrsetinfo *fingerprints = NULL; + + u_int8_t hostkey_algorithm; +@@ -200,8 +201,19 @@ verify_host_key_dns(const char *hostname + return -1; + } + ++ /* ++ * Original getrrsetbyname function, found on OpenBSD for example, ++ * doesn't accept any flag and prerequisite for obtaining AD bit in ++ * DNS response is set by "options edns0" in resolv.conf. ++ * ++ * Our version is more clever and use RRSET_FORCE_EDNS0 flag. ++ */ ++#ifndef HAVE_GETRRSETBYNAME ++ rrset_flags |= RRSET_FORCE_EDNS0; ++#endif + result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, +- DNS_RDATATYPE_SSHFP, 0, &fingerprints); ++ DNS_RDATATYPE_SSHFP, rrset_flags, &fingerprints); ++ + if (result) { + verbose("DNS lookup error: %s", dns_result_totext(result)); + return -1; +diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.c +--- openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns 2009-07-13 03:38:23.000000000 +0200 ++++ openssh-5.9p1/openbsd-compat/getrrsetbyname.c 2011-09-09 15:03:39.930500801 +0200 +@@ -209,8 +209,8 @@ getrrsetbyname(const char *hostname, uns + goto fail; + } + +- /* don't allow flags yet, unimplemented */ +- if (flags) { ++ /* Allow RRSET_FORCE_EDNS0 flag only. */ ++ if ((flags & ~RRSET_FORCE_EDNS0) != 0) { + result = ERRSET_INVAL; + goto fail; + } +@@ -226,9 +226,9 @@ getrrsetbyname(const char *hostname, uns + #endif /* DEBUG */ + + #ifdef RES_USE_DNSSEC +- /* turn on DNSSEC if EDNS0 is configured */ +- if (_resp->options & RES_USE_EDNS0) +- _resp->options |= RES_USE_DNSSEC; ++ /* turn on DNSSEC if required */ ++ if (flags & RRSET_FORCE_EDNS0) ++ _resp->options |= (RES_USE_EDNS0|RES_USE_DNSSEC); + #endif /* RES_USE_DNSEC */ + + /* make query */ +diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.h +--- openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns 2007-10-26 08:26:50.000000000 +0200 ++++ openssh-5.9p1/openbsd-compat/getrrsetbyname.h 2011-09-09 08:05:27.965438689 +0200 +@@ -72,6 +72,9 @@ + #ifndef RRSET_VALIDATED + # define RRSET_VALIDATED 1 + #endif ++#ifndef RRSET_FORCE_EDNS0 ++# define RRSET_FORCE_EDNS0 0x0001 ++#endif + + /* + * Return codes for getrrsetbyname() diff --git a/openssh/patches/openssh-5.9p1-entropy.patch b/openssh/patches/openssh-5.9p1-entropy.patch new file mode 100644 index 0000000..b3dec46 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-entropy.patch @@ -0,0 +1,251 @@ +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-ipfire.patch b/openssh/patches/openssh-5.9p1-ipfire.patch new file mode 100644 index 0000000..cdb49c6 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-ipfire.patch @@ -0,0 +1,108 @@ +diff -up openssh-5.9p0/ssh_config.redhat openssh-5.9p0/ssh_config +--- openssh-5.9p0/ssh_config.redhat 2010-01-12 09:40:27.000000000 +0100 ++++ openssh-5.9p0/ssh_config 2011-09-05 14:48:16.386439023 +0200 +@@ -45,3 +45,14 @@ + # PermitLocalCommand no + # VisualHostKey no + # ProxyCommand ssh -q -W %h:%p gateway.example.com ++Host * ++ GSSAPIAuthentication yes ++# If this option is set to yes then remote X11 clients will have full access ++# to the original X11 display. As virtually no X11 client supports the untrusted ++# mode correctly we set this to yes. ++ ForwardX11Trusted yes ++# Send locale-related environment variables ++ SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES ++ SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT ++ SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE ++ SendEnv XMODIFIERS +diff -up openssh-5.9p0/sshd_config.0.redhat openssh-5.9p0/sshd_config.0 +--- openssh-5.9p0/sshd_config.0.redhat 2011-09-05 14:48:08.522441255 +0200 ++++ openssh-5.9p0/sshd_config.0 2011-09-05 14:48:16.477443868 +0200 +@@ -581,9 +581,9 @@ DESCRIPTION + + SyslogFacility + Gives the facility code that is used when logging messages from +- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, +- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The +- default is AUTH. ++ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV, ++ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. ++ The default is AUTH. + + TCPKeepAlive + Specifies whether the system should send TCP keepalive messages +diff -up openssh-5.9p0/sshd_config.5.redhat openssh-5.9p0/sshd_config.5 +--- openssh-5.9p0/sshd_config.5.redhat 2011-09-05 14:48:08.657564688 +0200 ++++ openssh-5.9p0/sshd_config.5 2011-09-05 14:48:16.589501736 +0200 +@@ -1029,7 +1029,7 @@ Note that this option applies to protoco + .It Cm SyslogFacility + Gives the facility code that is used when logging messages from + .Xr sshd 8 . +-The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, ++The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, + LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. + The default is AUTH. + .It Cm TCPKeepAlive +diff -up openssh-5.9p0/sshd_config.redhat openssh-5.9p0/sshd_config +--- openssh-5.9p0/sshd_config.redhat 2011-09-05 14:48:16.250626793 +0200 ++++ openssh-5.9p0/sshd_config 2011-09-05 15:06:01.513443553 +0200 +@@ -32,6 +32,7 @@ + # Logging + # obsoletes QuietMode and FascistLogging + #SyslogFacility AUTH ++SyslogFacility AUTHPRIV + #LogLevel INFO + + # Authentication: +@@ -65,9 +66,11 @@ AuthorizedKeysFile .ssh/authorized_keys + # To disable tunneled clear text passwords, change to no here! + #PasswordAuthentication yes + #PermitEmptyPasswords no ++PasswordAuthentication yes + + # Change to no to disable s/key passwords + #ChallengeResponseAuthentication yes ++ChallengeResponseAuthentication no + + # Kerberos options + #KerberosAuthentication no +@@ -77,7 +80,9 @@ AuthorizedKeysFile .ssh/authorized_keys + + # GSSAPI options + #GSSAPIAuthentication no ++GSSAPIAuthentication yes + #GSSAPICleanupCredentials yes ++GSSAPICleanupCredentials yes + + # Set this to 'yes' to enable PAM authentication, account processing, + # and session processing. If this is enabled, PAM authentication will +@@ -89,6 +94,7 @@ AuthorizedKeysFile .ssh/authorized_keys + # PAM authentication, then enable this but set PasswordAuthentication + # and ChallengeResponseAuthentication to 'no'. + #UsePAM no ++UsePAM yes + + #TwoFactorAuthentication no + #SecondPubkeyAuthentication yes +@@ -101,6 +107,7 @@ AuthorizedKeysFile .ssh/authorized_keys + #AllowTcpForwarding yes + #GatewayPorts no + #X11Forwarding no ++X11Forwarding yes + #X11DisplayOffset 10 + #X11UseLocalhost yes + #PrintMotd yes +@@ -121,6 +128,12 @@ AuthorizedKeysFile .ssh/authorized_keys + # no default banner path + #Banner none + ++# Accept locale-related environment variables ++AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES ++AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT ++AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE ++AcceptEnv XMODIFIERS ++ + # override default of no subsystems + Subsystem sftp /usr/libexec/sftp-server + diff --git a/openssh/patches/openssh-5.9p1-ipv6man.patch b/openssh/patches/openssh-5.9p1-ipv6man.patch new file mode 100644 index 0000000..ece1a73 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-ipv6man.patch @@ -0,0 +1,24 @@ +diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1 +--- openssh-5.9p0/ssh.1.ipv6man 2011-08-05 22:17:32.000000000 +0200 ++++ openssh-5.9p0/ssh.1 2011-08-31 13:08:34.880024485 +0200 +@@ -1400,6 +1400,8 @@ manual page for more information. + .Nm + exits with the exit status of the remote command or with 255 + if an error occurred. ++.Sh IPV6 ++IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. + .Sh SEE ALSO + .Xr scp 1 , + .Xr sftp 1 , +diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8 +--- openssh-5.9p0/sshd.8.ipv6man 2011-08-05 22:17:32.000000000 +0200 ++++ openssh-5.9p0/sshd.8 2011-08-31 13:10:34.129039094 +0200 +@@ -940,6 +940,8 @@ concurrently for different ports, this c + started last). + The content of this file is not sensitive; it can be world-readable. + .El ++.Sh IPV6 ++IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. + .Sh SEE ALSO + .Xr scp 1 , + .Xr sftp 1 , diff --git a/openssh/patches/openssh-5.9p1-keygen.patch b/openssh/patches/openssh-5.9p1-keygen.patch new file mode 100644 index 0000000..69d4a6f --- /dev/null +++ b/openssh/patches/openssh-5.9p1-keygen.patch @@ -0,0 +1,80 @@ +diff -up openssh-5.9p0/ssh-keygen.0.keygen openssh-5.9p0/ssh-keygen.0 +--- openssh-5.9p0/ssh-keygen.0.keygen 2011-08-29 16:30:02.000000000 +0200 ++++ openssh-5.9p0/ssh-keygen.0 2011-08-30 13:47:56.208087184 +0200 +@@ -4,7 +4,7 @@ NAME + ssh-keygen - authentication key generation, management and conversion + + SYNOPSIS +- ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment] ++ ssh-keygen [-q] [-o] [-b bits] -t type [-N new_passphrase] [-C comment] + [-f output_keyfile] + ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] + ssh-keygen -i [-m key_format] [-f input_keyfile] +@@ -181,6 +181,8 @@ DESCRIPTION + principals may be specified, separated by commas. Please see the + CERTIFICATES section for details. + ++ -o Overwrite the key without prompting user. ++ + -O option + Specify a certificate option when signing a key. This option may + be specified multiple times. Please see the CERTIFICATES section +diff -up openssh-5.9p0/ssh-keygen.1.keygen openssh-5.9p0/ssh-keygen.1 +--- openssh-5.9p0/ssh-keygen.1.keygen 2011-08-30 13:32:30.787149917 +0200 ++++ openssh-5.9p0/ssh-keygen.1 2011-08-30 13:46:42.638087171 +0200 +@@ -45,6 +45,7 @@ + .Bk -words + .Nm ssh-keygen + .Op Fl q ++.Op Fl o + .Op Fl b Ar bits + .Fl t Ar type + .Op Fl N Ar new_passphrase +@@ -339,6 +340,8 @@ Multiple principals may be specified, se + Please see the + .Sx CERTIFICATES + section for details. ++.It Fl o ++Overwrite the key without prompting user. + .It Fl O Ar option + Specify a certificate option when signing a key. + This option may be specified multiple times. +diff -up openssh-5.9p0/ssh-keygen.c.keygen openssh-5.9p0/ssh-keygen.c +--- openssh-5.9p0/ssh-keygen.c.keygen 2011-08-30 13:32:20.268149992 +0200 ++++ openssh-5.9p0/ssh-keygen.c 2011-08-30 13:39:34.550214102 +0200 +@@ -73,6 +73,7 @@ int change_passphrase = 0; + int change_comment = 0; + + int quiet = 0; ++int overwrite = 0; + + int log_level = SYSLOG_LEVEL_INFO; + +@@ -1959,7 +1960,7 @@ main(int argc, char **argv) + exit(1); + } + +- while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:" ++ while ((opt = getopt(argc, argv, "AegiqopclBHLhvxXyF:b:f:t:D:I:P:m:N:n:" + "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) { + switch (opt) { + case 'A': +@@ -2042,6 +2043,9 @@ main(int argc, char **argv) + case 'q': + quiet = 1; + break; ++ case 'o': ++ overwrite = 1; ++ break; + case 'e': + case 'x': + /* export key */ +@@ -2278,7 +2282,7 @@ main(int argc, char **argv) + } + } + /* If the file already exists, ask the user to confirm. */ +- if (stat(identity_file, &st) >= 0) { ++ if (!overwrite && stat(identity_file, &st) >= 0) { + char yesno[3]; + printf("%s already exists.\n", identity_file); + printf("Overwrite (y/n)? "); diff --git a/openssh/patches/openssh-5.9p1-kuserok.patch b/openssh/patches/openssh-5.9p1-kuserok.patch new file mode 100644 index 0000000..11f38a5 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-kuserok.patch @@ -0,0 +1,167 @@ +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 new file mode 100644 index 0000000..1163949 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-mls.patch @@ -0,0 +1,400 @@ +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-randclean.patch b/openssh/patches/openssh-5.9p1-randclean.patch new file mode 100644 index 0000000..a2c5d33 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-randclean.patch @@ -0,0 +1,13 @@ +diff -up openssh-5.9p0/entropy.c.randclean openssh-5.9p0/entropy.c +--- openssh-5.9p0/entropy.c.randclean 2011-08-30 13:52:45.000000000 +0200 ++++ openssh-5.9p0/entropy.c 2011-08-30 13:57:44.630111338 +0200 +@@ -217,6 +217,9 @@ seed_rng(void) + fatal("OpenSSL version mismatch. Built against %lx, you " + "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); + ++ /* clean the PRNG status when exiting the program */ ++ atexit(RAND_cleanup); ++ + #ifndef OPENSSL_PRNG_ONLY + if (RAND_status() == 1) { + debug3("RNG is ready, skipping seeding"); diff --git a/openssh/patches/openssh-5.9p1-role.patch b/openssh/patches/openssh-5.9p1-role.patch new file mode 100644 index 0000000..8a26bdf --- /dev/null +++ b/openssh/patches/openssh-5.9p1-role.patch @@ -0,0 +1,613 @@ +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-sftp-chroot.patch b/openssh/patches/openssh-5.9p1-sftp-chroot.patch new file mode 100644 index 0000000..cfe4366 --- /dev/null +++ b/openssh/patches/openssh-5.9p1-sftp-chroot.patch @@ -0,0 +1,63 @@ +diff -up openssh-5.9p0/openbsd-compat/port-linux.c.sftp-chroot openssh-5.9p0/openbsd-compat/port-linux.c +--- openssh-5.9p0/openbsd-compat/port-linux.c.sftp-chroot 2011-09-01 04:12:22.743024608 +0200 ++++ openssh-5.9p0/openbsd-compat/port-linux.c 2011-09-01 04:12:23.069088065 +0200 +@@ -503,6 +503,23 @@ ssh_selinux_change_context(const char *n + xfree(newctx); + } + ++void ++ssh_selinux_copy_context(void) ++{ ++ char *ctx; ++ ++ if (!ssh_selinux_enabled()) ++ return; ++ ++ if (getexeccon((security_context_t *)&ctx) < 0) { ++ logit("%s: getcon failed with %s", __func__, strerror (errno)); ++ return; ++ } ++ if (setcon(ctx) < 0) ++ logit("%s: setcon failed with %s", __func__, strerror (errno)); ++ xfree(ctx); ++} ++ + #endif /* WITH_SELINUX */ + + #ifdef LINUX_OOM_ADJUST +diff -up openssh-5.9p0/openbsd-compat/port-linux.h.sftp-chroot openssh-5.9p0/openbsd-compat/port-linux.h +--- openssh-5.9p0/openbsd-compat/port-linux.h.sftp-chroot 2011-01-25 02:16:18.000000000 +0100 ++++ openssh-5.9p0/openbsd-compat/port-linux.h 2011-09-01 04:12:23.163088777 +0200 +@@ -24,6 +24,7 @@ int ssh_selinux_enabled(void); + void ssh_selinux_setup_pty(char *, const char *); + void ssh_selinux_setup_exec_context(char *); + void ssh_selinux_change_context(const char *); ++void ssh_selinux_chopy_context(void); + void ssh_selinux_setfscreatecon(const char *); + #endif + +diff -up openssh-5.9p0/session.c.sftp-chroot openssh-5.9p0/session.c +--- openssh-5.9p0/session.c.sftp-chroot 2011-09-01 04:12:19.698049195 +0200 ++++ openssh-5.9p0/session.c 2011-09-01 04:40:03.598148719 +0200 +@@ -1519,6 +1519,9 @@ do_setusercontext(struct passwd *pw) + pw->pw_uid); + chroot_path = percent_expand(tmp, "h", pw->pw_dir, + "u", pw->pw_name, (char *)NULL); ++#ifdef WITH_SELINUX ++ ssh_selinux_change_context("chroot_user_t"); ++#endif + safely_chroot(chroot_path, pw->pw_uid); + free(tmp); + free(chroot_path); +@@ -1788,7 +1791,10 @@ do_child(Session *s, const char *command + optind = optreset = 1; + __progname = argv[0]; + #ifdef WITH_SELINUX +- ssh_selinux_change_context("sftpd_t"); ++ if (options.chroot_directory == NULL || ++ strcasecmp(options.chroot_directory, "none") == 0) { ++ ssh_selinux_copy_context(); ++ } + #endif + exit(sftp_server_main(i, argv, s->pw)); + } diff --git a/openssh/patches/openssh-5.9p1-vendor.patch b/openssh/patches/openssh-5.9p1-vendor.patch new file mode 100644 index 0000000..3e63d3b --- /dev/null +++ b/openssh/patches/openssh-5.9p1-vendor.patch @@ -0,0 +1,157 @@ +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
hooks/post-receive -- IPFire 3.x development tree