Accepting request 222366 from network
- Update of the underlying OpenSSH to 6.5p1 - Update to 6.5p1 Features since 6.4p1: * ssh(1), sshd(8): support for key exchange using ECDH in Daniel Bernstein's Curve25519; default when both the client and server support it. * ssh(1), sshd(8): support for Ed25519 as a public key type fo rboth server and client. Ed25519 is an EC signature offering better security than ECDSA and DSA and good performance. * Add a new private key format that uses a bcrypt KDF to better protect keys at rest. Used unconditionally for Ed25519 keys, on demand for other key types via the -o ssh-keygen(1) option. Intended to become default in the near future. Details documented in PROTOCOL.key. * ssh(1), sshd(8): new transport cipher "chacha20-poly1305@openssh.com" combining Daniel Bernstein's ChaCha20 stream cipher and Poly1305 MAC to build an authenticated encryption mode. Details documented PROTOCOL.chacha20poly1305. * ssh(1), sshd(8): refuse RSA keys from old proprietary clients and servers that use the obsolete RSA+MD5 signature scheme. It will still be possible to connect with these clients/servers but only DSA keys will be accepted, and OpenSSH will refuse connection entirely in a future release. * ssh(1), sshd(8): refuse old proprietary clients and servers that use a weaker key exchange hash calculation. * ssh(1): increase the size of the Diffie-Hellman groups requested for each symmetric key size. New values from NIST Special Publication 800-57 with the upper limit specified by (forwarded request 222365 from pcerny) OBS-URL: https://build.opensuse.org/request/show/222366 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/openssh?expand=0&rev=90
This commit is contained in:
commit
f53e0cfba2
@ -1,11 +0,0 @@
|
||||
--- converter/Makefile.orig
|
||||
+++ converter/Makefile
|
||||
@@ -8,7 +8,7 @@ ssh-keyconverter.o: ssh-keyconverter.c .
|
||||
gcc $(RPM_OPT_FLAGS) -c -I../ $< -o $@
|
||||
|
||||
ssh-keyconverter: ssh-keyconverter.o ../libssh.a ../openbsd-compat/libopenbsd-compat.a
|
||||
- gcc $< -L../ -L../openbsd-compat/ -lssh -lopenbsd-compat -lssh -lpam -ldl -lwrap -lutil -lz -lnsl -lcrypt -lssl -o $@
|
||||
+ gcc -Wl,--no-as-needed $(RPM_OPT_FLAGS) -L../ -L../openbsd-compat/ $< -lssl -lcrypto -lssh -lopenbsd-compat -lssl -lssh -lpam -ldl -lwrap -lutil -lz -lnsl -lcrypt -o $@
|
||||
|
||||
install: ssh-keyconverter ssh-keyconverter.1
|
||||
if [ ! -d $(DESTDIR)$(bindir) ]; then install -d -m 755 $(DESTDIR)$(bindir); fi
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:da7ff204375259aef8aaf3ad89c7f311134354fe0129cddce927de5d4f7ab349
|
||||
size 4792
|
@ -1,224 +0,0 @@
|
||||
# add support for Linux audit (FATE #120269)
|
||||
================================================================================
|
||||
--- openssh-6.2p2.orig/Makefile.in
|
||||
+++ openssh-6.2p2/Makefile.in
|
||||
@@ -47,6 +47,7 @@ LIBS=@LIBS@
|
||||
K5LIBS=@K5LIBS@
|
||||
GSSLIBS=@GSSLIBS@
|
||||
SSHLIBS=@SSHLIBS@
|
||||
+LIBAUDIT=@LIBAUDIT@
|
||||
SSHDLIBS=@SSHDLIBS@
|
||||
LIBEDIT=@LIBEDIT@
|
||||
AR=@AR@
|
||||
@@ -144,7 +145,7 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SS
|
||||
$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS)
|
||||
|
||||
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
|
||||
- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
|
||||
+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(LIBAUDIT)
|
||||
|
||||
scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
|
||||
$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
--- openssh-6.2p2.orig/auth.c
|
||||
+++ openssh-6.2p2/auth.c
|
||||
@@ -298,6 +298,12 @@ auth_log(Authctxt *authctxt, int authent
|
||||
get_canonical_hostname(options.use_dns), "ssh", &loginmsg);
|
||||
# endif
|
||||
#endif
|
||||
+#if HAVE_LINUX_AUDIT
|
||||
+ if (authenticated == 0 && !authctxt->postponed) {
|
||||
+ linux_audit_record_event(-1, authctxt->user, NULL,
|
||||
+ get_remote_ipaddr(), "sshd", 0);
|
||||
+ }
|
||||
+#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
if (authenticated == 0 && !authctxt->postponed)
|
||||
audit_event(audit_classify_auth(method));
|
||||
@@ -606,6 +612,10 @@ getpwnamallow(const char *user)
|
||||
record_failed_login(user,
|
||||
get_canonical_hostname(options.use_dns), "ssh");
|
||||
#endif
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+ linux_audit_record_event(-1, user, NULL, get_remote_ipaddr(),
|
||||
+ "sshd", 0);
|
||||
+#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
audit_event(SSH_INVALID_USER);
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
--- openssh-6.2p2.orig/config.h.in
|
||||
+++ openssh-6.2p2/config.h.in
|
||||
@@ -1554,6 +1554,9 @@
|
||||
/* Define if you want SELinux support. */
|
||||
#undef WITH_SELINUX
|
||||
|
||||
+/* Define if you want Linux audit support. */
|
||||
+#undef HAVE_LINUX_AUDIT
|
||||
+
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
--- openssh-6.2p2.orig/configure.ac
|
||||
+++ openssh-6.2p2/configure.ac
|
||||
@@ -3653,6 +3653,20 @@ AC_ARG_WITH([selinux],
|
||||
AC_SUBST([SSHLIBS])
|
||||
AC_SUBST([SSHDLIBS])
|
||||
|
||||
+# Check whether user wants Linux audit support
|
||||
+LINUX_AUDIT_MSG="no"
|
||||
+LIBAUDIT=""
|
||||
+AC_ARG_WITH([linux-audit],
|
||||
+ [ --with-linux-audit Enable Linux audit support],
|
||||
+ [ if test "x$withval" != "xno" ; then
|
||||
+ AC_DEFINE([HAVE_LINUX_AUDIT],[1],[Define if you want Linux audit support.])
|
||||
+ LINUX_AUDIT_MSG="yes"
|
||||
+ AC_CHECK_HEADERS([libaudit.h])
|
||||
+ LIBAUDIT="-laudit"
|
||||
+ fi
|
||||
+ ])
|
||||
+AC_SUBST([LIBAUDIT])
|
||||
+
|
||||
# Check whether user wants Kerberos 5 support
|
||||
KRB5_MSG="no"
|
||||
AC_ARG_WITH([kerberos5],
|
||||
@@ -4569,6 +4583,7 @@ echo " PAM support
|
||||
echo " OSF SIA support: $SIA_MSG"
|
||||
echo " KerberosV support: $KRB5_MSG"
|
||||
echo " SELinux support: $SELINUX_MSG"
|
||||
+echo " Linux audit support: $LINUX_AUDIT_MSG"
|
||||
echo " Smartcard support: $SCARD_MSG"
|
||||
echo " S/KEY support: $SKEY_MSG"
|
||||
echo " TCP Wrappers support: $TCPW_MSG"
|
||||
--- openssh-6.2p2.orig/loginrec.c
|
||||
+++ openssh-6.2p2/loginrec.c
|
||||
@@ -176,6 +176,10 @@
|
||||
#include "auth.h"
|
||||
#include "buffer.h"
|
||||
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+# include <libaudit.h>
|
||||
+#endif
|
||||
+
|
||||
#ifdef HAVE_UTIL_H
|
||||
# include <util.h>
|
||||
#endif
|
||||
@@ -198,6 +202,9 @@ int utmp_write_entry(struct logininfo *l
|
||||
int utmpx_write_entry(struct logininfo *li);
|
||||
int wtmp_write_entry(struct logininfo *li);
|
||||
int wtmpx_write_entry(struct logininfo *li);
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+int linux_audit_write_entry(struct logininfo *li);
|
||||
+#endif
|
||||
int lastlog_write_entry(struct logininfo *li);
|
||||
int syslogin_write_entry(struct logininfo *li);
|
||||
|
||||
@@ -438,6 +445,10 @@ login_write(struct logininfo *li)
|
||||
|
||||
/* set the timestamp */
|
||||
login_set_current_time(li);
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+ if (linux_audit_write_entry(li) == 0)
|
||||
+ fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
+#endif
|
||||
#ifdef USE_LOGIN
|
||||
syslogin_write_entry(li);
|
||||
#endif
|
||||
@@ -1402,6 +1413,87 @@ wtmpx_get_entry(struct logininfo *li)
|
||||
}
|
||||
#endif /* USE_WTMPX */
|
||||
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+static void
|
||||
+_audit_hexscape(const char *what, char *where, unsigned int size)
|
||||
+{
|
||||
+ const char *ptr = what;
|
||||
+ const char *hex = "0123456789ABCDEF";
|
||||
+
|
||||
+ while (*ptr) {
|
||||
+ if (*ptr == '"' || *ptr < 0x21 || *ptr > 0x7E) {
|
||||
+ unsigned int i;
|
||||
+ ptr = what;
|
||||
+ for (i = 0; *ptr && i+2 < size; i += 2) {
|
||||
+ where[i] = hex[((unsigned)*ptr & 0xF0)>>4]; /* Upper nibble */
|
||||
+ where[i+1] = hex[(unsigned)*ptr & 0x0F]; /* Lower nibble */
|
||||
+ ptr++;
|
||||
+ }
|
||||
+ where[i] = '\0';
|
||||
+ return;
|
||||
+ }
|
||||
+ ptr++;
|
||||
+ }
|
||||
+ where[0] = '"';
|
||||
+ if ((unsigned)(ptr - what) < size - 3)
|
||||
+ {
|
||||
+ size = ptr - what + 3;
|
||||
+ }
|
||||
+ strncpy(where + 1, what, size - 3);
|
||||
+ where[size-2] = '"';
|
||||
+ where[size-1] = '\0';
|
||||
+}
|
||||
+
|
||||
+#define AUDIT_LOG_SIZE 128
|
||||
+#define AUDIT_ACCT_SIZE (AUDIT_LOG_SIZE - 8)
|
||||
+
|
||||
+int
|
||||
+linux_audit_record_event(int uid, const char *username,
|
||||
+ const char *hostname, const char *ip, const char *ttyn, int success)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, rc;
|
||||
+
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
+ errno == EAFNOSUPPORT)
|
||||
+ return 1; /* No audit support in kernel */
|
||||
+ else
|
||||
+ return 0; /* Must prevent login */
|
||||
+ }
|
||||
+ if (username == NULL)
|
||||
+ snprintf(buf, sizeof(buf), "uid=%d", uid);
|
||||
+ else {
|
||||
+ char encoded[AUDIT_ACCT_SIZE];
|
||||
+ _audit_hexscape(username, encoded, sizeof(encoded));
|
||||
+ snprintf(buf, sizeof(buf), "acct=%s", encoded);
|
||||
+ }
|
||||
+ rc = audit_log_user_message(audit_fd, AUDIT_USER_LOGIN,
|
||||
+ buf, hostname, ip, ttyn, success);
|
||||
+ close(audit_fd);
|
||||
+ if (rc >= 0)
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+linux_audit_write_entry(struct logininfo *li)
|
||||
+{
|
||||
+ switch(li->type) {
|
||||
+ case LTYPE_LOGIN:
|
||||
+ return (linux_audit_record_event(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1));
|
||||
+ case LTYPE_LOGOUT:
|
||||
+ return (1); /* We only care about logins */
|
||||
+ default:
|
||||
+ logit("%s: invalid type field", __func__);
|
||||
+ return (0);
|
||||
+ }
|
||||
+}
|
||||
+#endif /* HAVE_LINUX_AUDIT */
|
||||
+
|
||||
/**
|
||||
** Low-level libutil login() functions
|
||||
**/
|
||||
--- openssh-6.2p2.orig/loginrec.h
|
||||
+++ openssh-6.2p2/loginrec.h
|
||||
@@ -127,5 +127,9 @@ char *line_stripname(char *dst, const ch
|
||||
char *line_abbrevname(char *dst, const char *src, int dstsize);
|
||||
|
||||
void record_failed_login(const char *, const char *, const char *);
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+int linux_audit_record_event(int uid, const char *username,
|
||||
+ const char *hostname, const char *ip, const char *ttyn, int success);
|
||||
+#endif /* HAVE_LINUX_AUDIT */
|
||||
|
||||
#endif /* _HAVE_LOGINREC_H_ */
|
@ -1,43 +0,0 @@
|
||||
Index: log.c
|
||||
===================================================================
|
||||
--- log.c.orig
|
||||
+++ log.c
|
||||
@@ -51,6 +51,7 @@
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
+#include <signal.h>
|
||||
|
||||
static LogLevel log_level = SYSLOG_LEVEL_INFO;
|
||||
static int log_on_stderr = 1;
|
||||
@@ -336,6 +337,7 @@ do_log(LogLevel level, const char *fmt,
|
||||
char fmtbuf[MSGBUFSIZ];
|
||||
char *txt = NULL;
|
||||
int pri = LOG_INFO;
|
||||
+ sigset_t nset, oset;
|
||||
int saved_errno = errno;
|
||||
log_handler_fn *tmp_handler;
|
||||
|
||||
@@ -387,6 +389,14 @@ do_log(LogLevel level, const char *fmt,
|
||||
snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
|
||||
write(STDERR_FILENO, msgbuf, strlen(msgbuf));
|
||||
} else {
|
||||
+ /* Prevent a race between the grace_alarm
|
||||
+ * which writes a log message and terminates
|
||||
+ * and main sshd code that leads to deadlock
|
||||
+ * as syslog is not async safe.
|
||||
+ */
|
||||
+ sigemptyset(&nset);
|
||||
+ sigaddset(&nset, SIGALRM);
|
||||
+ sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
|
||||
openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
|
||||
syslog_r(pri, &sdata, "%.500s", fmtbuf);
|
||||
@@ -396,6 +406,7 @@ do_log(LogLevel level, const char *fmt,
|
||||
syslog(pri, "%.500s", fmtbuf);
|
||||
closelog();
|
||||
#endif
|
||||
+ sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
errno = saved_errno;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
Index: ssh_config
|
||||
===================================================================
|
||||
--- ssh_config.orig
|
||||
+++ ssh_config
|
||||
@@ -46,7 +46,7 @@ ForwardX11Trusted yes
|
||||
# IdentityFile ~/.ssh/id_rsa
|
||||
# IdentityFile ~/.ssh/id_dsa
|
||||
# Port 22
|
||||
-# Protocol 2,1
|
||||
+ Protocol 2
|
||||
# Cipher 3des
|
||||
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
|
||||
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
|
@ -1,45 +0,0 @@
|
||||
Index: openssh-5.8p1/sshd.8
|
||||
===================================================================
|
||||
--- openssh-5.8p1.orig/sshd.8
|
||||
+++ openssh-5.8p1/sshd.8
|
||||
@@ -855,7 +855,7 @@ Contains Diffie-Hellman groups used for
|
||||
The file format is described in
|
||||
.Xr moduli 5 .
|
||||
.Pp
|
||||
-.It Pa /etc/motd
|
||||
+.It Pa /etc/lib/motd
|
||||
See
|
||||
.Xr motd 5 .
|
||||
.Pp
|
||||
@@ -868,7 +868,7 @@ are displayed to anyone trying to log in
|
||||
refused.
|
||||
The file should be world-readable.
|
||||
.Pp
|
||||
-.It Pa /etc/shosts.equiv
|
||||
+.It Pa /etc/ssh/shosts.equiv
|
||||
This file is used in exactly the same way as
|
||||
.Pa hosts.equiv ,
|
||||
but allows host-based authentication without permitting login with
|
||||
@@ -947,8 +947,7 @@ The content of this file is not sensitiv
|
||||
.Xr ssh-keyscan 1 ,
|
||||
.Xr chroot 2 ,
|
||||
.Xr hosts_access 5 ,
|
||||
-.Xr login.conf 5 ,
|
||||
-.Xr moduli 5 ,
|
||||
+.Xr login.defs 5 ,
|
||||
.Xr sshd_config 5 ,
|
||||
.Xr inetd 8 ,
|
||||
.Xr sftp-server 8
|
||||
Index: openssh-5.8p1/sshd_config.5
|
||||
===================================================================
|
||||
--- openssh-5.8p1.orig/sshd_config.5
|
||||
+++ openssh-5.8p1/sshd_config.5
|
||||
@@ -497,7 +497,7 @@ or
|
||||
.Pp
|
||||
.Pa /etc/hosts.equiv
|
||||
and
|
||||
-.Pa /etc/shosts.equiv
|
||||
+.Pa /etc/ssh/shosts.equiv
|
||||
are still used.
|
||||
The default is
|
||||
.Dq yes .
|
@ -1,140 +0,0 @@
|
||||
Index: openssh-5.8p1/ssh-add.c
|
||||
===================================================================
|
||||
--- openssh-5.8p1.orig/ssh-add.c
|
||||
+++ openssh-5.8p1/ssh-add.c
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
+#include <openssl/engine.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
@@ -377,6 +378,10 @@ main(int argc, char **argv)
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
+ /* Init available hardware crypto engines. */
|
||||
+ ENGINE_load_builtin_engines();
|
||||
+ ENGINE_register_all_complete();
|
||||
+
|
||||
/* At first, get a connection to the authentication agent. */
|
||||
ac = ssh_get_authentication_connection();
|
||||
if (ac == NULL) {
|
||||
Index: openssh-5.8p1/ssh-agent.c
|
||||
===================================================================
|
||||
--- openssh-5.8p1.orig/ssh-agent.c
|
||||
+++ openssh-5.8p1/ssh-agent.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/md5.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
+#include <openssl/engine.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@@ -1153,6 +1154,10 @@ main(int ac, char **av)
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
+ /* Init available hardware crypto engines. */
|
||||
+ ENGINE_load_builtin_engines();
|
||||
+ ENGINE_register_all_complete();
|
||||
+
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
seed_rng();
|
||||
|
||||
Index: openssh-5.8p1/ssh-keygen.c
|
||||
===================================================================
|
||||
--- openssh-5.8p1.orig/ssh-keygen.c
|
||||
+++ openssh-5.8p1/ssh-keygen.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
+#include <openssl/engine.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@@ -1815,6 +1816,11 @@ main(int argc, char **argv)
|
||||
__progname = ssh_get_progname(argv[0]);
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
+
|
||||
+ /* Init available hardware crypto engines. */
|
||||
+ ENGINE_load_builtin_engines();
|
||||
+ ENGINE_register_all_complete();
|
||||
+
|
||||
log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
|
||||
|
||||
seed_rng();
|
||||
Index: openssh-5.8p1/ssh-keysign.c
|
||||
===================================================================
|
||||
--- openssh-5.8p1.orig/ssh-keysign.c
|
||||
+++ openssh-5.8p1/ssh-keysign.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rsa.h>
|
||||
+#include <openssl/engine.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
@@ -195,6 +196,11 @@ main(int argc, char **argv)
|
||||
fatal("could not open any host key");
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
+
|
||||
+ /* Init available hardware crypto engines. */
|
||||
+ ENGINE_load_builtin_engines();
|
||||
+ ENGINE_register_all_complete();
|
||||
+
|
||||
for (i = 0; i < 256; i++)
|
||||
rnd[i] = arc4random();
|
||||
RAND_seed(rnd, sizeof(rnd));
|
||||
Index: openssh-5.8p1/ssh.c
|
||||
===================================================================
|
||||
--- openssh-5.8p1.orig/ssh.c
|
||||
+++ openssh-5.8p1/ssh.c
|
||||
@@ -75,6 +75,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
+#include <openssl/engine.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
@@ -601,6 +602,10 @@ main(int ac, char **av)
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
+ /* Init available hardware crypto engines. */
|
||||
+ ENGINE_load_builtin_engines();
|
||||
+ ENGINE_register_all_complete();
|
||||
+
|
||||
/* Initialize the command to execute on remote host. */
|
||||
buffer_init(&command);
|
||||
|
||||
Index: openssh-5.8p1/sshd.c
|
||||
===================================================================
|
||||
--- openssh-5.8p1.orig/sshd.c
|
||||
+++ openssh-5.8p1/sshd.c
|
||||
@@ -77,6 +77,7 @@
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
+#include <openssl/engine.h>
|
||||
|
||||
#ifdef HAVE_SECUREWARE
|
||||
#include <sys/security.h>
|
||||
@@ -1474,6 +1475,10 @@ main(int ac, char **av)
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
+ /* Init available hardware crypto engines. */
|
||||
+ ENGINE_load_builtin_engines();
|
||||
+ ENGINE_register_all_complete();
|
||||
+
|
||||
/*
|
||||
* Force logging to stderr until we have loaded the private host
|
||||
* key (unless started from inetd)
|
@ -1,259 +0,0 @@
|
||||
The patch below adds support for the deprecated 'gssapi' authentication
|
||||
mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
|
||||
in this release. The use of 'gssapi' is deprecated due to the presence of
|
||||
potential man-in-the-middle attacks, which 'gssapi-with-mic' is not
|
||||
susceptible to.
|
||||
|
||||
To use the patch apply it to a OpenSSH 3.8p1 source tree. After compiling,
|
||||
backwards compatibility may be obtained by supplying the
|
||||
'GssapiEnableMitmAttack yes' option to either the client or server.
|
||||
|
||||
It should be noted that this patch is being made available purely as a means
|
||||
of easing the process of moving to OpenSSH 3.8p1. Any new installations are
|
||||
recommended to use the 'gssapi-with-mic' mechanism. Existing installations
|
||||
are encouraged to upgrade as soon as possible.
|
||||
|
||||
Index: auth2-gss.c
|
||||
===================================================================
|
||||
--- auth2-gss.c.orig
|
||||
+++ auth2-gss.c
|
||||
@@ -177,6 +177,15 @@ input_gssapi_token(int type, u_int32_t p
|
||||
dispatch_set(
|
||||
SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
|
||||
&input_gssapi_exchange_complete);
|
||||
+
|
||||
+ /*
|
||||
+ * Old style 'gssapi' didn't have the GSSAPI_MIC
|
||||
+ * and went straight to sending exchange_complete
|
||||
+ */
|
||||
+ if (options.gss_enable_mitm)
|
||||
+ dispatch_set(
|
||||
+ SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
|
||||
+ &input_gssapi_exchange_complete);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,4 +307,10 @@ Authmethod method_gssapi = {
|
||||
&options.gss_authentication
|
||||
};
|
||||
|
||||
+Authmethod method_gssapi_old = {
|
||||
+ "gssapi",
|
||||
+ userauth_gssapi,
|
||||
+ &options.gss_enable_mitm
|
||||
+};
|
||||
+
|
||||
#endif /* GSSAPI */
|
||||
Index: auth2.c
|
||||
===================================================================
|
||||
--- auth2.c.orig
|
||||
+++ auth2.c
|
||||
@@ -70,6 +70,7 @@ extern Authmethod method_kbdint;
|
||||
extern Authmethod method_hostbased;
|
||||
#ifdef GSSAPI
|
||||
extern Authmethod method_gssapi;
|
||||
+extern Authmethod method_gssapi_old;
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
extern Authmethod method_jpake;
|
||||
@@ -80,6 +81,7 @@ Authmethod *authmethods[] = {
|
||||
&method_pubkey,
|
||||
#ifdef GSSAPI
|
||||
&method_gssapi,
|
||||
+ &method_gssapi_old,
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
&method_jpake,
|
||||
Index: readconf.c
|
||||
===================================================================
|
||||
--- readconf.c.orig
|
||||
+++ readconf.c
|
||||
@@ -128,7 +128,7 @@ typedef enum {
|
||||
oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
|
||||
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
|
||||
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
|
||||
- oAddressFamily, oGssAuthentication, oGssDelegateCreds,
|
||||
+ oAddressFamily, oGssAuthentication, oGssDelegateCreds, oGssEnableMITM,
|
||||
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
|
||||
oSendEnv, oControlPath, oControlMaster, oControlPersist,
|
||||
oHashKnownHosts,
|
||||
@@ -170,9 +170,11 @@ static struct {
|
||||
#if defined(GSSAPI)
|
||||
{ "gssapiauthentication", oGssAuthentication },
|
||||
{ "gssapidelegatecredentials", oGssDelegateCreds },
|
||||
+ { "gssapienablemitmattack", oGssEnableMITM },
|
||||
#else
|
||||
{ "gssapiauthentication", oUnsupported },
|
||||
{ "gssapidelegatecredentials", oUnsupported },
|
||||
+ { "gssapienablemitmattack", oUnsupported },
|
||||
#endif
|
||||
{ "fallbacktorsh", oDeprecated },
|
||||
{ "usersh", oDeprecated },
|
||||
@@ -483,6 +485,10 @@ parse_flag:
|
||||
intptr = &options->gss_deleg_creds;
|
||||
goto parse_flag;
|
||||
|
||||
+ case oGssEnableMITM:
|
||||
+ intptr = &options->gss_enable_mitm;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case oBatchMode:
|
||||
intptr = &options->batch_mode;
|
||||
goto parse_flag;
|
||||
@@ -1093,6 +1099,7 @@ initialize_options(Options * options)
|
||||
options->challenge_response_authentication = -1;
|
||||
options->gss_authentication = -1;
|
||||
options->gss_deleg_creds = -1;
|
||||
+ options->gss_enable_mitm = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->kbd_interactive_devices = NULL;
|
||||
@@ -1195,6 +1202,8 @@ fill_default_options(Options * options)
|
||||
options->gss_authentication = 0;
|
||||
if (options->gss_deleg_creds == -1)
|
||||
options->gss_deleg_creds = 0;
|
||||
+ if (options->gss_enable_mitm == -1)
|
||||
+ options->gss_enable_mitm = 0;
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
Index: readconf.h
|
||||
===================================================================
|
||||
--- readconf.h.orig
|
||||
+++ readconf.h
|
||||
@@ -47,6 +47,7 @@ typedef struct {
|
||||
/* Try S/Key or TIS, authentication. */
|
||||
int gss_authentication; /* Try GSS authentication */
|
||||
int gss_deleg_creds; /* Delegate GSS credentials */
|
||||
+ int gss_enable_mitm; /* Enable old style gssapi auth */
|
||||
int password_authentication; /* Try password
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
|
||||
Index: servconf.c
|
||||
===================================================================
|
||||
--- servconf.c.orig
|
||||
+++ servconf.c
|
||||
@@ -98,6 +98,7 @@ initialize_server_options(ServerOptions
|
||||
options->kerberos_get_afs_token = -1;
|
||||
options->gss_authentication=-1;
|
||||
options->gss_cleanup_creds = -1;
|
||||
+ options->gss_enable_mitm = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->challenge_response_authentication = -1;
|
||||
@@ -228,6 +229,8 @@ fill_default_server_options(ServerOption
|
||||
options->gss_authentication = 0;
|
||||
if (options->gss_cleanup_creds == -1)
|
||||
options->gss_cleanup_creds = 1;
|
||||
+ if (options->gss_enable_mitm == -1)
|
||||
+ options->gss_enable_mitm = 0;
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
@@ -322,7 +325,7 @@ typedef enum {
|
||||
sBanner, sUseDNS, sHostbasedAuthentication,
|
||||
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
|
||||
sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
- sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
|
||||
+ sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sGssEnableMITM,
|
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
sZeroKnowledgePasswordAuthentication, sHostCertificate,
|
||||
@@ -386,9 +389,11 @@ static struct {
|
||||
#ifdef GSSAPI
|
||||
{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
|
||||
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
|
||||
+ { "gssapienablemitmattack", sGssEnableMITM },
|
||||
#else
|
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "gssapienablemitmattack", sUnsupported },
|
||||
#endif
|
||||
{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
|
||||
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
|
||||
@@ -948,6 +953,10 @@ process_server_config_line(ServerOptions
|
||||
intptr = &options->gss_cleanup_creds;
|
||||
goto parse_flag;
|
||||
|
||||
+ case sGssEnableMITM:
|
||||
+ intptr = &options->gss_enable_mitm;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sPasswordAuthentication:
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
Index: servconf.h
|
||||
===================================================================
|
||||
--- servconf.h.orig
|
||||
+++ servconf.h
|
||||
@@ -98,6 +98,7 @@ typedef struct {
|
||||
* authenticated with Kerberos. */
|
||||
int gss_authentication; /* If true, permit GSSAPI authentication */
|
||||
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
|
||||
+ int gss_enable_mitm; /* If true, enable old style GSSAPI */
|
||||
int password_authentication; /* If true, permit password
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* If true, permit */
|
||||
Index: ssh_config
|
||||
===================================================================
|
||||
--- ssh_config.orig
|
||||
+++ ssh_config
|
||||
@@ -54,5 +54,15 @@ ForwardX11Trusted yes
|
||||
# Tunnel no
|
||||
# TunnelDevice any:any
|
||||
# PermitLocalCommand no
|
||||
+# GSSAPIAuthentication no
|
||||
+# GSSAPIDelegateCredentials no
|
||||
+
|
||||
+# Set this to 'yes' to enable support for the deprecated 'gssapi' authentication
|
||||
+# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
|
||||
+# in this release. The use of 'gssapi' is deprecated due to the presence of
|
||||
+# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not susceptible to.
|
||||
+# GSSAPIEnableMITMAttack no
|
||||
+
|
||||
+>>>>>>>
|
||||
# VisualHostKey no
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
Index: sshconnect2.c
|
||||
===================================================================
|
||||
--- sshconnect2.c.orig
|
||||
+++ sshconnect2.c
|
||||
@@ -324,6 +324,10 @@ Authmethod authmethods[] = {
|
||||
NULL,
|
||||
&options.gss_authentication,
|
||||
NULL},
|
||||
+ {"gssapi",
|
||||
+ userauth_gssapi,
|
||||
+ &options.gss_enable_mitm,
|
||||
+ NULL},
|
||||
#endif
|
||||
{"hostbased",
|
||||
userauth_hostbased,
|
||||
@@ -701,7 +705,9 @@ process_gssapi_token(void *ctxt, gss_buf
|
||||
|
||||
if (status == GSS_S_COMPLETE) {
|
||||
/* send either complete or MIC, depending on mechanism */
|
||||
- if (!(flags & GSS_C_INTEG_FLAG)) {
|
||||
+
|
||||
+ if (strcmp(authctxt->method->name,"gssapi")==0 ||
|
||||
+ (!(flags & GSS_C_INTEG_FLAG))) {
|
||||
packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
|
||||
packet_send();
|
||||
} else {
|
||||
Index: sshd_config
|
||||
===================================================================
|
||||
--- sshd_config.orig
|
||||
+++ sshd_config
|
||||
@@ -73,6 +73,12 @@ PasswordAuthentication no
|
||||
#GSSAPIAuthentication no
|
||||
#GSSAPICleanupCredentials yes
|
||||
|
||||
+# Set this to 'yes' to enable support for the deprecated 'gssapi' authentication
|
||||
+# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
|
||||
+# in this release. The use of 'gssapi' is deprecated due to the presence of
|
||||
+# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not susceptible to.
|
||||
+#GSSAPIEnableMITMAttack no
|
||||
+
|
||||
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||
# and session processing. If this is enabled, PAM authentication will
|
||||
# be allowed through the ChallengeResponseAuthentication and
|
@ -1,16 +0,0 @@
|
||||
Index: openssh-5.7p1/sshconnect.c
|
||||
===================================================================
|
||||
--- openssh-5.7p1.orig/sshconnect.c
|
||||
+++ openssh-5.7p1/sshconnect.c
|
||||
@@ -958,6 +958,11 @@ check_host_key(char *hostname, struct so
|
||||
user_hostfiles[0]);
|
||||
error("Offending %s key in %s:%lu", key_type(host_found->key),
|
||||
host_found->file, host_found->line);
|
||||
+ error("You can use following command to remove all keys for this IP:");
|
||||
+ if (host_found->file)
|
||||
+ error("ssh-keygen -R %s -f %s", hostname, host_found->file);
|
||||
+ else
|
||||
+ error("ssh-keygen -R %s", hostname);
|
||||
|
||||
/*
|
||||
* If strict host key checking is in use, the user will have
|
@ -1,22 +0,0 @@
|
||||
Index: sshd_config
|
||||
===================================================================
|
||||
--- sshd_config.orig
|
||||
+++ sshd_config
|
||||
@@ -57,7 +57,7 @@
|
||||
#IgnoreRhosts yes
|
||||
|
||||
# To disable tunneled clear text passwords, change to no here!
|
||||
-#PasswordAuthentication yes
|
||||
+PasswordAuthentication no
|
||||
#PermitEmptyPasswords no
|
||||
|
||||
# Change to no to disable s/key passwords
|
||||
@@ -82,7 +82,7 @@
|
||||
# If you just want the PAM account and session checks to run without
|
||||
# PAM authentication, then enable this but set PasswordAuthentication
|
||||
# and ChallengeResponseAuthentication to 'no'.
|
||||
-#UsePAM no
|
||||
+UsePAM yes
|
||||
|
||||
#AllowAgentForwarding yes
|
||||
#AllowTcpForwarding yes
|
@ -1,15 +0,0 @@
|
||||
Index: auth-pam.c
|
||||
===================================================================
|
||||
--- auth-pam.c.orig
|
||||
+++ auth-pam.c
|
||||
@@ -786,7 +786,9 @@ sshpam_query(void *ctx, char **name, cha
|
||||
fatal("Internal error: PAM auth "
|
||||
"succeeded when it should have "
|
||||
"failed");
|
||||
- import_environments(&buffer);
|
||||
+#ifndef USE_POSIX_THREADS
|
||||
+ import_environments(&buffer);
|
||||
+#endif
|
||||
*num = 0;
|
||||
**echo_on = 0;
|
||||
ctxt->pam_done = 1;
|
@ -1,24 +0,0 @@
|
||||
Index: loginrec.c
|
||||
===================================================================
|
||||
--- loginrec.c.orig
|
||||
+++ loginrec.c
|
||||
@@ -555,7 +555,7 @@ getlast_entry(struct logininfo *li)
|
||||
* 1. The full filename (including '/dev')
|
||||
* 2. The stripped name (excluding '/dev')
|
||||
* 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00
|
||||
- * /dev/pts/1 -> ts/1 )
|
||||
+ * /dev/pts/1 -> /1 )
|
||||
*
|
||||
* Form 3 is used on some systems to identify a .tmp.? entry when
|
||||
* attempting to remove it. Typically both addition and removal is
|
||||
@@ -616,6 +616,10 @@ line_abbrevname(char *dst, const char *s
|
||||
if (strncmp(src, "tty", 3) == 0)
|
||||
src += 3;
|
||||
#endif
|
||||
+ if (strncmp(src, "pts/", 4) == 0) {
|
||||
+ src += 3;
|
||||
+ if (strlen(src) > 4) src++;
|
||||
+ }
|
||||
|
||||
len = strlen(src);
|
||||
|
@ -1,25 +0,0 @@
|
||||
Index: sshd.c
|
||||
===================================================================
|
||||
--- sshd.c.orig
|
||||
+++ sshd.c
|
||||
@@ -306,6 +306,7 @@ sighup_handler(int sig)
|
||||
static void
|
||||
sighup_restart(void)
|
||||
{
|
||||
+ int i;
|
||||
logit("Received SIGHUP; restarting.");
|
||||
close_listen_socks();
|
||||
close_startup_pipes();
|
||||
@@ -1319,7 +1320,11 @@ main(int ac, char **av)
|
||||
#ifndef HAVE_SETPROCTITLE
|
||||
/* Prepare for later setproctitle emulation */
|
||||
compat_init_setproctitle(ac, av);
|
||||
- av = saved_argv;
|
||||
+
|
||||
+ av = xmalloc(sizeof(*saved_argv) * (saved_argc + 1));
|
||||
+ for (i = 0; i < saved_argc; i++)
|
||||
+ av[i] = xstrdup(saved_argv[i]);
|
||||
+ av[i] = NULL;
|
||||
#endif
|
||||
|
||||
if (geteuid() == 0 && setgroups(0, NULL) == -1)
|
@ -1,19 +0,0 @@
|
||||
Index: ssh_config
|
||||
===================================================================
|
||||
--- ssh_config.orig
|
||||
+++ ssh_config
|
||||
@@ -67,5 +67,13 @@ ForwardX11Trusted yes
|
||||
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
|
||||
-# VisualHostKey no
|
||||
+
|
||||
+# This will print the fingerprint of the host key in "visual" form
|
||||
+# this should make it easier to also recognize bad things
|
||||
+VisualHostKey no
|
||||
+
|
||||
+# This will hash new host keys and make them so unusable for malicious
|
||||
+# people or software trying to use known_hosts to find further hops.
|
||||
+HashKnownHosts yes
|
||||
+
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
@ -1,51 +0,0 @@
|
||||
Index: ssh_config
|
||||
===================================================================
|
||||
--- ssh_config.orig
|
||||
+++ ssh_config
|
||||
@@ -17,9 +17,20 @@
|
||||
# list of available options, their meanings and defaults, please see the
|
||||
# ssh_config(5) man page.
|
||||
|
||||
-# Host *
|
||||
+Host *
|
||||
# ForwardAgent no
|
||||
# ForwardX11 no
|
||||
+
|
||||
+# If you do not trust your remote host (or its administrator), you
|
||||
+# should not forward X11 connections to your local X11-display for
|
||||
+# security reasons: Someone stealing the authentification data on the
|
||||
+# remote side (the "spoofed" X-server by the remote sshd) can read your
|
||||
+# keystrokes as you type, just like any other X11 client could do.
|
||||
+# Set this to "no" here for global effect or in your own ~/.ssh/config
|
||||
+# file if you want to have the remote X11 authentification data to
|
||||
+# expire after two minutes after remote login.
|
||||
+ForwardX11Trusted yes
|
||||
+
|
||||
# RhostsRSAAuthentication no
|
||||
# RSAAuthentication yes
|
||||
# PasswordAuthentication yes
|
||||
Index: sshd_config
|
||||
===================================================================
|
||||
--- sshd_config.orig
|
||||
+++ sshd_config
|
||||
@@ -87,7 +87,7 @@
|
||||
#AllowAgentForwarding yes
|
||||
#AllowTcpForwarding yes
|
||||
#GatewayPorts no
|
||||
-#X11Forwarding no
|
||||
+X11Forwarding yes
|
||||
#X11DisplayOffset 10
|
||||
#X11UseLocalhost yes
|
||||
#PrintMotd yes
|
||||
Index: sshlogin.c
|
||||
===================================================================
|
||||
--- sshlogin.c.orig
|
||||
+++ sshlogin.c
|
||||
@@ -133,6 +133,7 @@ record_login(pid_t pid, const char *tty,
|
||||
|
||||
li = login_alloc_entry(pid, user, host, tty);
|
||||
login_set_addr(li, addr, addrlen);
|
||||
+ li->uid=uid;
|
||||
login_login(li);
|
||||
login_free_entry(li);
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
Index: session.c
|
||||
===================================================================
|
||||
--- session.c.orig
|
||||
+++ session.c
|
||||
@@ -1116,7 +1116,7 @@ copy_environment(char **source, char ***
|
||||
}
|
||||
|
||||
static char **
|
||||
-do_setup_env(Session *s, const char *shell)
|
||||
+do_setup_env(Session *s, const char *shell, int *env_size)
|
||||
{
|
||||
char buf[256];
|
||||
u_int i, envsize;
|
||||
@@ -1303,6 +1303,8 @@ do_setup_env(Session *s, const char *she
|
||||
for (i = 0; env[i]; i++)
|
||||
fprintf(stderr, " %.200s\n", env[i]);
|
||||
}
|
||||
+
|
||||
+ *env_size = envsize;
|
||||
return env;
|
||||
}
|
||||
|
||||
@@ -1311,7 +1313,7 @@ do_setup_env(Session *s, const char *she
|
||||
* first in this order).
|
||||
*/
|
||||
static void
|
||||
-do_rc_files(Session *s, const char *shell)
|
||||
+do_rc_files(Session *s, const char *shell, char **env, int *env_size)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
char cmd[1024];
|
||||
@@ -1365,12 +1367,20 @@ do_rc_files(Session *s, const char *shel
|
||||
options.xauth_location);
|
||||
f = popen(cmd, "w");
|
||||
if (f) {
|
||||
+ char hostname[MAXHOSTNAMELEN];
|
||||
+
|
||||
fprintf(f, "remove %s\n",
|
||||
s->auth_display);
|
||||
fprintf(f, "add %s %s %s\n",
|
||||
s->auth_display, s->auth_proto,
|
||||
s->auth_data);
|
||||
pclose(f);
|
||||
+ if (gethostname(hostname,sizeof(hostname)) >= 0)
|
||||
+ child_set_env(&env,env_size,"XAUTHLOCALHOSTNAME",
|
||||
+ hostname);
|
||||
+ else
|
||||
+ debug("Cannot set up XAUTHLOCALHOSTNAME %s\n",
|
||||
+ strerror(errno));
|
||||
} else {
|
||||
fprintf(stderr, "Could not run %s\n",
|
||||
cmd);
|
||||
@@ -1608,6 +1618,7 @@ do_child(Session *s, const char *command
|
||||
{
|
||||
extern char **environ;
|
||||
char **env;
|
||||
+ int env_size;
|
||||
char *argv[ARGV_MAX];
|
||||
const char *shell, *shell0, *hostname = NULL;
|
||||
struct passwd *pw = s->pw;
|
||||
@@ -1674,7 +1685,7 @@ do_child(Session *s, const char *command
|
||||
* Make sure $SHELL points to the shell from the password file,
|
||||
* even if shell is overridden from login.conf
|
||||
*/
|
||||
- env = do_setup_env(s, shell);
|
||||
+ env = do_setup_env(s, shell, &env_size);
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
|
||||
@@ -1743,7 +1754,7 @@ do_child(Session *s, const char *command
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
if (!options.use_login)
|
||||
- do_rc_files(s, shell);
|
||||
+ do_rc_files(s, shell, env, &env_size);
|
||||
|
||||
/* restore SIGPIPE for child */
|
||||
signal(SIGPIPE, SIG_DFL);
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7f29b9d2ad672ae0f9e1dcbff871fc5c2e60a194e90c766432e32161b842313b
|
||||
size 1182922
|
61
openssh-6.5p1-X11-forwarding.patch
Normal file
61
openssh-6.5p1-X11-forwarding.patch
Normal file
@ -0,0 +1,61 @@
|
||||
# enable trusted X11 forwarding by default in both sshd and sshsystem-wide
|
||||
# configuration
|
||||
# bnc#50836 (was suse #35836)
|
||||
|
||||
diff --git a/openssh-6.5p1/ssh_config b/openssh-6.5p1/ssh_config
|
||||
--- a/openssh-6.5p1/ssh_config
|
||||
+++ b/openssh-6.5p1/ssh_config
|
||||
@@ -12,19 +12,30 @@
|
||||
# Any configuration value is only changed the first time it is set.
|
||||
# Thus, host-specific definitions should be at the beginning of the
|
||||
# configuration file, and defaults at the end.
|
||||
|
||||
# Site-wide defaults for some commonly used options. For a comprehensive
|
||||
# list of available options, their meanings and defaults, please see the
|
||||
# ssh_config(5) man page.
|
||||
|
||||
-# Host *
|
||||
+Host *
|
||||
# ForwardAgent no
|
||||
# ForwardX11 no
|
||||
+
|
||||
+# If you do not trust your remote host (or its administrator), you
|
||||
+# should not forward X11 connections to your local X11-display for
|
||||
+# security reasons: Someone stealing the authentification data on the
|
||||
+# remote side (the "spoofed" X-server by the remote sshd) can read your
|
||||
+# keystrokes as you type, just like any other X11 client could do.
|
||||
+# Set this to "no" here for global effect or in your own ~/.ssh/config
|
||||
+# file if you want to have the remote X11 authentification data to
|
||||
+# expire after two minutes after remote login.
|
||||
+ForwardX11Trusted yes
|
||||
+
|
||||
# RhostsRSAAuthentication no
|
||||
# RSAAuthentication yes
|
||||
# PasswordAuthentication yes
|
||||
# HostbasedAuthentication no
|
||||
# GSSAPIAuthentication no
|
||||
# GSSAPIDelegateCredentials no
|
||||
# BatchMode no
|
||||
# CheckHostIP yes
|
||||
diff --git a/openssh-6.5p1/sshd_config b/openssh-6.5p1/sshd_config
|
||||
--- a/openssh-6.5p1/sshd_config
|
||||
+++ b/openssh-6.5p1/sshd_config
|
||||
@@ -94,17 +94,17 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
# If you just want the PAM account and session checks to run without
|
||||
# PAM authentication, then enable this but set PasswordAuthentication
|
||||
# and ChallengeResponseAuthentication to 'no'.
|
||||
#UsePAM no
|
||||
|
||||
#AllowAgentForwarding yes
|
||||
#AllowTcpForwarding yes
|
||||
#GatewayPorts no
|
||||
-#X11Forwarding no
|
||||
+X11Forwarding yes
|
||||
#X11DisplayOffset 10
|
||||
#X11UseLocalhost yes
|
||||
#PermitTTY yes
|
||||
#PrintMotd yes
|
||||
#PrintLastLog yes
|
||||
#TCPKeepAlive yes
|
||||
#UseLogin no
|
||||
UsePrivilegeSeparation sandbox # Default for new installations.
|
33
openssh-6.5p1-audit1-remove_duplicit_audit.patch
Normal file
33
openssh-6.5p1-audit1-remove_duplicit_audit.patch
Normal file
@ -0,0 +1,33 @@
|
||||
# Don't audit SSH_INVALID_USER twice.
|
||||
# PRIVSEP(getpwnamallow()) a few lines above already did this.
|
||||
#
|
||||
# based on:
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
# https://bugzilla.mindrot.org/attachment.cgi?id=2010
|
||||
# by jchadima@redhat.com
|
||||
#
|
||||
# PRIVSEP(getpwnamallow()) a few lines above already did this.
|
||||
|
||||
diff --git a/openssh-6.5p1/auth2.c b/openssh-6.5p1/auth2.c
|
||||
--- a/openssh-6.5p1/auth2.c
|
||||
+++ b/openssh-6.5p1/auth2.c
|
||||
@@ -242,19 +242,16 @@ input_userauth_request(int type, u_int32
|
||||
authctxt->pw = PRIVSEP(getpwnamallow(user));
|
||||
authctxt->user = xstrdup(user);
|
||||
if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
|
||||
authctxt->valid = 1;
|
||||
debug2("input_userauth_request: setting up authctxt for %s", user);
|
||||
} else {
|
||||
logit("input_userauth_request: invalid user %s", user);
|
||||
authctxt->pw = fakepw();
|
||||
-#ifdef SSH_AUDIT_EVENTS
|
||||
- PRIVSEP(audit_event(SSH_INVALID_USER));
|
||||
-#endif
|
||||
}
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
PRIVSEP(start_pam(authctxt));
|
||||
#endif
|
||||
setproctitle("%s%s", authctxt->valid ? user : "unknown",
|
||||
use_privsep ? " [net]" : "");
|
||||
authctxt->service = xstrdup(service);
|
867
openssh-6.5p1-audit2-better_audit_of_user_actions.patch
Normal file
867
openssh-6.5p1-audit2-better_audit_of_user_actions.patch
Normal file
@ -0,0 +1,867 @@
|
||||
# extended auditing of user actions
|
||||
# based on:
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
# https://bugzilla.mindrot.org/attachment.cgi?id=2011
|
||||
# by jchadima@redhat.com
|
||||
|
||||
diff --git a/openssh-6.5p1/audit-bsm.c b/openssh-6.5p1/audit-bsm.c
|
||||
--- a/openssh-6.5p1/audit-bsm.c
|
||||
+++ b/openssh-6.5p1/audit-bsm.c
|
||||
@@ -370,20 +370,33 @@ audit_connection_from(const char *host,
|
||||
/* this is used on IPv4-only machines */
|
||||
tid->port = (dev_t)port;
|
||||
tid->machine = inet_addr(host);
|
||||
snprintf(buf, sizeof(buf), "%08x", tid->machine);
|
||||
debug3("BSM audit: machine ID %s", buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
-void
|
||||
+int
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
/* not implemented */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_end_command(int handle, const char *command)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_count_session_open(void)
|
||||
+{
|
||||
+ /* not necessary */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
diff --git a/openssh-6.5p1/audit-linux.c b/openssh-6.5p1/audit-linux.c
|
||||
--- a/openssh-6.5p1/audit-linux.c
|
||||
+++ b/openssh-6.5p1/audit-linux.c
|
||||
@@ -30,97 +30,210 @@
|
||||
#include "includes.h"
|
||||
#if defined(USE_LINUX_AUDIT)
|
||||
#include <libaudit.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "audit.h"
|
||||
+#include "key.h"
|
||||
+#include "hostfile.h"
|
||||
+#include "auth.h"
|
||||
+#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
|
||||
+extern ServerOptions options;
|
||||
+extern Authctxt *the_authctxt;
|
||||
+extern u_int utmp_len;
|
||||
const char* audit_username(void);
|
||||
|
||||
-int
|
||||
-linux_audit_record_event(int uid, const char *username,
|
||||
- const char *hostname, const char *ip, const char *ttyn, int success)
|
||||
+static void
|
||||
+linux_audit_user_logxxx(int uid, const char *username,
|
||||
+ const char *hostname, const char *ip, const char *ttyn, int success, int event)
|
||||
{
|
||||
int audit_fd, rc, saved_errno;
|
||||
|
||||
audit_fd = audit_open();
|
||||
if (audit_fd < 0) {
|
||||
if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
- return 1; /* No audit support in kernel */
|
||||
+ return; /* No audit support in kernel */
|
||||
else
|
||||
- return 0; /* Must prevent login */
|
||||
+ goto fatal_report; /* Must prevent login */
|
||||
}
|
||||
- rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN,
|
||||
+ rc = audit_log_acct_message(audit_fd, event,
|
||||
NULL, "login", username ? username : "(unknown)",
|
||||
username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
saved_errno = errno;
|
||||
close(audit_fd);
|
||||
/*
|
||||
* Do not report error if the error is EPERM and sshd is run as non
|
||||
* root user.
|
||||
*/
|
||||
if ((rc == -EPERM) && (geteuid() != 0))
|
||||
rc = 0;
|
||||
errno = saved_errno;
|
||||
- return (rc >= 0);
|
||||
+ if (rc < 0) {
|
||||
+fatal_report:
|
||||
+ fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
+ }
|
||||
}
|
||||
|
||||
+static void
|
||||
+linux_audit_user_auth(int uid, const char *username,
|
||||
+ const char *hostname, const char *ip, const char *ttyn, int success, int event)
|
||||
+{
|
||||
+ int audit_fd, rc, saved_errno;
|
||||
+ static const char *event_name[] = {
|
||||
+ "maxtries exceeded",
|
||||
+ "root denied",
|
||||
+ "success",
|
||||
+ "none",
|
||||
+ "password",
|
||||
+ "challenge-response",
|
||||
+ "pubkey",
|
||||
+ "hostbased",
|
||||
+ "gssapi",
|
||||
+ "invalid user",
|
||||
+ "nologin",
|
||||
+ "connection closed",
|
||||
+ "connection abandoned",
|
||||
+ "unknown"
|
||||
+ };
|
||||
+
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
+ errno == EAFNOSUPPORT)
|
||||
+ return; /* No audit support in kernel */
|
||||
+ else
|
||||
+ goto fatal_report; /* Must prevent login */
|
||||
+ }
|
||||
+
|
||||
+ if ((event < 0) || (event > SSH_AUDIT_UNKNOWN))
|
||||
+ event = SSH_AUDIT_UNKNOWN;
|
||||
+
|
||||
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH,
|
||||
+ NULL, event_name[event], username ? username : "(unknown)",
|
||||
+ username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
+ saved_errno = errno;
|
||||
+ close(audit_fd);
|
||||
+ /*
|
||||
+ * Do not report error if the error is EPERM and sshd is run as non
|
||||
+ * root user.
|
||||
+ */
|
||||
+ if ((rc == -EPERM) && (geteuid() != 0))
|
||||
+ rc = 0;
|
||||
+ errno = saved_errno;
|
||||
+ if (rc < 0) {
|
||||
+fatal_report:
|
||||
+ fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int user_login_count = 0;
|
||||
+
|
||||
/* Below is the sshd audit API code */
|
||||
|
||||
void
|
||||
audit_connection_from(const char *host, int port)
|
||||
{
|
||||
+ /* not implemented */
|
||||
}
|
||||
- /* not implemented */
|
||||
+
|
||||
+int
|
||||
+audit_run_command(const char *command)
|
||||
+{
|
||||
+ if (!user_login_count++)
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_LOGIN);
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_START);
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
void
|
||||
-audit_run_command(const char *command)
|
||||
+audit_end_command(int handle, const char *command)
|
||||
{
|
||||
- /* not implemented */
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_END);
|
||||
+ if (user_login_count && !--user_login_count)
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_LOGOUT);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_count_session_open(void)
|
||||
+{
|
||||
+ user_login_count++;
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
- if (linux_audit_record_event(li->uid, NULL, li->hostname,
|
||||
- NULL, li->line, 1) == 0)
|
||||
- fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
+ if (!user_login_count++)
|
||||
+ linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1, AUDIT_USER_LOGIN);
|
||||
+ linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1, AUDIT_USER_START);
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
- /* not implemented */
|
||||
+ linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1, AUDIT_USER_END);
|
||||
+ if (user_login_count && !--user_login_count)
|
||||
+ linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1, AUDIT_USER_LOGOUT);
|
||||
}
|
||||
|
||||
void
|
||||
audit_event(ssh_audit_event_t event)
|
||||
{
|
||||
switch(event) {
|
||||
case SSH_AUTH_SUCCESS:
|
||||
- case SSH_CONNECTION_CLOSE:
|
||||
- case SSH_NOLOGIN:
|
||||
- case SSH_LOGIN_EXCEED_MAXTRIES:
|
||||
- case SSH_LOGIN_ROOT_DENIED:
|
||||
+ linux_audit_user_auth(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 1, event);
|
||||
break;
|
||||
|
||||
+ case SSH_NOLOGIN:
|
||||
+ case SSH_LOGIN_ROOT_DENIED:
|
||||
+ linux_audit_user_auth(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 0, event);
|
||||
+ linux_audit_user_logxxx(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
|
||||
+ break;
|
||||
+
|
||||
+ case SSH_LOGIN_EXCEED_MAXTRIES:
|
||||
case SSH_AUTH_FAIL_NONE:
|
||||
case SSH_AUTH_FAIL_PASSWD:
|
||||
case SSH_AUTH_FAIL_KBDINT:
|
||||
case SSH_AUTH_FAIL_PUBKEY:
|
||||
case SSH_AUTH_FAIL_HOSTBASED:
|
||||
case SSH_AUTH_FAIL_GSSAPI:
|
||||
+ linux_audit_user_auth(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 0, event);
|
||||
+ break;
|
||||
+
|
||||
+ case SSH_CONNECTION_CLOSE:
|
||||
+ if (user_login_count) {
|
||||
+ while (user_login_count--)
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_END);
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_LOGOUT);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case SSH_CONNECTION_ABANDON:
|
||||
case SSH_INVALID_USER:
|
||||
- linux_audit_record_event(-1, audit_username(), NULL,
|
||||
- get_remote_ipaddr(), "sshd", 0);
|
||||
+ linux_audit_user_logxxx(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_LINUX_AUDIT */
|
||||
diff --git a/openssh-6.5p1/audit.c b/openssh-6.5p1/audit.c
|
||||
--- a/openssh-6.5p1/audit.c
|
||||
+++ b/openssh-6.5p1/audit.c
|
||||
@@ -135,16 +135,27 @@ audit_connection_from(const char *host,
|
||||
void
|
||||
audit_event(ssh_audit_event_t event)
|
||||
{
|
||||
debug("audit event euid %d user %s event %d (%s)", geteuid(),
|
||||
audit_username(), event, audit_event_lookup(event));
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Called when a child process has called, or will soon call,
|
||||
+ * audit_session_open.
|
||||
+ */
|
||||
+void
|
||||
+audit_count_session_open(void)
|
||||
+{
|
||||
+ debug("audit count session open euid %d user %s", geteuid(),
|
||||
+ audit_username());
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Called when a user session is started. Argument is the tty allocated to
|
||||
* the session, or NULL if no tty was allocated.
|
||||
*
|
||||
* Note that this may be called multiple times if multiple sessions are used
|
||||
* within a single connection.
|
||||
*/
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
@@ -169,18 +180,34 @@ audit_session_close(struct logininfo *li
|
||||
|
||||
debug("audit session close euid %d user %s tty name %s", geteuid(),
|
||||
audit_username(), t);
|
||||
}
|
||||
|
||||
/*
|
||||
* This will be called when a user runs a non-interactive command. Note that
|
||||
* it may be called multiple times for a single connection since SSH2 allows
|
||||
- * multiple sessions within a single connection.
|
||||
+ * multiple sessions within a single connection. Returns a "handle" for
|
||||
+ * audit_end_command.
|
||||
*/
|
||||
-void
|
||||
+int
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
debug("audit run command euid %d user %s command '%.200s'", geteuid(),
|
||||
audit_username(), command);
|
||||
+ return 0;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called when the non-interactive command finishes. Note that
|
||||
+ * it may be called multiple times for a single connection since SSH2 allows
|
||||
+ * multiple sessions within a single connection. "handle" should come from
|
||||
+ * the corresponding audit_run_command.
|
||||
+ */
|
||||
+void
|
||||
+audit_end_command(int handle, const char *command)
|
||||
+{
|
||||
+ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(),
|
||||
+ audit_username(), command);
|
||||
+}
|
||||
+
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/audit.h b/openssh-6.5p1/audit.h
|
||||
--- a/openssh-6.5p1/audit.h
|
||||
+++ b/openssh-6.5p1/audit.h
|
||||
@@ -44,14 +44,16 @@ enum ssh_audit_event_type {
|
||||
SSH_CONNECTION_CLOSE, /* closed after attempting auth or session */
|
||||
SSH_CONNECTION_ABANDON, /* closed without completing auth */
|
||||
SSH_AUDIT_UNKNOWN
|
||||
};
|
||||
typedef enum ssh_audit_event_type ssh_audit_event_t;
|
||||
|
||||
void audit_connection_from(const char *, int);
|
||||
void audit_event(ssh_audit_event_t);
|
||||
+void audit_count_session_open(void);
|
||||
void audit_session_open(struct logininfo *);
|
||||
void audit_session_close(struct logininfo *);
|
||||
-void audit_run_command(const char *);
|
||||
+int audit_run_command(const char *);
|
||||
+void audit_end_command(int, const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff --git a/openssh-6.5p1/monitor.c b/openssh-6.5p1/monitor.c
|
||||
--- a/openssh-6.5p1/monitor.c
|
||||
+++ b/openssh-6.5p1/monitor.c
|
||||
@@ -181,16 +181,17 @@ int mm_answer_gss_setup_ctx(int, Buffer
|
||||
int mm_answer_gss_accept_ctx(int, Buffer *);
|
||||
int mm_answer_gss_userok(int, Buffer *);
|
||||
int mm_answer_gss_checkmic(int, Buffer *);
|
||||
#endif
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
int mm_answer_audit_event(int, Buffer *);
|
||||
int mm_answer_audit_command(int, Buffer *);
|
||||
+int mm_answer_audit_end_command(int, Buffer *);
|
||||
#endif
|
||||
|
||||
static int monitor_read_log(struct monitor *);
|
||||
|
||||
static Authctxt *authctxt;
|
||||
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
|
||||
|
||||
/* local state for key verify */
|
||||
@@ -268,16 +269,17 @@ struct mon_table mon_dispatch_postauth20
|
||||
{MONITOR_REQ_MODULI, 0, mm_answer_moduli},
|
||||
{MONITOR_REQ_SIGN, 0, mm_answer_sign},
|
||||
{MONITOR_REQ_PTY, 0, mm_answer_pty},
|
||||
{MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
|
||||
{MONITOR_REQ_TERM, 0, mm_answer_term},
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
|
||||
+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table mon_dispatch_proto15[] = {
|
||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
|
||||
{MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
|
||||
{MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
|
||||
@@ -310,16 +312,17 @@ struct mon_table mon_dispatch_proto15[]
|
||||
|
||||
struct mon_table mon_dispatch_postauth15[] = {
|
||||
{MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
|
||||
{MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
|
||||
{MONITOR_REQ_TERM, 0, mm_answer_term},
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
|
||||
+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table *mon_dispatch;
|
||||
|
||||
/* Specifies if a certain message is allowed at the moment */
|
||||
|
||||
@@ -1442,16 +1445,22 @@ mm_record_login(Session *s, struct passw
|
||||
static void
|
||||
mm_session_close(Session *s)
|
||||
{
|
||||
debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);
|
||||
if (s->ttyfd != -1) {
|
||||
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
|
||||
session_pty_cleanup2(s);
|
||||
}
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ if (s->command != NULL) {
|
||||
+ debug3("%s: command %d", __func__, s->command_handle);
|
||||
+ session_end_command2(s);
|
||||
+ }
|
||||
+#endif
|
||||
session_unused(s->self);
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_pty(int sock, Buffer *m)
|
||||
{
|
||||
extern struct monitor *pmonitor;
|
||||
Session *s;
|
||||
@@ -1764,21 +1773,53 @@ mm_answer_audit_event(int socket, Buffer
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_audit_command(int socket, Buffer *m)
|
||||
{
|
||||
u_int len;
|
||||
char *cmd;
|
||||
+ Session *s;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
cmd = buffer_get_string(m, &len);
|
||||
/* sanity check command, if so how? */
|
||||
- audit_run_command(cmd);
|
||||
+ s = session_new();
|
||||
+ if (s == NULL)
|
||||
+ fatal("%s: error allocating a session", __func__);
|
||||
+ s->command = cmd;
|
||||
+ s->command_handle = audit_run_command(cmd);
|
||||
+
|
||||
+ buffer_clear(m);
|
||||
+ buffer_put_int(m, s->self);
|
||||
+
|
||||
+ mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m);
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mm_answer_audit_end_command(int socket, Buffer *m)
|
||||
+{
|
||||
+ int handle;
|
||||
+ u_int len;
|
||||
+ char *cmd;
|
||||
+ Session *s;
|
||||
+
|
||||
+ debug3("%s entering", __func__);
|
||||
+ handle = buffer_get_int(m);
|
||||
+ cmd = buffer_get_string(m, &len);
|
||||
+
|
||||
+ s = session_by_id(handle);
|
||||
+ if (s == NULL || s->ttyfd != -1 || s->command == NULL ||
|
||||
+ strcmp(s->command, cmd) != 0)
|
||||
+ fatal("%s: invalid handle", __func__);
|
||||
+ mm_session_close(s);
|
||||
+
|
||||
free(cmd);
|
||||
return (0);
|
||||
}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
|
||||
void
|
||||
monitor_apply_keystate(struct monitor *pmonitor)
|
||||
{
|
||||
diff --git a/openssh-6.5p1/monitor.h b/openssh-6.5p1/monitor.h
|
||||
--- a/openssh-6.5p1/monitor.h
|
||||
+++ b/openssh-6.5p1/monitor.h
|
||||
@@ -64,16 +64,17 @@ enum monitor_reqtype {
|
||||
|
||||
MONITOR_REQ_PAM_START = 100,
|
||||
MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
|
||||
MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105,
|
||||
MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107,
|
||||
MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109,
|
||||
MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
|
||||
MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
|
||||
+ MONITOR_ANS_AUDIT_COMMAND = 114, MONITOR_REQ_AUDIT_END_COMMAND = 115,
|
||||
|
||||
};
|
||||
|
||||
struct mm_master;
|
||||
struct monitor {
|
||||
int m_recvfd;
|
||||
int m_sendfd;
|
||||
int m_log_recvfd;
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.c b/openssh-6.5p1/monitor_wrap.c
|
||||
--- a/openssh-6.5p1/monitor_wrap.c
|
||||
+++ b/openssh-6.5p1/monitor_wrap.c
|
||||
@@ -1186,27 +1186,48 @@ mm_audit_event(ssh_audit_event_t event)
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_int(&m, event);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
-void
|
||||
+int
|
||||
mm_audit_run_command(const char *command)
|
||||
{
|
||||
Buffer m;
|
||||
+ int handle;
|
||||
|
||||
debug3("%s entering command %s", __func__, command);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, command);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, &m);
|
||||
+
|
||||
+ handle = buffer_get_int(&m);
|
||||
+ buffer_free(&m);
|
||||
+
|
||||
+ return (handle);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mm_audit_end_command(int handle, const char *command)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ debug3("%s entering command %s", __func__, command);
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_int(&m, handle);
|
||||
+ buffer_put_cstring(&m, command);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, &m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
|
||||
#ifdef GSSAPI
|
||||
OM_uint32
|
||||
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
|
||||
{
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.h b/openssh-6.5p1/monitor_wrap.h
|
||||
--- a/openssh-6.5p1/monitor_wrap.h
|
||||
+++ b/openssh-6.5p1/monitor_wrap.h
|
||||
@@ -69,17 +69,18 @@ void *mm_sshpam_init_ctx(struct Authctxt
|
||||
int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int mm_sshpam_respond(void *, u_int, char **);
|
||||
void mm_sshpam_free_ctx(void *);
|
||||
#endif
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
#include "audit.h"
|
||||
void mm_audit_event(ssh_audit_event_t);
|
||||
-void mm_audit_run_command(const char *);
|
||||
+int mm_audit_run_command(const char *);
|
||||
+void mm_audit_end_command(int, const char *);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
void mm_terminate(void);
|
||||
int mm_pty_allocate(int *, int *, char *, size_t);
|
||||
void mm_session_pty_cleanup2(struct Session *);
|
||||
|
||||
/* SSHv1 interfaces */
|
||||
diff --git a/openssh-6.5p1/session.c b/openssh-6.5p1/session.c
|
||||
--- a/openssh-6.5p1/session.c
|
||||
+++ b/openssh-6.5p1/session.c
|
||||
@@ -740,16 +740,24 @@ do_exec_pty(Session *s, const char *comm
|
||||
cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
|
||||
#endif
|
||||
|
||||
s->pid = pid;
|
||||
|
||||
/* Parent. Close the slave side of the pseudo tty. */
|
||||
close(ttyfd);
|
||||
|
||||
+#ifndef HAVE_OSF_SIA
|
||||
+ /* do_login in the child did not affect state in this process,
|
||||
+ compensate. From an architectural standpoint, this is extremely
|
||||
+ ugly. */
|
||||
+ if (!(options.use_login && command == NULL))
|
||||
+ audit_count_session_open();
|
||||
+#endif
|
||||
+
|
||||
/* Enter interactive session. */
|
||||
s->ptymaster = ptymaster;
|
||||
packet_set_interactive(1,
|
||||
options.ip_qos_interactive, options.ip_qos_bulk);
|
||||
if (compat20) {
|
||||
session_set_fds(s, ptyfd, fdout, -1, 1, 1);
|
||||
} else {
|
||||
server_loop(pid, ptyfd, fdout, -1);
|
||||
@@ -834,25 +842,29 @@ do_exec(Session *s, const char *command)
|
||||
session_type,
|
||||
tty == NULL ? "" : " on ",
|
||||
tty == NULL ? "" : tty,
|
||||
s->pw->pw_name,
|
||||
get_remote_ipaddr(),
|
||||
get_remote_port());
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
+ if (s->command != NULL || s->command_handle != -1)
|
||||
+ fatal("do_exec: command already set");
|
||||
if (command != NULL)
|
||||
- PRIVSEP(audit_run_command(command));
|
||||
+ s->command = xstrdup(command);
|
||||
else if (s->ttyfd == -1) {
|
||||
char *shell = s->pw->pw_shell;
|
||||
|
||||
if (shell[0] == '\0') /* empty shell means /bin/sh */
|
||||
shell =_PATH_BSHELL;
|
||||
- PRIVSEP(audit_run_command(shell));
|
||||
+ s->command = xstrdup(shell);
|
||||
}
|
||||
+ if (s->command != NULL)
|
||||
+ s->command_handle = PRIVSEP(audit_run_command(s->command));
|
||||
#endif
|
||||
if (s->ttyfd != -1)
|
||||
ret = do_exec_pty(s, command);
|
||||
else
|
||||
ret = do_exec_no_pty(s, command);
|
||||
|
||||
original_command = NULL;
|
||||
|
||||
@@ -1903,16 +1915,17 @@ session_unused(int id)
|
||||
bzero(&sessions[id], sizeof(*sessions));
|
||||
sessions[id].self = id;
|
||||
sessions[id].used = 0;
|
||||
sessions[id].chanid = -1;
|
||||
sessions[id].ptyfd = -1;
|
||||
sessions[id].ttyfd = -1;
|
||||
sessions[id].ptymaster = -1;
|
||||
sessions[id].x11_chanids = NULL;
|
||||
+ sessions[id].command_handle = -1;
|
||||
sessions[id].next_unused = sessions_first_unused;
|
||||
sessions_first_unused = id;
|
||||
}
|
||||
|
||||
Session *
|
||||
session_new(void)
|
||||
{
|
||||
Session *s, *tmp;
|
||||
@@ -1985,16 +1998,29 @@ session_open(Authctxt *authctxt, int cha
|
||||
if (s->pw == NULL || !authctxt->valid)
|
||||
fatal("no user for session %d", s->self);
|
||||
debug("session_open: session %d: link with channel %d", s->self, chanid);
|
||||
s->chanid = chanid;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Session *
|
||||
+session_by_id(int id)
|
||||
+{
|
||||
+ if (id >= 0 && id < sessions_nalloc) {
|
||||
+ Session *s = &sessions[id];
|
||||
+ if (s->used)
|
||||
+ return s;
|
||||
+ }
|
||||
+ debug("session_by_id: unknown id %d", id);
|
||||
+ session_dump();
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+Session *
|
||||
session_by_tty(char *tty)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sessions_nalloc; i++) {
|
||||
Session *s = &sessions[i];
|
||||
if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
|
||||
debug("session_by_tty: session %d tty %s", i, tty);
|
||||
return s;
|
||||
@@ -2501,16 +2527,40 @@ session_exit_message(Session *s, int sta
|
||||
* interested in data we write.
|
||||
* Note that we must not call 'chan_read_failed', since there could
|
||||
* be some more data waiting in the pipe.
|
||||
*/
|
||||
if (c->ostate != CHAN_OUTPUT_CLOSED)
|
||||
chan_write_failed(c);
|
||||
}
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+void
|
||||
+session_end_command2(Session *s)
|
||||
+{
|
||||
+ if (s->command != NULL) {
|
||||
+ audit_end_command(s->command_handle, s->command);
|
||||
+ free(s->command);
|
||||
+ s->command = NULL;
|
||||
+ s->command_handle = -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+session_end_command(Session *s)
|
||||
+{
|
||||
+ if (s->command != NULL) {
|
||||
+ PRIVSEP(audit_end_command(s->command_handle, s->command));
|
||||
+ free(s->command);
|
||||
+ s->command = NULL;
|
||||
+ s->command_handle = -1;
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
void
|
||||
session_close(Session *s)
|
||||
{
|
||||
u_int i;
|
||||
int do_xauth;
|
||||
|
||||
debug("session_close: session %d pid %ld", s->self, (long)s->pid);
|
||||
|
||||
@@ -2541,16 +2591,20 @@ session_close(Session *s)
|
||||
int status;
|
||||
|
||||
waitpid(pid, &status, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->ttyfd != -1)
|
||||
session_pty_cleanup(s);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ if (s->command)
|
||||
+ session_end_command(s);
|
||||
+#endif
|
||||
free(s->term);
|
||||
free(s->display);
|
||||
free(s->x11_chanids);
|
||||
free(s->auth_display);
|
||||
free(s->auth_data);
|
||||
free(s->auth_proto);
|
||||
free(s->subsys);
|
||||
if (s->env != NULL) {
|
||||
@@ -2755,16 +2809,25 @@ session_setup_x11fwd(Session *s)
|
||||
}
|
||||
|
||||
static void
|
||||
do_authenticated2(Authctxt *authctxt)
|
||||
{
|
||||
server_loop2(authctxt);
|
||||
}
|
||||
|
||||
+static void
|
||||
+do_cleanup_one_session(Session *s)
|
||||
+{
|
||||
+ session_pty_cleanup2(s);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ session_end_command2(s);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
void
|
||||
do_cleanup(Authctxt *authctxt)
|
||||
{
|
||||
static int called = 0;
|
||||
|
||||
debug("do_cleanup");
|
||||
|
||||
/* no cleanup if we're in the child for login shell */
|
||||
@@ -2803,10 +2866,10 @@ do_cleanup(Authctxt *authctxt)
|
||||
/* remove agent socket */
|
||||
auth_sock_cleanup_proc(authctxt->pw);
|
||||
|
||||
/*
|
||||
* Cleanup ptys/utmp only if privsep is disabled,
|
||||
* or if running in monitor.
|
||||
*/
|
||||
if (!use_privsep || mm_is_monitor())
|
||||
- session_destroy_all(session_pty_cleanup2);
|
||||
+ session_destroy_all(do_cleanup_one_session);
|
||||
}
|
||||
diff --git a/openssh-6.5p1/session.h b/openssh-6.5p1/session.h
|
||||
--- a/openssh-6.5p1/session.h
|
||||
+++ b/openssh-6.5p1/session.h
|
||||
@@ -56,29 +56,37 @@ struct Session {
|
||||
int *x11_chanids;
|
||||
int is_subsystem;
|
||||
char *subsys;
|
||||
u_int num_env;
|
||||
struct {
|
||||
char *name;
|
||||
char *val;
|
||||
} *env;
|
||||
+
|
||||
+ /* exec */
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ int command_handle;
|
||||
+ char *command;
|
||||
+#endif
|
||||
};
|
||||
|
||||
void do_authenticated(Authctxt *);
|
||||
void do_cleanup(Authctxt *);
|
||||
|
||||
int session_open(Authctxt *, int);
|
||||
void session_unused(int);
|
||||
int session_input_channel_req(Channel *, const char *);
|
||||
void session_close_by_pid(pid_t, int);
|
||||
void session_close_by_channel(int, void *);
|
||||
void session_destroy_all(void (*)(Session *));
|
||||
void session_pty_cleanup2(Session *);
|
||||
+void session_end_command2(Session *);
|
||||
|
||||
Session *session_new(void);
|
||||
+Session *session_by_id(int);
|
||||
Session *session_by_tty(char *);
|
||||
void session_close(Session *);
|
||||
void do_setusercontext(struct passwd *);
|
||||
void child_set_env(char ***envp, u_int *envsizep, const char *name,
|
||||
const char *value);
|
||||
|
||||
#endif
|
||||
diff --git a/openssh-6.5p1/sshd.c b/openssh-6.5p1/sshd.c
|
||||
--- a/openssh-6.5p1/sshd.c
|
||||
+++ b/openssh-6.5p1/sshd.c
|
||||
@@ -2504,13 +2504,14 @@ cleanup_exit(int i)
|
||||
if (kill(pmonitor->m_pid, SIGKILL) != 0 &&
|
||||
errno != ESRCH)
|
||||
error("%s: kill(%d): %s", __func__,
|
||||
pmonitor->m_pid, strerror(errno));
|
||||
}
|
||||
}
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
|
||||
- if (!use_privsep || mm_is_monitor())
|
||||
+ if ((the_authctxt == NULL || !the_authctxt->authenticated) &&
|
||||
+ (!use_privsep || mm_is_monitor()))
|
||||
audit_event(SSH_CONNECTION_ABANDON);
|
||||
#endif
|
||||
_exit(i);
|
||||
}
|
565
openssh-6.5p1-audit3-key_auth_usage.patch
Normal file
565
openssh-6.5p1-audit3-key_auth_usage.patch
Normal file
@ -0,0 +1,565 @@
|
||||
# auditing key-based authentication (both server and client)
|
||||
# based on:
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
# https://bugzilla.mindrot.org/attachment.cgi?id=2012
|
||||
# (replaces: https://bugzilla.mindrot.org/attachment.cgi?id=1975)
|
||||
# by jchadima@redhat.com
|
||||
|
||||
diff --git a/openssh-6.5p1/audit-bsm.c b/openssh-6.5p1/audit-bsm.c
|
||||
--- a/openssh-6.5p1/audit-bsm.c
|
||||
+++ b/openssh-6.5p1/audit-bsm.c
|
||||
@@ -401,16 +401,22 @@ audit_session_open(struct logininfo *li)
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
+int
|
||||
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
void
|
||||
audit_event(ssh_audit_event_t event)
|
||||
{
|
||||
char textbuf[BSM_TEXTBUFSZ];
|
||||
static int logged_in = 0;
|
||||
const char *user = the_authctxt ? the_authctxt->user : "(unknown user)";
|
||||
|
||||
if (cannot_audit(0))
|
||||
diff --git a/openssh-6.5p1/audit-linux.c b/openssh-6.5p1/audit-linux.c
|
||||
--- a/openssh-6.5p1/audit-linux.c
|
||||
+++ b/openssh-6.5p1/audit-linux.c
|
||||
@@ -36,16 +36,18 @@
|
||||
#include "log.h"
|
||||
#include "audit.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
|
||||
+#define AUDIT_LOG_SIZE 128
|
||||
+
|
||||
extern ServerOptions options;
|
||||
extern Authctxt *the_authctxt;
|
||||
extern u_int utmp_len;
|
||||
const char* audit_username(void);
|
||||
|
||||
static void
|
||||
linux_audit_user_logxxx(int uid, const char *username,
|
||||
const char *hostname, const char *ip, const char *ttyn, int success, int event)
|
||||
@@ -125,16 +127,47 @@ linux_audit_user_auth(int uid, const cha
|
||||
rc = 0;
|
||||
errno = saved_errno;
|
||||
if (rc < 0) {
|
||||
fatal_report:
|
||||
fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
+int
|
||||
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, rc, saved_errno;
|
||||
+
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
+ errno == EAFNOSUPPORT)
|
||||
+ return 1; /* No audit support in kernel */
|
||||
+ else
|
||||
+ return 0; /* Must prevent login */
|
||||
+ }
|
||||
+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port());
|
||||
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
||||
+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
|
||||
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
|
||||
+ goto out;
|
||||
+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d",
|
||||
+ type, bits, fp, get_remote_port());
|
||||
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
||||
+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
|
||||
+out:
|
||||
+ saved_errno = errno;
|
||||
+ audit_close(audit_fd);
|
||||
+ errno = saved_errno;
|
||||
+ /* do not report error if the error is EPERM and sshd is run as non root user */
|
||||
+ return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0));
|
||||
+}
|
||||
+
|
||||
static int user_login_count = 0;
|
||||
|
||||
/* Below is the sshd audit API code */
|
||||
|
||||
void
|
||||
audit_connection_from(const char *host, int port)
|
||||
{
|
||||
/* not implemented */
|
||||
diff --git a/openssh-6.5p1/audit.c b/openssh-6.5p1/audit.c
|
||||
--- a/openssh-6.5p1/audit.c
|
||||
+++ b/openssh-6.5p1/audit.c
|
||||
@@ -31,16 +31,17 @@
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
|
||||
#include "audit.h"
|
||||
#include "log.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
+#include "xmalloc.h"
|
||||
|
||||
/*
|
||||
* Care must be taken when using this since it WILL NOT be initialized when
|
||||
* audit_connection_from() is called and MAY NOT be initialized when
|
||||
* audit_event(CONNECTION_ABANDON) is called. Test for NULL before using.
|
||||
*/
|
||||
extern Authctxt *the_authctxt;
|
||||
|
||||
@@ -106,16 +107,32 @@ audit_event_lookup(ssh_audit_event_t ev)
|
||||
};
|
||||
|
||||
for (i = 0; event_lookup[i].event != SSH_AUDIT_UNKNOWN; i++)
|
||||
if (event_lookup[i].event == ev)
|
||||
break;
|
||||
return(event_lookup[i].name);
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_key(int host_user, int *rv, const Key *key)
|
||||
+{
|
||||
+ char *fp;
|
||||
+ const char *crypto_name;
|
||||
+
|
||||
+ fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
||||
+ if (key->type == KEY_RSA1)
|
||||
+ crypto_name = "ssh-rsa1";
|
||||
+ else
|
||||
+ crypto_name = key_ssh_name(key);
|
||||
+ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0)
|
||||
+ *rv = 0;
|
||||
+ free(fp);
|
||||
+}
|
||||
+
|
||||
# ifndef CUSTOM_SSH_AUDIT_EVENTS
|
||||
/*
|
||||
* Null implementations of audit functions.
|
||||
* These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Called after a connection has been accepted but before any authentication
|
||||
@@ -204,10 +221,22 @@ audit_run_command(const char *command)
|
||||
*/
|
||||
void
|
||||
audit_end_command(int handle, const char *command)
|
||||
{
|
||||
debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(),
|
||||
audit_username(), command);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key.
|
||||
+ *
|
||||
+ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key.
|
||||
+ */
|
||||
+int
|
||||
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
||||
+{
|
||||
+ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s, result %d",
|
||||
+ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits,
|
||||
+ fp, rv);
|
||||
+}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/audit.h b/openssh-6.5p1/audit.h
|
||||
--- a/openssh-6.5p1/audit.h
|
||||
+++ b/openssh-6.5p1/audit.h
|
||||
@@ -23,16 +23,17 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SSH_AUDIT_H
|
||||
# define _SSH_AUDIT_H
|
||||
|
||||
#include "loginrec.h"
|
||||
+#include "key.h"
|
||||
|
||||
enum ssh_audit_event_type {
|
||||
SSH_LOGIN_EXCEED_MAXTRIES,
|
||||
SSH_LOGIN_ROOT_DENIED,
|
||||
SSH_AUTH_SUCCESS,
|
||||
SSH_AUTH_FAIL_NONE,
|
||||
SSH_AUTH_FAIL_PASSWD,
|
||||
SSH_AUTH_FAIL_KBDINT, /* keyboard-interactive or challenge-response */
|
||||
@@ -50,10 +51,12 @@ typedef enum ssh_audit_event_type ssh_au
|
||||
void audit_connection_from(const char *, int);
|
||||
void audit_event(ssh_audit_event_t);
|
||||
void audit_count_session_open(void);
|
||||
void audit_session_open(struct logininfo *);
|
||||
void audit_session_close(struct logininfo *);
|
||||
int audit_run_command(const char *);
|
||||
void audit_end_command(int, const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
+int audit_keyusage(int, const char *, unsigned, char *, int);
|
||||
+void audit_key(int, int *, const Key *);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff --git a/openssh-6.5p1/auth-rsa.c b/openssh-6.5p1/auth-rsa.c
|
||||
--- a/openssh-6.5p1/auth-rsa.c
|
||||
+++ b/openssh-6.5p1/auth-rsa.c
|
||||
@@ -87,17 +87,20 @@ auth_rsa_generate_challenge(Key *key)
|
||||
return challenge;
|
||||
}
|
||||
|
||||
int
|
||||
auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
|
||||
{
|
||||
u_char buf[32], mdbuf[16];
|
||||
MD5_CTX md;
|
||||
- int len;
|
||||
+ int len, rv;
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ char *fp;
|
||||
+#endif
|
||||
|
||||
/* don't allow short keys */
|
||||
if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
|
||||
error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits",
|
||||
BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -108,22 +111,28 @@ auth_rsa_verify_response(Key *key, BIGNU
|
||||
memset(buf, 0, 32);
|
||||
BN_bn2bin(challenge, buf + 32 - len);
|
||||
MD5_Init(&md);
|
||||
MD5_Update(&md, buf, 32);
|
||||
MD5_Update(&md, session_id, 16);
|
||||
MD5_Final(mdbuf, &md);
|
||||
|
||||
/* Verify that the response is the original challenge. */
|
||||
- if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
|
||||
- /* Wrong answer. */
|
||||
- return (0);
|
||||
+ rv = timingsafe_bcmp(response, mdbuf, 16) == 0;
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
||||
+ if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) {
|
||||
+ debug("unsuccessful audit");
|
||||
+ rv = 0;
|
||||
}
|
||||
- /* Correct answer. */
|
||||
- return (1);
|
||||
+ free(fp);
|
||||
+#endif
|
||||
+
|
||||
+ return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs the RSA authentication challenge-response dialog with the client,
|
||||
* and returns true (non-zero) if the client gave the correct answer to
|
||||
* our challenge; returns zero if the client gives a wrong answer.
|
||||
*/
|
||||
|
||||
diff --git a/openssh-6.5p1/auth.h b/openssh-6.5p1/auth.h
|
||||
--- a/openssh-6.5p1/auth.h
|
||||
+++ b/openssh-6.5p1/auth.h
|
||||
@@ -182,16 +182,17 @@ int allowed_user(struct passwd *);
|
||||
struct passwd * getpwnamallow(const char *user);
|
||||
|
||||
char *get_challenge(Authctxt *);
|
||||
int verify_response(Authctxt *, const char *);
|
||||
void abandon_challenge_response(Authctxt *);
|
||||
|
||||
char *expand_authorized_keys(const char *, struct passwd *pw);
|
||||
char *authorized_principals_file(struct passwd *);
|
||||
+int user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
FILE *auth_openkeyfile(const char *, struct passwd *, int);
|
||||
FILE *auth_openprincipals(const char *, struct passwd *, int);
|
||||
int auth_key_is_revoked(Key *);
|
||||
|
||||
HostStatus
|
||||
check_key_in_hostfiles(struct passwd *, Key *, const char *,
|
||||
const char *, const char *);
|
||||
@@ -199,16 +200,17 @@ check_key_in_hostfiles(struct passwd *,
|
||||
/* hostkey handling */
|
||||
Key *get_hostkey_by_index(int);
|
||||
Key *get_hostkey_public_by_index(int);
|
||||
Key *get_hostkey_public_by_type(int);
|
||||
Key *get_hostkey_private_by_type(int);
|
||||
int get_hostkey_index(Key *);
|
||||
int ssh1_session_key(BIGNUM *);
|
||||
void sshd_hostkey_sign(Key *, Key *, u_char **, u_int *, u_char *, u_int);
|
||||
+int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
/* debug messages during authentication */
|
||||
void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
||||
void auth_debug_send(void);
|
||||
void auth_debug_reset(void);
|
||||
|
||||
struct passwd *fakepw(void);
|
||||
|
||||
diff --git a/openssh-6.5p1/auth2-hostbased.c b/openssh-6.5p1/auth2-hostbased.c
|
||||
--- a/openssh-6.5p1/auth2-hostbased.c
|
||||
+++ b/openssh-6.5p1/auth2-hostbased.c
|
||||
@@ -124,33 +124,45 @@ userauth_hostbased(Authctxt *authctxt)
|
||||
#endif
|
||||
|
||||
pubkey_auth_info(authctxt, key,
|
||||
"client user \"%.100s\", client host \"%.100s\"", cuser, chost);
|
||||
|
||||
/* test for allowed key and correct signature */
|
||||
authenticated = 0;
|
||||
if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
|
||||
- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
+ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
buffer_len(&b))) == 1)
|
||||
authenticated = 1;
|
||||
|
||||
buffer_free(&b);
|
||||
done:
|
||||
debug2("userauth_hostbased: authenticated %d", authenticated);
|
||||
if (key != NULL)
|
||||
key_free(key);
|
||||
free(pkalg);
|
||||
free(pkblob);
|
||||
free(cuser);
|
||||
free(chost);
|
||||
free(sig);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
+int
|
||||
+hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
|
||||
+{
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = key_verify(key, sig, slen, data, datalen);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_key(0, &rv, key);
|
||||
+#endif
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
/* return 1 if given hostkey is allowed */
|
||||
int
|
||||
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
|
||||
Key *key)
|
||||
{
|
||||
const char *resolvedname, *ipaddr, *lookup, *reason;
|
||||
HostStatus host_status;
|
||||
int len;
|
||||
diff --git a/openssh-6.5p1/auth2-pubkey.c b/openssh-6.5p1/auth2-pubkey.c
|
||||
--- a/openssh-6.5p1/auth2-pubkey.c
|
||||
+++ b/openssh-6.5p1/auth2-pubkey.c
|
||||
@@ -153,17 +153,17 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
#ifdef DEBUG_PK
|
||||
buffer_dump(&b);
|
||||
#endif
|
||||
pubkey_auth_info(authctxt, key, NULL);
|
||||
|
||||
/* test for correct signature */
|
||||
authenticated = 0;
|
||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
|
||||
- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
+ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
buffer_len(&b))) == 1)
|
||||
authenticated = 1;
|
||||
buffer_free(&b);
|
||||
free(sig);
|
||||
} else {
|
||||
debug("test whether pkalg/pkblob are acceptable");
|
||||
packet_check_eom();
|
||||
|
||||
@@ -190,16 +190,28 @@ done:
|
||||
debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
|
||||
if (key != NULL)
|
||||
key_free(key);
|
||||
free(pkalg);
|
||||
free(pkblob);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
+int
|
||||
+user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
|
||||
+{
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = key_verify(key, sig, slen, data, datalen);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_key(1, &rv, key);
|
||||
+#endif
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
void
|
||||
pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
|
||||
{
|
||||
char *fp, *extra;
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
extra = NULL;
|
||||
diff --git a/openssh-6.5p1/monitor.c b/openssh-6.5p1/monitor.c
|
||||
--- a/openssh-6.5p1/monitor.c
|
||||
+++ b/openssh-6.5p1/monitor.c
|
||||
@@ -1362,26 +1362,30 @@ monitor_valid_hostbasedblob(u_char *data
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_keyverify(int sock, Buffer *m)
|
||||
{
|
||||
Key *key;
|
||||
u_char *signature, *data, *blob;
|
||||
u_int signaturelen, datalen, bloblen;
|
||||
+ int type = 0;
|
||||
int verified = 0;
|
||||
int valid_data = 0;
|
||||
|
||||
+ type = buffer_get_int(m);
|
||||
blob = buffer_get_string(m, &bloblen);
|
||||
signature = buffer_get_string(m, &signaturelen);
|
||||
data = buffer_get_string(m, &datalen);
|
||||
|
||||
if (hostbased_cuser == NULL || hostbased_chost == NULL ||
|
||||
!monitor_allowed_key(blob, bloblen))
|
||||
fatal("%s: bad key, not previously allowed", __func__);
|
||||
+ if (type != key_blobtype)
|
||||
+ fatal("%s: bad key type", __func__);
|
||||
|
||||
key = key_from_blob(blob, bloblen);
|
||||
if (key == NULL)
|
||||
fatal("%s: bad public key blob", __func__);
|
||||
|
||||
switch (key_blobtype) {
|
||||
case MM_USERKEY:
|
||||
valid_data = monitor_valid_userblob(data, datalen);
|
||||
@@ -1392,17 +1396,27 @@ mm_answer_keyverify(int sock, Buffer *m)
|
||||
break;
|
||||
default:
|
||||
valid_data = 0;
|
||||
break;
|
||||
}
|
||||
if (!valid_data)
|
||||
fatal("%s: bad signature data blob", __func__);
|
||||
|
||||
- verified = key_verify(key, signature, signaturelen, data, datalen);
|
||||
+ switch (key_blobtype) {
|
||||
+ case MM_USERKEY:
|
||||
+ verified = user_key_verify(key, signature, signaturelen, data, datalen);
|
||||
+ break;
|
||||
+ case MM_HOSTKEY:
|
||||
+ verified = hostbased_key_verify(key, signature, signaturelen, data, datalen);
|
||||
+ break;
|
||||
+ default:
|
||||
+ verified = 0;
|
||||
+ break;
|
||||
+ }
|
||||
debug3("%s: key %p signature %s",
|
||||
__func__, key, (verified == 1) ? "verified" : "unverified");
|
||||
|
||||
key_free(key);
|
||||
free(blob);
|
||||
free(signature);
|
||||
free(data);
|
||||
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.c b/openssh-6.5p1/monitor_wrap.c
|
||||
--- a/openssh-6.5p1/monitor_wrap.c
|
||||
+++ b/openssh-6.5p1/monitor_wrap.c
|
||||
@@ -428,30 +428,31 @@ mm_key_allowed(enum mm_keytype type, cha
|
||||
|
||||
/*
|
||||
* This key verify needs to send the key type along, because the
|
||||
* privileged parent makes the decision if the key is allowed
|
||||
* for authentication.
|
||||
*/
|
||||
|
||||
int
|
||||
-mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
+mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
{
|
||||
Buffer m;
|
||||
u_char *blob;
|
||||
u_int len;
|
||||
int verified = 0;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
/* Convert the key to a blob and the pass it over */
|
||||
if (!key_to_blob(key, &blob, &len))
|
||||
return (0);
|
||||
|
||||
buffer_init(&m);
|
||||
+ buffer_put_int(&m, type);
|
||||
buffer_put_string(&m, blob, len);
|
||||
buffer_put_string(&m, sig, siglen);
|
||||
buffer_put_string(&m, data, datalen);
|
||||
free(blob);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
|
||||
@@ -459,16 +460,29 @@ mm_key_verify(Key *key, u_char *sig, u_i
|
||||
|
||||
verified = buffer_get_int(&m);
|
||||
|
||||
buffer_free(&m);
|
||||
|
||||
return (verified);
|
||||
}
|
||||
|
||||
+int
|
||||
+mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
+{
|
||||
+ return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, datalen);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
+{
|
||||
+ return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Export key state after authentication */
|
||||
Newkeys *
|
||||
mm_newkeys_from_blob(u_char *blob, int blen)
|
||||
{
|
||||
Buffer b;
|
||||
u_int len;
|
||||
Newkeys *newkey = NULL;
|
||||
Enc *enc;
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.h b/openssh-6.5p1/monitor_wrap.h
|
||||
--- a/openssh-6.5p1/monitor_wrap.h
|
||||
+++ b/openssh-6.5p1/monitor_wrap.h
|
||||
@@ -44,17 +44,18 @@ int mm_key_sign(Key *, u_char **, u_int
|
||||
void mm_inform_authserv(char *, char *);
|
||||
struct passwd *mm_getpwnamallow(const char *);
|
||||
char *mm_auth2_read_banner(void);
|
||||
int mm_auth_password(struct Authctxt *, char *);
|
||||
int mm_key_allowed(enum mm_keytype, char *, char *, Key *);
|
||||
int mm_user_key_allowed(struct passwd *, Key *);
|
||||
int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
|
||||
int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
|
||||
-int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
||||
+int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
||||
+int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
||||
int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
|
||||
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
|
||||
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
||||
|
||||
#ifdef GSSAPI
|
||||
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
|
||||
OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
|
||||
gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
|
778
openssh-6.5p1-audit4-kex_results.patch
Normal file
778
openssh-6.5p1-audit4-kex_results.patch
Normal file
@ -0,0 +1,778 @@
|
||||
# key exhange auditing
|
||||
# based on:
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
# https://bugzilla.mindrot.org/attachment.cgi?id=2013
|
||||
# (replaces: https://bugzilla.mindrot.org/attachment.cgi?id=1976)
|
||||
# by jchadima@redhat.com
|
||||
|
||||
diff --git a/openssh-6.5p1/Makefile.in b/openssh-6.5p1/Makefile.in
|
||||
--- a/openssh-6.5p1/Makefile.in
|
||||
+++ b/openssh-6.5p1/Makefile.in
|
||||
@@ -71,17 +71,18 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o
|
||||
readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
|
||||
atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
|
||||
monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
|
||||
kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
|
||||
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
|
||||
jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \
|
||||
kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
|
||||
ssh-ed25519.o digest.o \
|
||||
- sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o
|
||||
+ sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \
|
||||
+ auditstub.o
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
sshconnect.o sshconnect1.o sshconnect2.o mux.o \
|
||||
roaming_common.o roaming_client.o
|
||||
|
||||
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
|
||||
audit.o audit-bsm.o audit-linux.o platform.o \
|
||||
sshpty.o sshlogin.o servconf.o serverloop.o \
|
||||
diff --git a/openssh-6.5p1/audit-bsm.c b/openssh-6.5p1/audit-bsm.c
|
||||
--- a/openssh-6.5p1/audit-bsm.c
|
||||
+++ b/openssh-6.5p1/audit-bsm.c
|
||||
@@ -468,9 +468,21 @@ audit_event(ssh_audit_event_t event)
|
||||
case SSH_AUTH_FAIL_KBDINT:
|
||||
bsm_audit_bad_login("interactive password entry");
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
}
|
||||
}
|
||||
+
|
||||
+void
|
||||
+audit_unsupported_body(int what)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
#endif /* BSM */
|
||||
diff --git a/openssh-6.5p1/audit-linux.c b/openssh-6.5p1/audit-linux.c
|
||||
--- a/openssh-6.5p1/audit-linux.c
|
||||
+++ b/openssh-6.5p1/audit-linux.c
|
||||
@@ -35,16 +35,18 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "audit.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
+#include "packet.h"
|
||||
+#include "cipher.h"
|
||||
|
||||
#define AUDIT_LOG_SIZE 128
|
||||
|
||||
extern ServerOptions options;
|
||||
extern Authctxt *the_authctxt;
|
||||
extern u_int utmp_len;
|
||||
const char* audit_username(void);
|
||||
|
||||
@@ -264,9 +266,65 @@ audit_event(ssh_audit_event_t event)
|
||||
get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_unsupported_body(int what)
|
||||
+{
|
||||
+#ifdef AUDIT_CRYPTO_SESSION
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ const static char *name[] = { "cipher", "mac", "comp" };
|
||||
+ char *s;
|
||||
+ int audit_fd;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ",
|
||||
+ name[what], get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())),
|
||||
+ get_local_port());
|
||||
+ free(s);
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0)
|
||||
+ /* no problem, the next instruction will be fatal() */
|
||||
+ return;
|
||||
+ audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
|
||||
+ buf, NULL, get_remote_ipaddr(), NULL, 0);
|
||||
+ audit_close(audit_fd);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid,
|
||||
+ uid_t uid)
|
||||
+{
|
||||
+#ifdef AUDIT_CRYPTO_SESSION
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, audit_ok;
|
||||
+ const static char *direction[] = { "from-server", "from-client", "both" };
|
||||
+ Cipher *cipher = cipher_by_name(enc);
|
||||
+ char *s;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
|
||||
+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0,
|
||||
+ (intmax_t)pid, (intmax_t)uid,
|
||||
+ get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port());
|
||||
+ free(s);
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
+ errno == EAFNOSUPPORT)
|
||||
+ return; /* No audit support in kernel */
|
||||
+ else
|
||||
+ fatal("cannot open audit"); /* Must prevent login */
|
||||
+ }
|
||||
+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
|
||||
+ buf, NULL, get_remote_ipaddr(), NULL, 1);
|
||||
+ audit_close(audit_fd);
|
||||
+ /* do not abort if the error is EPERM and sshd is run as non root user */
|
||||
+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
|
||||
+ fatal("cannot write into audit"); /* Must prevent login */
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
#endif /* USE_LINUX_AUDIT */
|
||||
diff --git a/openssh-6.5p1/audit.c b/openssh-6.5p1/audit.c
|
||||
--- a/openssh-6.5p1/audit.c
|
||||
+++ b/openssh-6.5p1/audit.c
|
||||
@@ -23,24 +23,27 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
|
||||
#include "audit.h"
|
||||
#include "log.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
+#include "ssh-gss.h"
|
||||
+#include "monitor_wrap.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/*
|
||||
* Care must be taken when using this since it WILL NOT be initialized when
|
||||
* audit_connection_from() is called and MAY NOT be initialized when
|
||||
* audit_event(CONNECTION_ABANDON) is called. Test for NULL before using.
|
||||
*/
|
||||
extern Authctxt *the_authctxt;
|
||||
@@ -123,16 +126,28 @@ audit_key(int host_user, int *rv, const
|
||||
crypto_name = "ssh-rsa1";
|
||||
else
|
||||
crypto_name = key_ssh_name(key);
|
||||
if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0)
|
||||
*rv = 0;
|
||||
free(fp);
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_unsupported(int what)
|
||||
+{
|
||||
+ PRIVSEP(audit_unsupported_body(what));
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_kex(int ctos, char *enc, char *mac, char *comp)
|
||||
+{
|
||||
+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid()));
|
||||
+}
|
||||
+
|
||||
# ifndef CUSTOM_SSH_AUDIT_EVENTS
|
||||
/*
|
||||
* Null implementations of audit functions.
|
||||
* These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Called after a connection has been accepted but before any authentication
|
||||
@@ -233,10 +248,31 @@ audit_end_command(int handle, const char
|
||||
*/
|
||||
int
|
||||
audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
||||
{
|
||||
debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s, result %d",
|
||||
host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits,
|
||||
fp, rv);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called when the protocol negotiation fails.
|
||||
+ */
|
||||
+void
|
||||
+audit_unsupported_body(int what)
|
||||
+{
|
||||
+ debug("audit unsupported protocol euid %d type %d", geteuid(), what);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called on succesfull protocol negotiation.
|
||||
+ */
|
||||
+void
|
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid,
|
||||
+ uid_t uid)
|
||||
+{
|
||||
+ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s from pid %ld uid %u",
|
||||
+ (unsigned)geteuid(), ctos, enc, mac, compress, (long)pid,
|
||||
+ (unsigned)uid);
|
||||
+}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/audit.h b/openssh-6.5p1/audit.h
|
||||
--- a/openssh-6.5p1/audit.h
|
||||
+++ b/openssh-6.5p1/audit.h
|
||||
@@ -53,10 +53,14 @@ void audit_event(ssh_audit_event_t);
|
||||
void audit_count_session_open(void);
|
||||
void audit_session_open(struct logininfo *);
|
||||
void audit_session_close(struct logininfo *);
|
||||
int audit_run_command(const char *);
|
||||
void audit_end_command(int, const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
int audit_keyusage(int, const char *, unsigned, char *, int);
|
||||
void audit_key(int, int *, const Key *);
|
||||
+void audit_unsupported(int);
|
||||
+void audit_kex(int, char *, char *, char *);
|
||||
+void audit_unsupported_body(int);
|
||||
+void audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff --git a/openssh-6.5p1/auditstub.c b/openssh-6.5p1/auditstub.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/openssh-6.5p1/auditstub.c
|
||||
@@ -0,0 +1,39 @@
|
||||
+/* $Id: auditstub.c,v 1.1 jfch Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright 2010 Red Hat, Inc. All rights reserved.
|
||||
+ * Use is subject to license terms.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ * 1. Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ *
|
||||
+ * Red Hat author: Jan F. Chadima <jchadima@redhat.com>
|
||||
+ */
|
||||
+
|
||||
+void
|
||||
+audit_unsupported(int n)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_kex(int ctos, char *enc, char *mac, char *comp)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
diff --git a/openssh-6.5p1/cipher.c b/openssh-6.5p1/cipher.c
|
||||
--- a/openssh-6.5p1/cipher.c
|
||||
+++ b/openssh-6.5p1/cipher.c
|
||||
@@ -52,31 +52,17 @@
|
||||
|
||||
/* compatibility with old or broken OpenSSL versions */
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
extern const EVP_CIPHER *evp_ssh1_bf(void);
|
||||
extern const EVP_CIPHER *evp_ssh1_3des(void);
|
||||
extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
|
||||
|
||||
-struct Cipher {
|
||||
- char *name;
|
||||
- int number; /* for ssh1 only */
|
||||
- u_int block_size;
|
||||
- u_int key_len;
|
||||
- u_int iv_len; /* defaults to block_size */
|
||||
- u_int auth_len;
|
||||
- u_int discard_len;
|
||||
- u_int flags;
|
||||
-#define CFLAG_CBC (1<<0)
|
||||
-#define CFLAG_CHACHAPOLY (1<<1)
|
||||
- const EVP_CIPHER *(*evptype)(void);
|
||||
-};
|
||||
-
|
||||
-static const struct Cipher ciphers[] = {
|
||||
+struct Cipher ciphers[] = {
|
||||
{ "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
|
||||
{ "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
|
||||
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
|
||||
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
|
||||
|
||||
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
|
||||
{ "blowfish-cbc",
|
||||
SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
|
||||
diff --git a/openssh-6.5p1/cipher.h b/openssh-6.5p1/cipher.h
|
||||
--- a/openssh-6.5p1/cipher.h
|
||||
+++ b/openssh-6.5p1/cipher.h
|
||||
@@ -58,17 +58,30 @@
|
||||
#define SSH_CIPHER_MAX 31
|
||||
|
||||
#define CIPHER_ENCRYPT 1
|
||||
#define CIPHER_DECRYPT 0
|
||||
|
||||
typedef struct Cipher Cipher;
|
||||
typedef struct CipherContext CipherContext;
|
||||
|
||||
-struct Cipher;
|
||||
+struct Cipher {
|
||||
+ char *name;
|
||||
+ int number; /* for ssh1 only */
|
||||
+ u_int block_size;
|
||||
+ u_int key_len;
|
||||
+ u_int iv_len; /* defaults to block_size */
|
||||
+ u_int auth_len;
|
||||
+ u_int discard_len;
|
||||
+ u_int flags;
|
||||
+#define CFLAG_CBC (1<<0)
|
||||
+#define CFLAG_CHACHAPOLY (1<<1)
|
||||
+ const EVP_CIPHER *(*evptype)(void);
|
||||
+};
|
||||
+
|
||||
struct CipherContext {
|
||||
int plaintext;
|
||||
int encrypt;
|
||||
EVP_CIPHER_CTX evp;
|
||||
struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
|
||||
const Cipher *cipher;
|
||||
};
|
||||
|
||||
diff --git a/openssh-6.5p1/kex.c b/openssh-6.5p1/kex.c
|
||||
--- a/openssh-6.5p1/kex.c
|
||||
+++ b/openssh-6.5p1/kex.c
|
||||
@@ -45,16 +45,17 @@
|
||||
#include "kex.h"
|
||||
#include "log.h"
|
||||
#include "mac.h"
|
||||
#include "match.h"
|
||||
#include "dispatch.h"
|
||||
#include "monitor.h"
|
||||
#include "roaming.h"
|
||||
#include "digest.h"
|
||||
+#include "audit.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
|
||||
# if defined(HAVE_EVP_SHA256)
|
||||
# define evp_ssh_sha256 EVP_sha256
|
||||
# else
|
||||
extern const EVP_MD *evp_ssh_sha256(void);
|
||||
# endif
|
||||
#endif
|
||||
@@ -346,53 +347,65 @@ kex_kexinit_finish(Kex *kex)
|
||||
fatal("Unsupported key exchange %d", kex->kex_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
choose_enc(Enc *enc, char *client, char *server)
|
||||
{
|
||||
char *name = match_list(client, server, NULL);
|
||||
- if (name == NULL)
|
||||
+ if (name == NULL) {
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_unsupported(0);
|
||||
+#endif
|
||||
fatal("no matching cipher found: client %s server %s",
|
||||
client, server);
|
||||
+ }
|
||||
if ((enc->cipher = cipher_by_name(name)) == NULL)
|
||||
fatal("matching cipher is not supported: %s", name);
|
||||
enc->name = name;
|
||||
enc->enabled = 0;
|
||||
enc->iv = NULL;
|
||||
enc->iv_len = cipher_ivlen(enc->cipher);
|
||||
enc->key = NULL;
|
||||
enc->key_len = cipher_keylen(enc->cipher);
|
||||
enc->block_size = cipher_blocksize(enc->cipher);
|
||||
}
|
||||
|
||||
static void
|
||||
choose_mac(Mac *mac, char *client, char *server)
|
||||
{
|
||||
char *name = match_list(client, server, NULL);
|
||||
- if (name == NULL)
|
||||
+ if (name == NULL) {
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_unsupported(1);
|
||||
+#endif
|
||||
fatal("no matching mac found: client %s server %s",
|
||||
client, server);
|
||||
+ }
|
||||
if (mac_setup(mac, name) < 0)
|
||||
fatal("unsupported mac %s", name);
|
||||
/* truncate the key */
|
||||
if (datafellows & SSH_BUG_HMAC)
|
||||
mac->key_len = 16;
|
||||
mac->name = name;
|
||||
mac->key = NULL;
|
||||
mac->enabled = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
choose_comp(Comp *comp, char *client, char *server)
|
||||
{
|
||||
char *name = match_list(client, server, NULL);
|
||||
- if (name == NULL)
|
||||
+ if (name == NULL) {
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_unsupported(2);
|
||||
+#endif
|
||||
fatal("no matching comp found: client %s server %s", client, server);
|
||||
+ }
|
||||
if (strcmp(name, "zlib@openssh.com") == 0) {
|
||||
comp->type = COMP_DELAYED;
|
||||
} else if (strcmp(name, "zlib") == 0) {
|
||||
comp->type = COMP_ZLIB;
|
||||
} else if (strcmp(name, "none") == 0) {
|
||||
comp->type = COMP_NONE;
|
||||
} else {
|
||||
fatal("unsupported comp %s", name);
|
||||
@@ -497,16 +510,19 @@ kex_choose_conf(Kex *kex)
|
||||
if (authlen == 0)
|
||||
choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]);
|
||||
choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
|
||||
debug("kex: %s %s %s %s",
|
||||
ctos ? "client->server" : "server->client",
|
||||
newkeys->enc.name,
|
||||
authlen == 0 ? newkeys->mac.name : "<implicit>",
|
||||
newkeys->comp.name);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_kex(ctos, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name);
|
||||
+#endif
|
||||
}
|
||||
choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
|
||||
choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
||||
sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
|
||||
need = dh_need = 0;
|
||||
for (mode = 0; mode < MODE_MAX; mode++) {
|
||||
newkeys = kex->newkeys[mode];
|
||||
need = MAX(need, newkeys->enc.key_len);
|
||||
diff --git a/openssh-6.5p1/monitor.c b/openssh-6.5p1/monitor.c
|
||||
--- a/openssh-6.5p1/monitor.c
|
||||
+++ b/openssh-6.5p1/monitor.c
|
||||
@@ -93,16 +93,17 @@
|
||||
#include "monitor_wrap.h"
|
||||
#include "monitor_fdpass.h"
|
||||
#include "misc.h"
|
||||
#include "compat.h"
|
||||
#include "ssh2.h"
|
||||
#include "jpake.h"
|
||||
#include "roaming.h"
|
||||
#include "authfd.h"
|
||||
+#include "audit.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
static Gssctxt *gsscontext = NULL;
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
extern ServerOptions options;
|
||||
extern u_int utmp_len;
|
||||
@@ -182,16 +183,18 @@ int mm_answer_gss_accept_ctx(int, Buffer
|
||||
int mm_answer_gss_userok(int, Buffer *);
|
||||
int mm_answer_gss_checkmic(int, Buffer *);
|
||||
#endif
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
int mm_answer_audit_event(int, Buffer *);
|
||||
int mm_answer_audit_command(int, Buffer *);
|
||||
int mm_answer_audit_end_command(int, Buffer *);
|
||||
+int mm_answer_audit_unsupported_body(int, Buffer *);
|
||||
+int mm_answer_audit_kex_body(int, Buffer *);
|
||||
#endif
|
||||
|
||||
static int monitor_read_log(struct monitor *);
|
||||
|
||||
static Authctxt *authctxt;
|
||||
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
|
||||
|
||||
/* local state for key verify */
|
||||
@@ -233,16 +236,18 @@ struct mon_table mon_dispatch_proto20[]
|
||||
{MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
|
||||
{MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
|
||||
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
|
||||
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
{MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
|
||||
{MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
|
||||
@@ -270,16 +275,18 @@ struct mon_table mon_dispatch_postauth20
|
||||
{MONITOR_REQ_SIGN, 0, mm_answer_sign},
|
||||
{MONITOR_REQ_PTY, 0, mm_answer_pty},
|
||||
{MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
|
||||
{MONITOR_REQ_TERM, 0, mm_answer_term},
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
|
||||
{MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table mon_dispatch_proto15[] = {
|
||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
|
||||
{MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
|
||||
{MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
|
||||
@@ -301,28 +308,32 @@ struct mon_table mon_dispatch_proto15[]
|
||||
{MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
|
||||
{MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
|
||||
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table mon_dispatch_postauth15[] = {
|
||||
{MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
|
||||
{MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
|
||||
{MONITOR_REQ_TERM, 0, mm_answer_term},
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
|
||||
{MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
+ {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
+ {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table *mon_dispatch;
|
||||
|
||||
/* Specifies if a certain message is allowed at the moment */
|
||||
|
||||
@@ -2411,8 +2422,52 @@ mm_answer_jpake_check_confirm(int sock,
|
||||
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1);
|
||||
|
||||
auth_method = "jpake-01@openssh.com";
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
#endif /* JPAKE */
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+int
|
||||
+mm_answer_audit_unsupported_body(int sock, Buffer *m)
|
||||
+{
|
||||
+ int what;
|
||||
+
|
||||
+ what = buffer_get_int(m);
|
||||
+
|
||||
+ audit_unsupported_body(what);
|
||||
+
|
||||
+ buffer_clear(m);
|
||||
+
|
||||
+ mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mm_answer_audit_kex_body(int sock, Buffer *m)
|
||||
+{
|
||||
+ int ctos, len;
|
||||
+ char *cipher, *mac, *compress;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ ctos = buffer_get_int(m);
|
||||
+ cipher = buffer_get_string(m, &len);
|
||||
+ mac = buffer_get_string(m, &len);
|
||||
+ compress = buffer_get_string(m, &len);
|
||||
+ pid = buffer_get_int64(m);
|
||||
+ uid = buffer_get_int64(m);
|
||||
+
|
||||
+ audit_kex_body(ctos, cipher, mac, compress, pid, uid);
|
||||
+
|
||||
+ free(cipher);
|
||||
+ free(mac);
|
||||
+ free(compress);
|
||||
+ buffer_clear(m);
|
||||
+
|
||||
+ mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/monitor.h b/openssh-6.5p1/monitor.h
|
||||
--- a/openssh-6.5p1/monitor.h
|
||||
+++ b/openssh-6.5p1/monitor.h
|
||||
@@ -65,16 +65,18 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_PAM_START = 100,
|
||||
MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
|
||||
MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105,
|
||||
MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107,
|
||||
MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109,
|
||||
MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
|
||||
MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
|
||||
MONITOR_ANS_AUDIT_COMMAND = 114, MONITOR_REQ_AUDIT_END_COMMAND = 115,
|
||||
+ MONITOR_REQ_AUDIT_UNSUPPORTED = 116, MONITOR_ANS_AUDIT_UNSUPPORTED = 117,
|
||||
+ MONITOR_REQ_AUDIT_KEX = 118, MONITOR_ANS_AUDIT_KEX = 119,
|
||||
|
||||
};
|
||||
|
||||
struct mm_master;
|
||||
struct monitor {
|
||||
int m_recvfd;
|
||||
int m_sendfd;
|
||||
int m_log_recvfd;
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.c b/openssh-6.5p1/monitor_wrap.c
|
||||
--- a/openssh-6.5p1/monitor_wrap.c
|
||||
+++ b/openssh-6.5p1/monitor_wrap.c
|
||||
@@ -1483,8 +1483,46 @@ mm_jpake_check_confirm(const BIGNUM *k,
|
||||
|
||||
success = buffer_get_int(&m);
|
||||
buffer_free(&m);
|
||||
|
||||
debug3("%s: success = %d", __func__, success);
|
||||
return success;
|
||||
}
|
||||
#endif /* JPAKE */
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+void
|
||||
+mm_audit_unsupported_body(int what)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_int(&m, what);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED,
|
||||
+ &m);
|
||||
+
|
||||
+ buffer_free(&m);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid,
|
||||
+ uid_t uid)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_int(&m, ctos);
|
||||
+ buffer_put_cstring(&m, cipher);
|
||||
+ buffer_put_cstring(&m, mac);
|
||||
+ buffer_put_cstring(&m, compress);
|
||||
+ buffer_put_int64(&m, pid);
|
||||
+ buffer_put_int64(&m, uid);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX,
|
||||
+ &m);
|
||||
+
|
||||
+ buffer_free(&m);
|
||||
+}
|
||||
+#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.h b/openssh-6.5p1/monitor_wrap.h
|
||||
--- a/openssh-6.5p1/monitor_wrap.h
|
||||
+++ b/openssh-6.5p1/monitor_wrap.h
|
||||
@@ -72,16 +72,18 @@ int mm_sshpam_respond(void *, u_int, cha
|
||||
void mm_sshpam_free_ctx(void *);
|
||||
#endif
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
#include "audit.h"
|
||||
void mm_audit_event(ssh_audit_event_t);
|
||||
int mm_audit_run_command(const char *);
|
||||
void mm_audit_end_command(int, const char *);
|
||||
+void mm_audit_unsupported_body(int);
|
||||
+void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
void mm_terminate(void);
|
||||
int mm_pty_allocate(int *, int *, char *, size_t);
|
||||
void mm_session_pty_cleanup2(struct Session *);
|
||||
|
||||
/* SSHv1 interfaces */
|
||||
diff --git a/openssh-6.5p1/sshd.c b/openssh-6.5p1/sshd.c
|
||||
--- a/openssh-6.5p1/sshd.c
|
||||
+++ b/openssh-6.5p1/sshd.c
|
||||
@@ -114,16 +114,17 @@
|
||||
#include "session.h"
|
||||
#include "monitor_mm.h"
|
||||
#include "monitor.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "roaming.h"
|
||||
+#include "audit.h"
|
||||
#include "ssh-sandbox.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef LIBWRAP
|
||||
#include <tcpd.h>
|
||||
#include <syslog.h>
|
||||
int allow_severity;
|
||||
int deny_severity;
|
||||
@@ -2312,16 +2313,20 @@ do_ssh1_kex(void)
|
||||
packet_disconnect("Warning: client selects unsupported cipher.");
|
||||
|
||||
/* Get check bytes from the packet. These must match those we
|
||||
sent earlier with the public key packet. */
|
||||
for (i = 0; i < 8; i++)
|
||||
if (cookie[i] != packet_get_char())
|
||||
packet_disconnect("IP Spoofing check bytes do not match.");
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_kex(2, cipher_name(cipher_type), "crc", "none");
|
||||
+#endif
|
||||
+
|
||||
debug("Encryption type: %.200s", cipher_name(cipher_type));
|
||||
|
||||
/* Get the encrypted integer. */
|
||||
if ((session_key_int = BN_new()) == NULL)
|
||||
fatal("do_ssh1_kex: BN_new failed");
|
||||
packet_get_bignum(session_key_int);
|
||||
|
||||
protocol_flags = packet_get_int();
|
981
openssh-6.5p1-audit5-session_key_destruction.patch
Normal file
981
openssh-6.5p1-audit5-session_key_destruction.patch
Normal file
@ -0,0 +1,981 @@
|
||||
# session key destruction and auditing
|
||||
# based on:
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
# https://bugzilla.mindrot.org/attachment.cgi?id=2014
|
||||
# by jchadima@redhat.com
|
||||
|
||||
diff --git a/openssh-6.5p1/audit-bsm.c b/openssh-6.5p1/audit-bsm.c
|
||||
--- a/openssh-6.5p1/audit-bsm.c
|
||||
+++ b/openssh-6.5p1/audit-bsm.c
|
||||
@@ -480,9 +480,15 @@ audit_unsupported_body(int what)
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, uid_t uid)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
+
|
||||
+void
|
||||
+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
#endif /* BSM */
|
||||
diff --git a/openssh-6.5p1/audit-linux.c b/openssh-6.5p1/audit-linux.c
|
||||
--- a/openssh-6.5p1/audit-linux.c
|
||||
+++ b/openssh-6.5p1/audit-linux.c
|
||||
@@ -289,24 +289,25 @@ audit_unsupported_body(int what)
|
||||
/* no problem, the next instruction will be fatal() */
|
||||
return;
|
||||
audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
|
||||
buf, NULL, get_remote_ipaddr(), NULL, 0);
|
||||
audit_close(audit_fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
+const static char *direction[] = { "from-server", "from-client", "both" };
|
||||
+
|
||||
void
|
||||
audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid,
|
||||
uid_t uid)
|
||||
{
|
||||
#ifdef AUDIT_CRYPTO_SESSION
|
||||
char buf[AUDIT_LOG_SIZE];
|
||||
int audit_fd, audit_ok;
|
||||
- const static char *direction[] = { "from-server", "from-client", "both" };
|
||||
Cipher *cipher = cipher_by_name(enc);
|
||||
char *s;
|
||||
|
||||
snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
|
||||
direction[ctos], enc, cipher ? 8 * cipher->key_len : 0,
|
||||
(intmax_t)pid, (intmax_t)uid,
|
||||
get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port());
|
||||
free(s);
|
||||
@@ -322,9 +323,37 @@ audit_kex_body(int ctos, char *enc, char
|
||||
buf, NULL, get_remote_ipaddr(), NULL, 1);
|
||||
audit_close(audit_fd);
|
||||
/* do not abort if the error is EPERM and sshd is run as non root user */
|
||||
if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
|
||||
fatal("cannot write into audit"); /* Must prevent login */
|
||||
#endif
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, audit_ok;
|
||||
+ char *s;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
|
||||
+ direction[ctos], (intmax_t)pid, (intmax_t)uid,
|
||||
+ get_remote_port(),
|
||||
+ (s = get_local_ipaddr(packet_get_connection_in())),
|
||||
+ get_local_port());
|
||||
+ free(s);
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno != EINVAL && errno != EPROTONOSUPPORT &&
|
||||
+ errno != EAFNOSUPPORT)
|
||||
+ error("cannot open audit");
|
||||
+ return;
|
||||
+ }
|
||||
+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
|
||||
+ buf, NULL, get_remote_ipaddr(), NULL, 1);
|
||||
+ audit_close(audit_fd);
|
||||
+ /* do not abort if the error is EPERM and sshd is run as non root user */
|
||||
+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
|
||||
+ error("cannot write into audit");
|
||||
+}
|
||||
+
|
||||
#endif /* USE_LINUX_AUDIT */
|
||||
diff --git a/openssh-6.5p1/audit.c b/openssh-6.5p1/audit.c
|
||||
--- a/openssh-6.5p1/audit.c
|
||||
+++ b/openssh-6.5p1/audit.c
|
||||
@@ -138,16 +138,22 @@ audit_unsupported(int what)
|
||||
}
|
||||
|
||||
void
|
||||
audit_kex(int ctos, char *enc, char *mac, char *comp)
|
||||
{
|
||||
PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid()));
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_session_key_free(int ctos)
|
||||
+{
|
||||
+ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid()));
|
||||
+}
|
||||
+
|
||||
# ifndef CUSTOM_SSH_AUDIT_EVENTS
|
||||
/*
|
||||
* Null implementations of audit functions.
|
||||
* These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Called after a connection has been accepted but before any authentication
|
||||
@@ -269,10 +275,20 @@ audit_unsupported_body(int what)
|
||||
void
|
||||
audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid,
|
||||
uid_t uid)
|
||||
{
|
||||
debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s from pid %ld uid %u",
|
||||
(unsigned)geteuid(), ctos, enc, mac, compress, (long)pid,
|
||||
(unsigned)uid);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called on succesfull session key discard
|
||||
+ */
|
||||
+void
|
||||
+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ debug("audit session key discard euid %u direction %d from pid %ld uid %u",
|
||||
+ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid);
|
||||
+}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/audit.h b/openssh-6.5p1/audit.h
|
||||
--- a/openssh-6.5p1/audit.h
|
||||
+++ b/openssh-6.5p1/audit.h
|
||||
@@ -57,10 +57,12 @@ int audit_run_command(const char *);
|
||||
void audit_end_command(int, const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
int audit_keyusage(int, const char *, unsigned, char *, int);
|
||||
void audit_key(int, int *, const Key *);
|
||||
void audit_unsupported(int);
|
||||
void audit_kex(int, char *, char *, char *);
|
||||
void audit_unsupported_body(int);
|
||||
void audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
|
||||
+void audit_session_key_free(int ctos);
|
||||
+void audit_session_key_free_body(int ctos, pid_t, uid_t);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff --git a/openssh-6.5p1/auditstub.c b/openssh-6.5p1/auditstub.c
|
||||
--- a/openssh-6.5p1/auditstub.c
|
||||
+++ b/openssh-6.5p1/auditstub.c
|
||||
@@ -22,18 +22,29 @@
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Red Hat author: Jan F. Chadima <jchadima@redhat.com>
|
||||
*/
|
||||
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
void
|
||||
audit_unsupported(int n)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
audit_kex(int ctos, char *enc, char *mac, char *comp)
|
||||
{
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_session_key_free(int ctos)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+}
|
||||
diff --git a/openssh-6.5p1/kex.c b/openssh-6.5p1/kex.c
|
||||
--- a/openssh-6.5p1/kex.c
|
||||
+++ b/openssh-6.5p1/kex.c
|
||||
@@ -698,8 +698,39 @@ dump_digest(char *msg, u_char *digest, i
|
||||
if (i%32 == 31)
|
||||
fprintf(stderr, "\n");
|
||||
else if (i%8 == 7)
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+static void
|
||||
+enc_destroy(Enc *enc)
|
||||
+{
|
||||
+ if (enc == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ if (enc->key) {
|
||||
+ memset(enc->key, 0, enc->key_len);
|
||||
+ free(enc->key);
|
||||
+ }
|
||||
+
|
||||
+ if (enc->iv) {
|
||||
+ memset(enc->iv, 0, enc->block_size);
|
||||
+ free(enc->iv);
|
||||
+ }
|
||||
+
|
||||
+ memset(enc, 0, sizeof(*enc));
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+newkeys_destroy(Newkeys *newkeys)
|
||||
+{
|
||||
+ if (newkeys == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ enc_destroy(&newkeys->enc);
|
||||
+ mac_destroy(&newkeys->mac);
|
||||
+ memset(&newkeys->comp, 0, sizeof(newkeys->comp));
|
||||
+}
|
||||
+
|
||||
diff --git a/openssh-6.5p1/kex.h b/openssh-6.5p1/kex.h
|
||||
--- a/openssh-6.5p1/kex.h
|
||||
+++ b/openssh-6.5p1/kex.h
|
||||
@@ -163,16 +163,18 @@ void kexdh_client(Kex *);
|
||||
void kexdh_server(Kex *);
|
||||
void kexgex_client(Kex *);
|
||||
void kexgex_server(Kex *);
|
||||
void kexecdh_client(Kex *);
|
||||
void kexecdh_server(Kex *);
|
||||
void kexc25519_client(Kex *);
|
||||
void kexc25519_server(Kex *);
|
||||
|
||||
+void newkeys_destroy(Newkeys *newkeys);
|
||||
+
|
||||
void
|
||||
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
|
||||
BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
|
||||
void
|
||||
kexgex_hash(int, char *, char *, char *, int, char *,
|
||||
int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, u_char **, u_int *);
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
diff --git a/openssh-6.5p1/mac.c b/openssh-6.5p1/mac.c
|
||||
--- a/openssh-6.5p1/mac.c
|
||||
+++ b/openssh-6.5p1/mac.c
|
||||
@@ -219,16 +219,30 @@ mac_clear(Mac *mac)
|
||||
if (mac->umac_ctx != NULL)
|
||||
umac128_delete(mac->umac_ctx);
|
||||
} else if (mac->evp_md != NULL)
|
||||
HMAC_cleanup(&mac->evp_ctx);
|
||||
mac->evp_md = NULL;
|
||||
mac->umac_ctx = NULL;
|
||||
}
|
||||
|
||||
+void
|
||||
+mac_destroy(Mac *mac)
|
||||
+{
|
||||
+ if (mac == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ if (mac->key) {
|
||||
+ memset(mac->key, 0, mac->key_len);
|
||||
+ free(mac->key);
|
||||
+ }
|
||||
+
|
||||
+ memset(mac, 0, sizeof(*mac));
|
||||
+}
|
||||
+
|
||||
/* XXX copied from ciphers_valid */
|
||||
#define MAC_SEP ","
|
||||
int
|
||||
mac_valid(const char *names)
|
||||
{
|
||||
char *maclist, *cp, *p;
|
||||
|
||||
if (names == NULL || strcmp(names, "") == 0)
|
||||
diff --git a/openssh-6.5p1/mac.h b/openssh-6.5p1/mac.h
|
||||
--- a/openssh-6.5p1/mac.h
|
||||
+++ b/openssh-6.5p1/mac.h
|
||||
@@ -24,8 +24,9 @@
|
||||
*/
|
||||
|
||||
int mac_valid(const char *);
|
||||
char *mac_alg_list(char);
|
||||
int mac_setup(Mac *, char *);
|
||||
int mac_init(Mac *);
|
||||
u_char *mac_compute(Mac *, u_int32_t, u_char *, int);
|
||||
void mac_clear(Mac *);
|
||||
+void mac_destroy(Mac *);
|
||||
diff --git a/openssh-6.5p1/monitor.c b/openssh-6.5p1/monitor.c
|
||||
--- a/openssh-6.5p1/monitor.c
|
||||
+++ b/openssh-6.5p1/monitor.c
|
||||
@@ -185,16 +185,17 @@ int mm_answer_gss_checkmic(int, Buffer *
|
||||
#endif
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
int mm_answer_audit_event(int, Buffer *);
|
||||
int mm_answer_audit_command(int, Buffer *);
|
||||
int mm_answer_audit_end_command(int, Buffer *);
|
||||
int mm_answer_audit_unsupported_body(int, Buffer *);
|
||||
int mm_answer_audit_kex_body(int, Buffer *);
|
||||
+int mm_answer_audit_session_key_free_body(int, Buffer *);
|
||||
#endif
|
||||
|
||||
static int monitor_read_log(struct monitor *);
|
||||
|
||||
static Authctxt *authctxt;
|
||||
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
|
||||
|
||||
/* local state for key verify */
|
||||
@@ -238,16 +239,17 @@ struct mon_table mon_dispatch_proto20[]
|
||||
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
{MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
|
||||
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
{MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
|
||||
{MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
|
||||
@@ -277,16 +279,17 @@ struct mon_table mon_dispatch_postauth20
|
||||
{MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
|
||||
{MONITOR_REQ_TERM, 0, mm_answer_term},
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
|
||||
{MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
{MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
{MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table mon_dispatch_proto15[] = {
|
||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
|
||||
{MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
|
||||
{MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
|
||||
@@ -310,30 +313,32 @@ struct mon_table mon_dispatch_proto15[]
|
||||
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
{MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table mon_dispatch_postauth15[] = {
|
||||
{MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
|
||||
{MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
|
||||
{MONITOR_REQ_TERM, 0, mm_answer_term},
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
|
||||
{MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
{MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
{MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table *mon_dispatch;
|
||||
|
||||
/* Specifies if a certain message is allowed at the moment */
|
||||
|
||||
@@ -1971,21 +1976,23 @@ mm_get_keystate(struct monitor *pmonitor
|
||||
goto skip;
|
||||
} else {
|
||||
/* Get the Kex for rekeying */
|
||||
*pmonitor->m_pkex = mm_get_kex(&m);
|
||||
}
|
||||
|
||||
blob = buffer_get_string(&m, &bloblen);
|
||||
current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
|
||||
+ memset(blob, 0, bloblen);
|
||||
free(blob);
|
||||
|
||||
debug3("%s: Waiting for second key", __func__);
|
||||
blob = buffer_get_string(&m, &bloblen);
|
||||
current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
|
||||
+ memset(blob, 0, bloblen);
|
||||
free(blob);
|
||||
|
||||
/* Now get sequence numbers for the packets */
|
||||
seqnr = buffer_get_int(&m);
|
||||
blocks = buffer_get_int64(&m);
|
||||
packets = buffer_get_int(&m);
|
||||
bytes = buffer_get_int64(&m);
|
||||
packet_set_state(MODE_OUT, seqnr, blocks, packets, bytes);
|
||||
@@ -2021,16 +2028,31 @@ mm_get_keystate(struct monitor *pmonitor
|
||||
|
||||
/* Roaming */
|
||||
if (compat20) {
|
||||
child_state.sent_bytes = buffer_get_int64(&m);
|
||||
child_state.recv_bytes = buffer_get_int64(&m);
|
||||
}
|
||||
|
||||
buffer_free(&m);
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ if (compat20) {
|
||||
+ buffer_init(&m);
|
||||
+ mm_request_receive_expect(pmonitor->m_sendfd,
|
||||
+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
|
||||
+ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m);
|
||||
+ buffer_free(&m);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* Drain any buffered messages from the child */
|
||||
+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
|
||||
+ ;
|
||||
+
|
||||
}
|
||||
|
||||
|
||||
/* Allocation functions for zlib */
|
||||
void *
|
||||
mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
|
||||
{
|
||||
size_t len = (size_t) size * ncount;
|
||||
@@ -2465,9 +2487,27 @@ mm_answer_audit_kex_body(int sock, Buffe
|
||||
free(mac);
|
||||
free(compress);
|
||||
buffer_clear(m);
|
||||
|
||||
mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int
|
||||
+mm_answer_audit_session_key_free_body(int sock, Buffer *m)
|
||||
+{
|
||||
+ int ctos;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ ctos = buffer_get_int(m);
|
||||
+ pid = buffer_get_int64(m);
|
||||
+ uid = buffer_get_int64(m);
|
||||
+
|
||||
+ audit_session_key_free_body(ctos, pid, uid);
|
||||
+
|
||||
+ buffer_clear(m);
|
||||
+
|
||||
+ mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m);
|
||||
+ return 0;
|
||||
+}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/monitor.h b/openssh-6.5p1/monitor.h
|
||||
--- a/openssh-6.5p1/monitor.h
|
||||
+++ b/openssh-6.5p1/monitor.h
|
||||
@@ -67,16 +67,17 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105,
|
||||
MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107,
|
||||
MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109,
|
||||
MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
|
||||
MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
|
||||
MONITOR_ANS_AUDIT_COMMAND = 114, MONITOR_REQ_AUDIT_END_COMMAND = 115,
|
||||
MONITOR_REQ_AUDIT_UNSUPPORTED = 116, MONITOR_ANS_AUDIT_UNSUPPORTED = 117,
|
||||
MONITOR_REQ_AUDIT_KEX = 118, MONITOR_ANS_AUDIT_KEX = 119,
|
||||
+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 120, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 121,
|
||||
|
||||
};
|
||||
|
||||
struct mm_master;
|
||||
struct monitor {
|
||||
int m_recvfd;
|
||||
int m_sendfd;
|
||||
int m_log_recvfd;
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.c b/openssh-6.5p1/monitor_wrap.c
|
||||
--- a/openssh-6.5p1/monitor_wrap.c
|
||||
+++ b/openssh-6.5p1/monitor_wrap.c
|
||||
@@ -651,22 +651,24 @@ mm_send_keystate(struct monitor *monitor
|
||||
__func__, packet_get_newkeys(MODE_OUT),
|
||||
packet_get_newkeys(MODE_IN));
|
||||
|
||||
/* Keys from Kex */
|
||||
if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
|
||||
fatal("%s: conversion of newkeys failed", __func__);
|
||||
|
||||
buffer_put_string(&m, blob, bloblen);
|
||||
+ memset(blob, 0, bloblen);
|
||||
free(blob);
|
||||
|
||||
if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
|
||||
fatal("%s: conversion of newkeys failed", __func__);
|
||||
|
||||
buffer_put_string(&m, blob, bloblen);
|
||||
+ memset(blob, 0, bloblen);
|
||||
free(blob);
|
||||
|
||||
packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes);
|
||||
buffer_put_int(&m, seqnr);
|
||||
buffer_put_int64(&m, blocks);
|
||||
buffer_put_int(&m, packets);
|
||||
buffer_put_int64(&m, bytes);
|
||||
packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes);
|
||||
@@ -1520,9 +1522,24 @@ mm_audit_kex_body(int ctos, char *cipher
|
||||
buffer_put_int64(&m, uid);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX,
|
||||
&m);
|
||||
|
||||
buffer_free(&m);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_int(&m, ctos);
|
||||
+ buffer_put_int64(&m, pid);
|
||||
+ buffer_put_int64(&m, uid);
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE,
|
||||
+ &m);
|
||||
+ buffer_free(&m);
|
||||
+}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.h b/openssh-6.5p1/monitor_wrap.h
|
||||
--- a/openssh-6.5p1/monitor_wrap.h
|
||||
+++ b/openssh-6.5p1/monitor_wrap.h
|
||||
@@ -74,16 +74,17 @@ void mm_sshpam_free_ctx(void *);
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
#include "audit.h"
|
||||
void mm_audit_event(ssh_audit_event_t);
|
||||
int mm_audit_run_command(const char *);
|
||||
void mm_audit_end_command(int, const char *);
|
||||
void mm_audit_unsupported_body(int);
|
||||
void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
|
||||
+void mm_audit_session_key_free_body(int, pid_t, uid_t);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
void mm_terminate(void);
|
||||
int mm_pty_allocate(int *, int *, char *, size_t);
|
||||
void mm_session_pty_cleanup2(struct Session *);
|
||||
|
||||
/* SSHv1 interfaces */
|
||||
diff --git a/openssh-6.5p1/packet.c b/openssh-6.5p1/packet.c
|
||||
--- a/openssh-6.5p1/packet.c
|
||||
+++ b/openssh-6.5p1/packet.c
|
||||
@@ -56,16 +56,17 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
+#include "audit.h"
|
||||
#include "buffer.h"
|
||||
#include "packet.h"
|
||||
#include "crc32.h"
|
||||
#include "compress.h"
|
||||
#include "deattack.h"
|
||||
#include "channels.h"
|
||||
#include "compat.h"
|
||||
#include "ssh1.h"
|
||||
@@ -469,41 +470,51 @@ packet_get_connection_in(void)
|
||||
/* Returns the descriptor used for writing. */
|
||||
|
||||
int
|
||||
packet_get_connection_out(void)
|
||||
{
|
||||
return active_state->connection_out;
|
||||
}
|
||||
|
||||
+static int
|
||||
+packet_state_has_keys (const struct session_state *state)
|
||||
+{
|
||||
+ return state != NULL &&
|
||||
+ (state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL);
|
||||
+}
|
||||
+
|
||||
/* Closes the connection and clears and frees internal data structures. */
|
||||
|
||||
void
|
||||
packet_close(void)
|
||||
{
|
||||
if (!active_state->initialized)
|
||||
return;
|
||||
active_state->initialized = 0;
|
||||
- if (active_state->connection_in == active_state->connection_out) {
|
||||
- shutdown(active_state->connection_out, SHUT_RDWR);
|
||||
- close(active_state->connection_out);
|
||||
- } else {
|
||||
- close(active_state->connection_in);
|
||||
- close(active_state->connection_out);
|
||||
- }
|
||||
buffer_free(&active_state->input);
|
||||
buffer_free(&active_state->output);
|
||||
buffer_free(&active_state->outgoing_packet);
|
||||
buffer_free(&active_state->incoming_packet);
|
||||
if (active_state->compression_buffer_ready) {
|
||||
buffer_free(&active_state->compression_buffer);
|
||||
buffer_compress_uninit();
|
||||
}
|
||||
- cipher_cleanup(&active_state->send_context);
|
||||
- cipher_cleanup(&active_state->receive_context);
|
||||
+ if (packet_state_has_keys(active_state)) {
|
||||
+ cipher_cleanup(&active_state->send_context);
|
||||
+ cipher_cleanup(&active_state->receive_context);
|
||||
+ audit_session_key_free(2);
|
||||
+ }
|
||||
+ if (active_state->connection_in == active_state->connection_out) {
|
||||
+ shutdown(active_state->connection_out, SHUT_RDWR);
|
||||
+ close(active_state->connection_out);
|
||||
+ } else {
|
||||
+ close(active_state->connection_in);
|
||||
+ close(active_state->connection_out);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Sets remote side protocol flags. */
|
||||
|
||||
void
|
||||
packet_set_protocol_flags(u_int protocol_flags)
|
||||
{
|
||||
active_state->remote_protocol_flags = protocol_flags;
|
||||
@@ -729,16 +740,35 @@ packet_send1(void)
|
||||
|
||||
/*
|
||||
* Note that the packet is now only buffered in output. It won't be
|
||||
* actually sent until packet_write_wait or packet_write_poll is
|
||||
* called.
|
||||
*/
|
||||
}
|
||||
|
||||
+static void
|
||||
+newkeys_destroy_and_free(Newkeys *newkeys)
|
||||
+{
|
||||
+ if (newkeys == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ free(newkeys->enc.name);
|
||||
+
|
||||
+ mac_clear(&newkeys->mac);
|
||||
+ /* MAC may happen to be empty - if the GCM mode of AES is used */
|
||||
+ if (newkeys->mac.name)
|
||||
+ free(newkeys->mac.name);
|
||||
+
|
||||
+ free(newkeys->comp.name);
|
||||
+
|
||||
+ newkeys_destroy(newkeys);
|
||||
+ free(newkeys);
|
||||
+}
|
||||
+
|
||||
void
|
||||
set_newkeys(int mode)
|
||||
{
|
||||
Enc *enc;
|
||||
Mac *mac;
|
||||
Comp *comp;
|
||||
CipherContext *cc;
|
||||
u_int64_t *max_blocks;
|
||||
@@ -754,31 +784,19 @@ set_newkeys(int mode)
|
||||
} else {
|
||||
cc = &active_state->receive_context;
|
||||
crypt_type = CIPHER_DECRYPT;
|
||||
active_state->p_read.packets = active_state->p_read.blocks = 0;
|
||||
max_blocks = &active_state->max_blocks_in;
|
||||
}
|
||||
if (active_state->newkeys[mode] != NULL) {
|
||||
debug("set_newkeys: rekeying");
|
||||
+ audit_session_key_free(mode);
|
||||
cipher_cleanup(cc);
|
||||
- enc = &active_state->newkeys[mode]->enc;
|
||||
- mac = &active_state->newkeys[mode]->mac;
|
||||
- comp = &active_state->newkeys[mode]->comp;
|
||||
- mac_clear(mac);
|
||||
- memset(enc->iv, 0, enc->iv_len);
|
||||
- memset(enc->key, 0, enc->key_len);
|
||||
- memset(mac->key, 0, mac->key_len);
|
||||
- free(enc->name);
|
||||
- free(enc->iv);
|
||||
- free(enc->key);
|
||||
- free(mac->name);
|
||||
- free(mac->key);
|
||||
- free(comp->name);
|
||||
- free(active_state->newkeys[mode]);
|
||||
+ newkeys_destroy_and_free(active_state->newkeys[mode]);
|
||||
}
|
||||
active_state->newkeys[mode] = kex_get_newkeys(mode);
|
||||
if (active_state->newkeys[mode] == NULL)
|
||||
fatal("newkeys: no keys for mode %d", mode);
|
||||
enc = &active_state->newkeys[mode]->enc;
|
||||
mac = &active_state->newkeys[mode]->mac;
|
||||
comp = &active_state->newkeys[mode]->comp;
|
||||
if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0)
|
||||
@@ -2004,54 +2022,93 @@ packet_get_output(void)
|
||||
}
|
||||
|
||||
void *
|
||||
packet_get_newkeys(int mode)
|
||||
{
|
||||
return (void *)active_state->newkeys[mode];
|
||||
}
|
||||
|
||||
+static void
|
||||
+packet_destroy_state(struct session_state *state)
|
||||
+{
|
||||
+ if (state == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ cipher_cleanup(&state->receive_context);
|
||||
+ cipher_cleanup(&state->send_context);
|
||||
+
|
||||
+ buffer_free(&state->input);
|
||||
+ buffer_free(&state->output);
|
||||
+ buffer_free(&state->outgoing_packet);
|
||||
+ buffer_free(&state->incoming_packet);
|
||||
+ buffer_free(&state->compression_buffer);
|
||||
+ newkeys_destroy_and_free(state->newkeys[MODE_IN]);
|
||||
+ state->newkeys[MODE_IN] = NULL;
|
||||
+ newkeys_destroy_and_free(state->newkeys[MODE_OUT]);
|
||||
+ state->newkeys[MODE_OUT] = NULL;
|
||||
+ mac_destroy(state->packet_discard_mac);
|
||||
+// TAILQ_HEAD(, packet) outgoing;
|
||||
+// memset(state, 0, sizeof(state));
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+packet_destroy_all(int audit_it, int privsep)
|
||||
+{
|
||||
+ if (audit_it)
|
||||
+ audit_it = packet_state_has_keys (active_state) ||
|
||||
+ packet_state_has_keys (backup_state);
|
||||
+ packet_destroy_state(active_state);
|
||||
+ packet_destroy_state(backup_state);
|
||||
+ if (audit_it) {
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ if (privsep)
|
||||
+ audit_session_key_free(2);
|
||||
+ else
|
||||
+ audit_session_key_free_body(2, getpid(), getuid());
|
||||
+#endif
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Save the state for the real connection, and use a separate state when
|
||||
* resuming a suspended connection.
|
||||
*/
|
||||
void
|
||||
packet_backup_state(void)
|
||||
{
|
||||
- struct session_state *tmp;
|
||||
-
|
||||
close(active_state->connection_in);
|
||||
active_state->connection_in = -1;
|
||||
close(active_state->connection_out);
|
||||
active_state->connection_out = -1;
|
||||
- if (backup_state)
|
||||
- tmp = backup_state;
|
||||
- else
|
||||
- tmp = alloc_session_state();
|
||||
backup_state = active_state;
|
||||
- active_state = tmp;
|
||||
+ active_state = alloc_session_state();
|
||||
}
|
||||
|
||||
/*
|
||||
* Swap in the old state when resuming a connecion.
|
||||
*/
|
||||
void
|
||||
packet_restore_state(void)
|
||||
{
|
||||
struct session_state *tmp;
|
||||
void *buf;
|
||||
u_int len;
|
||||
|
||||
tmp = backup_state;
|
||||
backup_state = active_state;
|
||||
active_state = tmp;
|
||||
active_state->connection_in = backup_state->connection_in;
|
||||
- backup_state->connection_in = -1;
|
||||
active_state->connection_out = backup_state->connection_out;
|
||||
- backup_state->connection_out = -1;
|
||||
len = buffer_len(&backup_state->input);
|
||||
if (len > 0) {
|
||||
buf = buffer_ptr(&backup_state->input);
|
||||
buffer_append(&active_state->input, buf, len);
|
||||
buffer_clear(&backup_state->input);
|
||||
add_recv_bytes(len);
|
||||
}
|
||||
+ backup_state->connection_in = -1;
|
||||
+ backup_state->connection_out = -1;
|
||||
+ packet_destroy_state(backup_state);
|
||||
+ free(backup_state);
|
||||
+ backup_state = NULL;
|
||||
}
|
||||
+
|
||||
diff --git a/openssh-6.5p1/packet.h b/openssh-6.5p1/packet.h
|
||||
--- a/openssh-6.5p1/packet.h
|
||||
+++ b/openssh-6.5p1/packet.h
|
||||
@@ -119,9 +119,10 @@ void packet_set_rekey_limits(u_int32_t,
|
||||
time_t packet_get_rekey_timeout(void);
|
||||
|
||||
void packet_backup_state(void);
|
||||
void packet_restore_state(void);
|
||||
|
||||
void *packet_get_input(void);
|
||||
void *packet_get_output(void);
|
||||
|
||||
+void packet_destroy_all(int, int);
|
||||
#endif /* PACKET_H */
|
||||
diff --git a/openssh-6.5p1/session.c b/openssh-6.5p1/session.c
|
||||
--- a/openssh-6.5p1/session.c
|
||||
+++ b/openssh-6.5p1/session.c
|
||||
@@ -1689,16 +1689,19 @@ do_child(Session *s, const char *command
|
||||
int env_size;
|
||||
char *argv[ARGV_MAX];
|
||||
const char *shell, *shell0, *hostname = NULL;
|
||||
struct passwd *pw = s->pw;
|
||||
int r = 0;
|
||||
|
||||
/* remove hostkey from the child's memory */
|
||||
destroy_sensitive_data();
|
||||
+ /* Don't audit this - both us and the parent would be talking to the
|
||||
+ monitor over a single socket, with no synchronization. */
|
||||
+ packet_destroy_all(0, 1);
|
||||
|
||||
/* Force a password change */
|
||||
if (s->authctxt->force_pwchange) {
|
||||
do_setusercontext(pw);
|
||||
child_close_fds();
|
||||
do_pwchange(s);
|
||||
exit(1);
|
||||
}
|
||||
diff --git a/openssh-6.5p1/sshd.c b/openssh-6.5p1/sshd.c
|
||||
--- a/openssh-6.5p1/sshd.c
|
||||
+++ b/openssh-6.5p1/sshd.c
|
||||
@@ -711,16 +711,18 @@ privsep_preauth(Authctxt *authctxt)
|
||||
setproctitle("%s", "[net]");
|
||||
if (box != NULL)
|
||||
ssh_sandbox_child(box);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
+extern Newkeys *current_keys[];
|
||||
+
|
||||
static void
|
||||
privsep_postauth(Authctxt *authctxt)
|
||||
{
|
||||
u_int32_t rnd[256];
|
||||
|
||||
#ifdef DISABLE_FD_PASSING
|
||||
if (1) {
|
||||
#else
|
||||
@@ -735,16 +737,20 @@ privsep_postauth(Authctxt *authctxt)
|
||||
monitor_reinit(pmonitor);
|
||||
|
||||
pmonitor->m_pid = fork();
|
||||
if (pmonitor->m_pid == -1)
|
||||
fatal("fork of unprivileged child failed");
|
||||
else if (pmonitor->m_pid != 0) {
|
||||
verbose("User child is on pid %ld", (long)pmonitor->m_pid);
|
||||
buffer_clear(&loginmsg);
|
||||
+ newkeys_destroy(current_keys[MODE_OUT]);
|
||||
+ newkeys_destroy(current_keys[MODE_IN]);
|
||||
+ audit_session_key_free_body(2, getpid(), getuid());
|
||||
+ packet_destroy_all(0, 0);
|
||||
monitor_child_postauth(pmonitor);
|
||||
|
||||
/* NEVERREACHED */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* child */
|
||||
|
||||
@@ -2104,16 +2110,17 @@ main(int ac, char **av)
|
||||
do_authentication(authctxt);
|
||||
}
|
||||
/*
|
||||
* If we use privilege separation, the unprivileged child transfers
|
||||
* the current keystate and exits
|
||||
*/
|
||||
if (use_privsep) {
|
||||
mm_send_keystate(pmonitor);
|
||||
+ packet_destroy_all(1, 1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
authenticated:
|
||||
/*
|
||||
* Cancel the alarm we set to limit the time taken for
|
||||
* authentication.
|
||||
*/
|
||||
@@ -2156,16 +2163,18 @@ main(int ac, char **av)
|
||||
|
||||
packet_set_timeout(options.client_alive_interval,
|
||||
options.client_alive_count_max);
|
||||
|
||||
/* Start session. */
|
||||
do_authenticated(authctxt);
|
||||
|
||||
/* The connection has been terminated. */
|
||||
+ packet_destroy_all(1, 1);
|
||||
+
|
||||
packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
|
||||
packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
|
||||
verbose("Transferred: sent %llu, received %llu bytes",
|
||||
(unsigned long long)obytes, (unsigned long long)ibytes);
|
||||
|
||||
verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
|
||||
|
||||
#ifdef USE_PAM
|
||||
@@ -2497,26 +2506,38 @@ do_ssh2_kex(void)
|
||||
#endif
|
||||
debug("KEX done");
|
||||
}
|
||||
|
||||
/* server specific fatal cleanup */
|
||||
void
|
||||
cleanup_exit(int i)
|
||||
{
|
||||
+ static int in_cleanup = 0;
|
||||
+ int is_privsep_child;
|
||||
+
|
||||
+ /* cleanup_exit can be called at the very least from the privsep
|
||||
+ wrappers used for auditing. Make sure we don't recurse
|
||||
+ indefinitely. */
|
||||
+ if (in_cleanup)
|
||||
+ _exit(i);
|
||||
+ in_cleanup = 1;
|
||||
+
|
||||
if (the_authctxt) {
|
||||
do_cleanup(the_authctxt);
|
||||
if (use_privsep && privsep_is_preauth && pmonitor->m_pid > 1) {
|
||||
debug("Killing privsep child %d", pmonitor->m_pid);
|
||||
if (kill(pmonitor->m_pid, SIGKILL) != 0 &&
|
||||
errno != ESRCH)
|
||||
error("%s: kill(%d): %s", __func__,
|
||||
pmonitor->m_pid, strerror(errno));
|
||||
}
|
||||
}
|
||||
+ is_privsep_child = use_privsep && (pmonitor != NULL) && !mm_is_monitor();
|
||||
+ packet_destroy_all(1, is_privsep_child);
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
|
||||
if ((the_authctxt == NULL || !the_authctxt->authenticated) &&
|
||||
(!use_privsep || mm_is_monitor()))
|
||||
audit_event(SSH_CONNECTION_ABANDON);
|
||||
#endif
|
||||
_exit(i);
|
||||
}
|
738
openssh-6.5p1-audit6-server_key_destruction.patch
Normal file
738
openssh-6.5p1-audit6-server_key_destruction.patch
Normal file
@ -0,0 +1,738 @@
|
||||
# server key destruction and auditing
|
||||
# based on:
|
||||
# https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
# https://bugzilla.mindrot.org/attachment.cgi?id=2015
|
||||
# by jchadima@redhat.com
|
||||
|
||||
diff --git a/openssh-6.5p1/audit-bsm.c b/openssh-6.5p1/audit-bsm.c
|
||||
--- a/openssh-6.5p1/audit-bsm.c
|
||||
+++ b/openssh-6.5p1/audit-bsm.c
|
||||
@@ -486,9 +486,27 @@ audit_kex_body(int ctos, char *enc, char
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
+
|
||||
+void
|
||||
+audit_destroy_sensitive_data(const char *fp)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_generate_ephemeral_server_key(const char *fp)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
#endif /* BSM */
|
||||
diff --git a/openssh-6.5p1/audit-linux.c b/openssh-6.5p1/audit-linux.c
|
||||
--- a/openssh-6.5p1/audit-linux.c
|
||||
+++ b/openssh-6.5p1/audit-linux.c
|
||||
@@ -351,9 +351,55 @@ audit_session_key_free_body(int ctos, pi
|
||||
audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
|
||||
buf, NULL, get_remote_ipaddr(), NULL, 1);
|
||||
audit_close(audit_fd);
|
||||
/* do not abort if the error is EPERM and sshd is run as non root user */
|
||||
if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
|
||||
error("cannot write into audit");
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, audit_ok;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ",
|
||||
+ fp, (intmax_t)pid, (intmax_t)uid);
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno != EINVAL && errno != EPROTONOSUPPORT &&
|
||||
+ errno != EAFNOSUPPORT)
|
||||
+ error("cannot open audit");
|
||||
+ return;
|
||||
+ }
|
||||
+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
|
||||
+ buf, NULL,
|
||||
+ listening_for_clients() ? NULL : get_remote_ipaddr(),
|
||||
+ NULL, 1);
|
||||
+ audit_close(audit_fd);
|
||||
+ /* do not abort if the error is EPERM and sshd is run as non root user */
|
||||
+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
|
||||
+ error("cannot write into audit");
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_generate_ephemeral_server_key(const char *fp)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, audit_ok;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=create kind=server fp=%s direction=? ", fp);
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno != EINVAL && errno != EPROTONOSUPPORT &&
|
||||
+ errno != EAFNOSUPPORT)
|
||||
+ error("cannot open audit");
|
||||
+ return;
|
||||
+ }
|
||||
+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
|
||||
+ buf, NULL, 0, NULL, 1);
|
||||
+ audit_close(audit_fd);
|
||||
+ /* do not abort if the error is EPERM and sshd is run as non root user */
|
||||
+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
|
||||
+ error("cannot write into audit");
|
||||
+}
|
||||
#endif /* USE_LINUX_AUDIT */
|
||||
diff --git a/openssh-6.5p1/audit.c b/openssh-6.5p1/audit.c
|
||||
--- a/openssh-6.5p1/audit.c
|
||||
+++ b/openssh-6.5p1/audit.c
|
||||
@@ -285,10 +285,29 @@ audit_kex_body(int ctos, char *enc, char
|
||||
* This will be called on succesfull session key discard
|
||||
*/
|
||||
void
|
||||
audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
|
||||
{
|
||||
debug("audit session key discard euid %u direction %d from pid %ld uid %u",
|
||||
(unsigned)geteuid(), ctos, (long)pid, (unsigned)uid);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called on destroy private part of the server key
|
||||
+ */
|
||||
+void
|
||||
+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u",
|
||||
+ geteuid(), fp, (long)pid, (unsigned)uid);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called on generation of the ephemeral server key
|
||||
+ */
|
||||
+void
|
||||
+audit_generate_ephemeral_server_key(const char *)
|
||||
+{
|
||||
+ debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
|
||||
+}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/audit.h b/openssh-6.5p1/audit.h
|
||||
--- a/openssh-6.5p1/audit.h
|
||||
+++ b/openssh-6.5p1/audit.h
|
||||
@@ -43,26 +43,30 @@ enum ssh_audit_event_type {
|
||||
SSH_INVALID_USER,
|
||||
SSH_NOLOGIN, /* denied by /etc/nologin, not implemented */
|
||||
SSH_CONNECTION_CLOSE, /* closed after attempting auth or session */
|
||||
SSH_CONNECTION_ABANDON, /* closed without completing auth */
|
||||
SSH_AUDIT_UNKNOWN
|
||||
};
|
||||
typedef enum ssh_audit_event_type ssh_audit_event_t;
|
||||
|
||||
+int listening_for_clients(void);
|
||||
+
|
||||
void audit_connection_from(const char *, int);
|
||||
void audit_event(ssh_audit_event_t);
|
||||
void audit_count_session_open(void);
|
||||
void audit_session_open(struct logininfo *);
|
||||
void audit_session_close(struct logininfo *);
|
||||
int audit_run_command(const char *);
|
||||
void audit_end_command(int, const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
int audit_keyusage(int, const char *, unsigned, char *, int);
|
||||
void audit_key(int, int *, const Key *);
|
||||
void audit_unsupported(int);
|
||||
void audit_kex(int, char *, char *, char *);
|
||||
void audit_unsupported_body(int);
|
||||
void audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
|
||||
void audit_session_key_free(int ctos);
|
||||
void audit_session_key_free_body(int ctos, pid_t, uid_t);
|
||||
+void audit_destroy_sensitive_data(const char *, pid_t, uid_t);
|
||||
+void audit_generate_ephemeral_server_key(const char *);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff --git a/openssh-6.5p1/key.c b/openssh-6.5p1/key.c
|
||||
--- a/openssh-6.5p1/key.c
|
||||
+++ b/openssh-6.5p1/key.c
|
||||
@@ -1959,16 +1959,41 @@ key_demote(const Key *k)
|
||||
fatal("key_demote: bad key type %d", k->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return (pk);
|
||||
}
|
||||
|
||||
int
|
||||
+key_is_private(const Key *k)
|
||||
+{
|
||||
+ switch (k->type) {
|
||||
+ case KEY_RSA_CERT_V00:
|
||||
+ case KEY_RSA_CERT:
|
||||
+ case KEY_RSA1:
|
||||
+ case KEY_RSA:
|
||||
+ return k->rsa->d != NULL;
|
||||
+ case KEY_DSA_CERT_V00:
|
||||
+ case KEY_DSA_CERT:
|
||||
+ case KEY_DSA:
|
||||
+ return k->dsa->priv_key != NULL;
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+ case KEY_ECDSA_CERT:
|
||||
+ case KEY_ECDSA:
|
||||
+ return EC_KEY_get0_private_key(k->ecdsa) != NULL;
|
||||
+#endif
|
||||
+ default:
|
||||
+ /* fatal("key_is_private: bad key type %d", k->type); */
|
||||
+ debug2("key_is_private: bad key type %d", k->type);
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int
|
||||
key_is_cert(const Key *k)
|
||||
{
|
||||
if (k == NULL)
|
||||
return 0;
|
||||
return key_type_is_cert(k->type);
|
||||
}
|
||||
|
||||
/* Return the cert-less equivalent to a certified key type */
|
||||
diff --git a/openssh-6.5p1/key.h b/openssh-6.5p1/key.h
|
||||
--- a/openssh-6.5p1/key.h
|
||||
+++ b/openssh-6.5p1/key.h
|
||||
@@ -113,16 +113,17 @@ int key_read(Key *, char **);
|
||||
u_int key_size(const Key *);
|
||||
enum fp_type key_fp_type_select(void);
|
||||
char *key_fp_type_str(enum fp_type);
|
||||
|
||||
Key *key_generate(int, u_int);
|
||||
Key *key_from_private(const Key *);
|
||||
int key_type_from_name(char *);
|
||||
int key_is_cert(const Key *);
|
||||
+int key_is_private(const Key *k);
|
||||
int key_type_is_cert(int);
|
||||
int key_type_plain(int);
|
||||
int key_to_certified(Key *, int);
|
||||
int key_drop_cert(Key *);
|
||||
int key_certify(Key *, Key *);
|
||||
void key_cert_copy(const Key *, struct Key *);
|
||||
int key_cert_check_authority(const Key *, int, int, const char *,
|
||||
const char **);
|
||||
diff --git a/openssh-6.5p1/monitor.c b/openssh-6.5p1/monitor.c
|
||||
--- a/openssh-6.5p1/monitor.c
|
||||
+++ b/openssh-6.5p1/monitor.c
|
||||
@@ -110,16 +110,18 @@ extern u_int utmp_len;
|
||||
extern Newkeys *current_keys[];
|
||||
extern z_stream incoming_stream;
|
||||
extern z_stream outgoing_stream;
|
||||
extern u_char session_id[];
|
||||
extern Buffer auth_debug;
|
||||
extern int auth_debug_init;
|
||||
extern Buffer loginmsg;
|
||||
|
||||
+extern void destroy_sensitive_data(int);
|
||||
+
|
||||
/* State exported from the child */
|
||||
|
||||
struct {
|
||||
z_stream incoming;
|
||||
z_stream outgoing;
|
||||
u_char *keyin;
|
||||
u_int keyinlen;
|
||||
u_char *keyout;
|
||||
@@ -186,16 +188,17 @@ int mm_answer_gss_checkmic(int, Buffer *
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
int mm_answer_audit_event(int, Buffer *);
|
||||
int mm_answer_audit_command(int, Buffer *);
|
||||
int mm_answer_audit_end_command(int, Buffer *);
|
||||
int mm_answer_audit_unsupported_body(int, Buffer *);
|
||||
int mm_answer_audit_kex_body(int, Buffer *);
|
||||
int mm_answer_audit_session_key_free_body(int, Buffer *);
|
||||
+int mm_answer_audit_server_key_free(int, Buffer *);
|
||||
#endif
|
||||
|
||||
static int monitor_read_log(struct monitor *);
|
||||
|
||||
static Authctxt *authctxt;
|
||||
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
|
||||
|
||||
/* local state for key verify */
|
||||
@@ -240,16 +243,17 @@ struct mon_table mon_dispatch_proto20[]
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
{MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
{MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
|
||||
+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
|
||||
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
{MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
|
||||
{MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
|
||||
@@ -280,16 +284,17 @@ struct mon_table mon_dispatch_postauth20
|
||||
{MONITOR_REQ_TERM, 0, mm_answer_term},
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
|
||||
{MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
{MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
{MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
{MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
|
||||
+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table mon_dispatch_proto15[] = {
|
||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
|
||||
{MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
|
||||
{MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
|
||||
@@ -314,31 +319,33 @@ struct mon_table mon_dispatch_proto15[]
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
{MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
{MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
|
||||
+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table mon_dispatch_postauth15[] = {
|
||||
{MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
|
||||
{MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
|
||||
{MONITOR_REQ_TERM, 0, mm_answer_term},
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
|
||||
{MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
{MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
|
||||
{MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
|
||||
{MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
|
||||
+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
struct mon_table *mon_dispatch;
|
||||
|
||||
/* Specifies if a certain message is allowed at the moment */
|
||||
|
||||
@@ -1761,16 +1768,18 @@ mm_answer_term(int sock, Buffer *req)
|
||||
/* The child is terminating */
|
||||
session_destroy_all(&mm_session_close);
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
sshpam_cleanup();
|
||||
#endif
|
||||
|
||||
+ destroy_sensitive_data(0);
|
||||
+
|
||||
while (waitpid(pmonitor->m_pid, &status, 0) == -1)
|
||||
if (errno != EINTR)
|
||||
exit(1);
|
||||
|
||||
res = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
|
||||
|
||||
/* Terminate process */
|
||||
exit(res);
|
||||
@@ -2505,9 +2514,30 @@ mm_answer_audit_session_key_free_body(in
|
||||
|
||||
audit_session_key_free_body(ctos, pid, uid);
|
||||
|
||||
buffer_clear(m);
|
||||
|
||||
mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m);
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+mm_answer_audit_server_key_free(int sock, Buffer *m)
|
||||
+{
|
||||
+ int len;
|
||||
+ char *fp;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ fp = buffer_get_string(m, &len);
|
||||
+ pid = buffer_get_int64(m);
|
||||
+ uid = buffer_get_int64(m);
|
||||
+
|
||||
+ audit_destroy_sensitive_data(fp, pid, uid);
|
||||
+
|
||||
+ free(fp);
|
||||
+ buffer_clear(m);
|
||||
+
|
||||
+ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m);
|
||||
+ return 0;
|
||||
+}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/monitor.h b/openssh-6.5p1/monitor.h
|
||||
--- a/openssh-6.5p1/monitor.h
|
||||
+++ b/openssh-6.5p1/monitor.h
|
||||
@@ -68,16 +68,17 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107,
|
||||
MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109,
|
||||
MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
|
||||
MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
|
||||
MONITOR_ANS_AUDIT_COMMAND = 114, MONITOR_REQ_AUDIT_END_COMMAND = 115,
|
||||
MONITOR_REQ_AUDIT_UNSUPPORTED = 116, MONITOR_ANS_AUDIT_UNSUPPORTED = 117,
|
||||
MONITOR_REQ_AUDIT_KEX = 118, MONITOR_ANS_AUDIT_KEX = 119,
|
||||
MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 120, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 121,
|
||||
+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 122, MONITOR_ANS_AUDIT_SERVER_KEY_FREE = 123,
|
||||
|
||||
};
|
||||
|
||||
struct mm_master;
|
||||
struct monitor {
|
||||
int m_recvfd;
|
||||
int m_sendfd;
|
||||
int m_log_recvfd;
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.c b/openssh-6.5p1/monitor_wrap.c
|
||||
--- a/openssh-6.5p1/monitor_wrap.c
|
||||
+++ b/openssh-6.5p1/monitor_wrap.c
|
||||
@@ -1537,9 +1537,25 @@ mm_audit_session_key_free_body(int ctos,
|
||||
buffer_put_int(&m, ctos);
|
||||
buffer_put_int64(&m, pid);
|
||||
buffer_put_int64(&m, uid);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE,
|
||||
&m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_cstring(&m, fp);
|
||||
+ buffer_put_int64(&m, pid);
|
||||
+ buffer_put_int64(&m, uid);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SERVER_KEY_FREE,
|
||||
+ &m);
|
||||
+ buffer_free(&m);
|
||||
+}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/monitor_wrap.h b/openssh-6.5p1/monitor_wrap.h
|
||||
--- a/openssh-6.5p1/monitor_wrap.h
|
||||
+++ b/openssh-6.5p1/monitor_wrap.h
|
||||
@@ -75,16 +75,17 @@ void mm_sshpam_free_ctx(void *);
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
#include "audit.h"
|
||||
void mm_audit_event(ssh_audit_event_t);
|
||||
int mm_audit_run_command(const char *);
|
||||
void mm_audit_end_command(int, const char *);
|
||||
void mm_audit_unsupported_body(int);
|
||||
void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
|
||||
void mm_audit_session_key_free_body(int, pid_t, uid_t);
|
||||
+void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
void mm_terminate(void);
|
||||
int mm_pty_allocate(int *, int *, char *, size_t);
|
||||
void mm_session_pty_cleanup2(struct Session *);
|
||||
|
||||
/* SSHv1 interfaces */
|
||||
diff --git a/openssh-6.5p1/session.c b/openssh-6.5p1/session.c
|
||||
--- a/openssh-6.5p1/session.c
|
||||
+++ b/openssh-6.5p1/session.c
|
||||
@@ -132,17 +132,17 @@ static int session_pty_req(Session *);
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern char *__progname;
|
||||
extern int log_stderr;
|
||||
extern int debug_flag;
|
||||
extern u_int utmp_len;
|
||||
extern int startup_pipe;
|
||||
-extern void destroy_sensitive_data(void);
|
||||
+extern void destroy_sensitive_data(int);
|
||||
extern Buffer loginmsg;
|
||||
|
||||
/* original command from peer. */
|
||||
const char *original_command = NULL;
|
||||
|
||||
/* data */
|
||||
static int sessions_first_unused = -1;
|
||||
static int sessions_nalloc = 0;
|
||||
@@ -1688,17 +1688,17 @@ do_child(Session *s, const char *command
|
||||
char **env;
|
||||
int env_size;
|
||||
char *argv[ARGV_MAX];
|
||||
const char *shell, *shell0, *hostname = NULL;
|
||||
struct passwd *pw = s->pw;
|
||||
int r = 0;
|
||||
|
||||
/* remove hostkey from the child's memory */
|
||||
- destroy_sensitive_data();
|
||||
+ destroy_sensitive_data(1);
|
||||
/* Don't audit this - both us and the parent would be talking to the
|
||||
monitor over a single socket, with no synchronization. */
|
||||
packet_destroy_all(0, 1);
|
||||
|
||||
/* Force a password change */
|
||||
if (s->authctxt->force_pwchange) {
|
||||
do_setusercontext(pw);
|
||||
child_close_fds();
|
||||
diff --git a/openssh-6.5p1/sshd.c b/openssh-6.5p1/sshd.c
|
||||
--- a/openssh-6.5p1/sshd.c
|
||||
+++ b/openssh-6.5p1/sshd.c
|
||||
@@ -256,17 +256,17 @@ Buffer cfg;
|
||||
|
||||
/* message to be displayed after login */
|
||||
Buffer loginmsg;
|
||||
|
||||
/* Unprivileged user */
|
||||
struct passwd *privsep_pw = NULL;
|
||||
|
||||
/* Prototypes for various functions defined later in this file. */
|
||||
-void destroy_sensitive_data(void);
|
||||
+void destroy_sensitive_data(int);
|
||||
void demote_sensitive_data(void);
|
||||
|
||||
static void do_ssh1_kex(void);
|
||||
static void do_ssh2_kex(void);
|
||||
|
||||
/*
|
||||
* Close all listening sockets
|
||||
*/
|
||||
@@ -275,16 +275,25 @@ close_listen_socks(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_listen_socks; i++)
|
||||
close(listen_socks[i]);
|
||||
num_listen_socks = -1;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Is this process listening for clients (i.e. not specific to any specific
|
||||
+ * client connection?)
|
||||
+ */
|
||||
+int listening_for_clients(void)
|
||||
+{
|
||||
+ return num_listen_socks > 0;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
close_startup_pipes(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (startup_pipes)
|
||||
for (i = 0; i < options.max_startups; i++)
|
||||
if (startup_pipes[i] != -1)
|
||||
@@ -554,60 +563,99 @@ sshd_exchange_identification(int sock_in
|
||||
close(sock_out);
|
||||
logit("Protocol major versions differ for %s: %.200s vs. %.200s",
|
||||
get_remote_ipaddr(),
|
||||
server_version_string, client_version_string);
|
||||
cleanup_exit(255);
|
||||
}
|
||||
}
|
||||
|
||||
-/* Destroy the host and server keys. They will no longer be needed. */
|
||||
+/*
|
||||
+ * Destroy the host and server keys. They will no longer be needed. Careful,
|
||||
+ * this can be called from cleanup_exit() - i.e. from just about anywhere.
|
||||
+ */
|
||||
void
|
||||
-destroy_sensitive_data(void)
|
||||
+destroy_sensitive_data(int privsep)
|
||||
{
|
||||
int i;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
|
||||
if (sensitive_data.server_key) {
|
||||
key_free(sensitive_data.server_key);
|
||||
sensitive_data.server_key = NULL;
|
||||
}
|
||||
+ pid = getpid();
|
||||
+ uid = getuid();
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
if (sensitive_data.host_keys[i]) {
|
||||
+ char *fp;
|
||||
+
|
||||
+ if (key_is_private(sensitive_data.host_keys[i]))
|
||||
+ fp = key_fingerprint(sensitive_data.host_keys[i],
|
||||
+ key_fp_type_select(), SSH_FP_HEX);
|
||||
+ else
|
||||
+ fp = NULL;
|
||||
key_free(sensitive_data.host_keys[i]);
|
||||
sensitive_data.host_keys[i] = NULL;
|
||||
+ if (fp != NULL) {
|
||||
+ if (privsep)
|
||||
+ PRIVSEP(audit_destroy_sensitive_data(fp,
|
||||
+ pid, uid));
|
||||
+ else
|
||||
+ audit_destroy_sensitive_data(fp,
|
||||
+ pid, uid);
|
||||
+ free(fp);
|
||||
+ }
|
||||
}
|
||||
- if (sensitive_data.host_certificates[i]) {
|
||||
+ if (sensitive_data.host_certificates
|
||||
+ && sensitive_data.host_certificates[i]) {
|
||||
key_free(sensitive_data.host_certificates[i]);
|
||||
sensitive_data.host_certificates[i] = NULL;
|
||||
}
|
||||
}
|
||||
sensitive_data.ssh1_host_key = NULL;
|
||||
memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH);
|
||||
}
|
||||
|
||||
/* Demote private to public keys for network child */
|
||||
void
|
||||
demote_sensitive_data(void)
|
||||
{
|
||||
Key *tmp;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
int i;
|
||||
|
||||
if (sensitive_data.server_key) {
|
||||
tmp = key_demote(sensitive_data.server_key);
|
||||
key_free(sensitive_data.server_key);
|
||||
sensitive_data.server_key = tmp;
|
||||
}
|
||||
|
||||
+ pid = getpid();
|
||||
+ uid = getuid();
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
if (sensitive_data.host_keys[i]) {
|
||||
+ char *fp;
|
||||
+
|
||||
+ if (key_is_private(sensitive_data.host_keys[i]))
|
||||
+ fp = key_fingerprint(sensitive_data.host_keys[i],
|
||||
+ key_fp_type_select(), SSH_FP_HEX);
|
||||
+ else
|
||||
+ fp = NULL;
|
||||
tmp = key_demote(sensitive_data.host_keys[i]);
|
||||
key_free(sensitive_data.host_keys[i]);
|
||||
sensitive_data.host_keys[i] = tmp;
|
||||
if (tmp->type == KEY_RSA1)
|
||||
sensitive_data.ssh1_host_key = tmp;
|
||||
+ if (fp != NULL) {
|
||||
+ audit_destroy_sensitive_data(fp, pid, uid);
|
||||
+ free(fp);
|
||||
+ }
|
||||
}
|
||||
/* Certs do not need demotion */
|
||||
}
|
||||
|
||||
/* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1192,16 +1240,17 @@ server_accept_loop(int *sock_in, int *so
|
||||
|
||||
/* Wait in select until there is a connection. */
|
||||
ret = select(maxfd+1, fdset, NULL, NULL, NULL);
|
||||
if (ret < 0 && errno != EINTR)
|
||||
error("select: %.100s", strerror(errno));
|
||||
if (received_sigterm) {
|
||||
logit("Received signal %d; terminating.",
|
||||
(int) received_sigterm);
|
||||
+ destroy_sensitive_data(0);
|
||||
close_listen_socks();
|
||||
unlink(options.pid_file);
|
||||
exit(received_sigterm == SIGTERM ? 0 : 255);
|
||||
}
|
||||
if (key_used && key_do_regen) {
|
||||
generate_ephemeral_server_key();
|
||||
key_used = 0;
|
||||
key_do_regen = 0;
|
||||
@@ -2153,27 +2202,28 @@ main(int ac, char **av)
|
||||
/*
|
||||
* In privilege separation, we fork another child and prepare
|
||||
* file descriptor passing.
|
||||
*/
|
||||
if (use_privsep) {
|
||||
privsep_postauth(authctxt);
|
||||
/* the monitor process [priv] will not return */
|
||||
if (!compat20)
|
||||
- destroy_sensitive_data();
|
||||
+ destroy_sensitive_data(0);
|
||||
}
|
||||
|
||||
packet_set_timeout(options.client_alive_interval,
|
||||
options.client_alive_count_max);
|
||||
|
||||
/* Start session. */
|
||||
do_authenticated(authctxt);
|
||||
|
||||
/* The connection has been terminated. */
|
||||
packet_destroy_all(1, 1);
|
||||
+ destroy_sensitive_data(1);
|
||||
|
||||
packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
|
||||
packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
|
||||
verbose("Transferred: sent %llu, received %llu bytes",
|
||||
(unsigned long long)obytes, (unsigned long long)ibytes);
|
||||
|
||||
verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
|
||||
|
||||
@@ -2392,17 +2442,17 @@ do_ssh1_kex(void)
|
||||
MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
|
||||
MD5_Final(session_key + 16, &md);
|
||||
memset(buf, 0, bytes);
|
||||
free(buf);
|
||||
for (i = 0; i < 16; i++)
|
||||
session_id[i] = session_key[i] ^ session_key[i + 16];
|
||||
}
|
||||
/* Destroy the private and public keys. No longer. */
|
||||
- destroy_sensitive_data();
|
||||
+ destroy_sensitive_data(0);
|
||||
|
||||
if (use_privsep)
|
||||
mm_ssh1_session_id(session_id);
|
||||
|
||||
/* Destroy the decrypted integer. It is no longer needed. */
|
||||
BN_clear_free(session_key_int);
|
||||
|
||||
/* Set the session key. From this on all communications will be encrypted. */
|
||||
@@ -2527,16 +2577,18 @@ cleanup_exit(int i)
|
||||
debug("Killing privsep child %d", pmonitor->m_pid);
|
||||
if (kill(pmonitor->m_pid, SIGKILL) != 0 &&
|
||||
errno != ESRCH)
|
||||
error("%s: kill(%d): %s", __func__,
|
||||
pmonitor->m_pid, strerror(errno));
|
||||
}
|
||||
}
|
||||
is_privsep_child = use_privsep && (pmonitor != NULL) && !mm_is_monitor();
|
||||
+ if (sensitive_data.host_keys != NULL)
|
||||
+ destroy_sensitive_data(is_privsep_child);
|
||||
packet_destroy_all(1, is_privsep_child);
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
|
||||
if ((the_authctxt == NULL || !the_authctxt->authenticated) &&
|
||||
(!use_privsep || mm_is_monitor()))
|
||||
audit_event(SSH_CONNECTION_ABANDON);
|
||||
#endif
|
||||
_exit(i);
|
107
openssh-6.5p1-audit7-libaudit_compat.patch
Normal file
107
openssh-6.5p1-audit7-libaudit_compat.patch
Normal file
@ -0,0 +1,107 @@
|
||||
# definitions for AUDIT_CRYPTO_* symbols fom libaudit 2.x
|
||||
|
||||
diff --git a/openssh-6.5p1/audit-linux.c b/openssh-6.5p1/audit-linux.c
|
||||
--- a/openssh-6.5p1/audit-linux.c
|
||||
+++ b/openssh-6.5p1/audit-linux.c
|
||||
@@ -25,16 +25,17 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Red Hat author: Jan F. Chadima <jchadima@redhat.com>
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#if defined(USE_LINUX_AUDIT)
|
||||
#include <libaudit.h>
|
||||
+#include "compat-libaudit.h"
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "audit.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
diff --git a/openssh-6.5p1/compat-libaudit.h b/openssh-6.5p1/compat-libaudit.h
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/openssh-6.5p1/compat-libaudit.h
|
||||
@@ -0,0 +1,79 @@
|
||||
+/* AUDIT_CRYPTO symbol definitions from libaudit 2.x */
|
||||
+/* libaudit.h --
|
||||
+ * Copyright 2004-2011 Red Hat Inc., Durham, North Carolina.
|
||||
+ * All Rights Reserved.
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Steve Grubb <sgrubb@redhat.com>
|
||||
+ * Rickard E. (Rik) Faith <faith@redhat.com>
|
||||
+ */
|
||||
+#ifndef _COMPAT_LIBAUDIT_H_
|
||||
+#define _COMPAT_LIBAUDIT_H_
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_FIRST_CRYPTO_MSG
|
||||
+#define AUDIT_FIRST_CRYPTO_MSG 2400
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_CRYPTO_TEST_USER
|
||||
+#define AUDIT_CRYPTO_TEST_USER 2400 /* Crypto test results */
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_CRYPTO_PARAM_CHANGE_USER
|
||||
+#define AUDIT_CRYPTO_PARAM_CHANGE_USER 2401 /* Crypto attribute change */
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_CRYPTO_LOGIN
|
||||
+#define AUDIT_CRYPTO_LOGIN 2402 /* Logged in as crypto officer */
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_CRYPTO_LOGOUT
|
||||
+#define AUDIT_CRYPTO_LOGOUT 2403 /* Logged out from crypto */
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_CRYPTO_KEY_USER
|
||||
+#define AUDIT_CRYPTO_KEY_USER 2404 /* Create,delete,negotiate */
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_CRYPTO_FAILURE_USER
|
||||
+#define AUDIT_CRYPTO_FAILURE_USER 2405 /* Fail decrypt,encrypt,randomiz */
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_CRYPTO_REPLAY_USER
|
||||
+#define AUDIT_CRYPTO_REPLAY_USER 2406 /* Crypto replay detected */
|
||||
+#endif
|
||||
+
|
||||
+#ifndef AUDIT_CRYPTO_SESSION
|
||||
+#define AUDIT_CRYPTO_SESSION 2407 /* Record parameters set during
|
||||
+ TLS session establishment */
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+#ifndef AUDIT_LAST_CRYPTO_MSG
|
||||
+#define AUDIT_LAST_CRYPTO_MSG 2499
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* _COMPAT_LIBAUDIT_H_ */
|
||||
+
|
47
openssh-6.5p1-audit8-libaudit_dns_timeouts.patch
Normal file
47
openssh-6.5p1-audit8-libaudit_dns_timeouts.patch
Normal file
@ -0,0 +1,47 @@
|
||||
# bnc#752354, bnc#757360
|
||||
# prevent timeouts in libaudit code caused by DNS misconfiguration by
|
||||
# explicitely disabling DNS lookups in libaudit when UseDNS is false.
|
||||
# Note that this particular solution causes the logs to always contain
|
||||
# "hostname=?, addr=?" when DNS lookups are disabled.
|
||||
|
||||
diff --git a/openssh-6.5p1/audit-linux.c b/openssh-6.5p1/audit-linux.c
|
||||
--- a/openssh-6.5p1/audit-linux.c
|
||||
+++ b/openssh-6.5p1/audit-linux.c
|
||||
@@ -62,17 +62,17 @@ linux_audit_user_logxxx(int uid, const c
|
||||
if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
return; /* No audit support in kernel */
|
||||
else
|
||||
goto fatal_report; /* Must prevent login */
|
||||
}
|
||||
rc = audit_log_acct_message(audit_fd, event,
|
||||
NULL, "login", username ? username : "(unknown)",
|
||||
- username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
+ username == NULL ? uid : -1, options.use_dns ? hostname : NULL, ip, ttyn, success);
|
||||
saved_errno = errno;
|
||||
close(audit_fd);
|
||||
/*
|
||||
* Do not report error if the error is EPERM and sshd is run as non
|
||||
* root user.
|
||||
*/
|
||||
if ((rc == -EPERM) && (geteuid() != 0))
|
||||
rc = 0;
|
||||
@@ -114,17 +114,17 @@ linux_audit_user_auth(int uid, const cha
|
||||
goto fatal_report; /* Must prevent login */
|
||||
}
|
||||
|
||||
if ((event < 0) || (event > SSH_AUDIT_UNKNOWN))
|
||||
event = SSH_AUDIT_UNKNOWN;
|
||||
|
||||
rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH,
|
||||
NULL, event_name[event], username ? username : "(unknown)",
|
||||
- username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
+ username == NULL ? uid : -1, options.use_dns ? hostname : NULL, ip, ttyn, success);
|
||||
saved_errno = errno;
|
||||
close(audit_fd);
|
||||
/*
|
||||
* Do not report error if the error is EPERM and sshd is run as non
|
||||
* root user.
|
||||
*/
|
||||
if ((rc == -EPERM) && (geteuid() != 0))
|
||||
rc = 0;
|
73
openssh-6.5p1-blocksigalrm.patch
Normal file
73
openssh-6.5p1-blocksigalrm.patch
Normal file
@ -0,0 +1,73 @@
|
||||
# block SIGALRM while logging through syslog to prevent deadlocks (through
|
||||
# grace_alarm_handler)
|
||||
# bnc#57354
|
||||
|
||||
diff --git a/openssh-6.5p1/log.c b/openssh-6.5p1/log.c
|
||||
--- a/openssh-6.5p1/log.c
|
||||
+++ b/openssh-6.5p1/log.c
|
||||
@@ -47,16 +47,17 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
|
||||
# include <vis.h>
|
||||
#endif
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
+#include <signal.h>
|
||||
|
||||
static LogLevel log_level = SYSLOG_LEVEL_INFO;
|
||||
static int log_on_stderr = 1;
|
||||
static int log_stderr_fd = STDERR_FILENO;
|
||||
static int log_facility = LOG_AUTH;
|
||||
static char *argv0;
|
||||
static log_handler_fn *log_handler;
|
||||
static void *log_handler_ctx;
|
||||
@@ -384,16 +385,17 @@ do_log(LogLevel level, const char *fmt,
|
||||
{
|
||||
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
|
||||
struct syslog_data sdata = SYSLOG_DATA_INIT;
|
||||
#endif
|
||||
char msgbuf[MSGBUFSIZ];
|
||||
char fmtbuf[MSGBUFSIZ];
|
||||
char *txt = NULL;
|
||||
int pri = LOG_INFO;
|
||||
+ sigset_t nset, oset;
|
||||
int saved_errno = errno;
|
||||
log_handler_fn *tmp_handler;
|
||||
|
||||
if (level > log_level)
|
||||
return;
|
||||
|
||||
switch (level) {
|
||||
case SYSLOG_LEVEL_FATAL:
|
||||
@@ -442,20 +444,29 @@ do_log(LogLevel level, const char *fmt,
|
||||
tmp_handler = log_handler;
|
||||
log_handler = NULL;
|
||||
tmp_handler(level, fmtbuf, log_handler_ctx);
|
||||
log_handler = tmp_handler;
|
||||
} else if (log_on_stderr) {
|
||||
snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
|
||||
(void)write(log_stderr_fd, msgbuf, strlen(msgbuf));
|
||||
} else {
|
||||
+ /* Prevent a race between the grace_alarm
|
||||
+ * which writes a log message and terminates
|
||||
+ * and main sshd code that leads to deadlock
|
||||
+ * as syslog is not async safe.
|
||||
+ */
|
||||
+ sigemptyset(&nset);
|
||||
+ sigaddset(&nset, SIGALRM);
|
||||
+ sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
|
||||
openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
|
||||
syslog_r(pri, &sdata, "%.500s", fmtbuf);
|
||||
closelog_r(&sdata);
|
||||
#else
|
||||
openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
|
||||
syslog(pri, "%.500s", fmtbuf);
|
||||
closelog();
|
||||
#endif
|
||||
+ sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
errno = saved_errno;
|
||||
}
|
24
openssh-6.5p1-default-protocol.patch
Normal file
24
openssh-6.5p1-default-protocol.patch
Normal file
@ -0,0 +1,24 @@
|
||||
# only enable SSHv2 protocol by default (upstream default is fallback to v1)
|
||||
|
||||
diff --git a/openssh-6.5p1/ssh_config b/openssh-6.5p1/ssh_config
|
||||
--- a/openssh-6.5p1/ssh_config
|
||||
+++ b/openssh-6.5p1/ssh_config
|
||||
@@ -41,17 +41,17 @@ ForwardX11Trusted yes
|
||||
# CheckHostIP yes
|
||||
# AddressFamily any
|
||||
# ConnectTimeout 0
|
||||
# StrictHostKeyChecking ask
|
||||
# IdentityFile ~/.ssh/identity
|
||||
# IdentityFile ~/.ssh/id_rsa
|
||||
# IdentityFile ~/.ssh/id_dsa
|
||||
# Port 22
|
||||
-# Protocol 2,1
|
||||
+Protocol 2
|
||||
# Cipher 3des
|
||||
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
|
||||
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
|
||||
# EscapeChar ~
|
||||
# Tunnel no
|
||||
# TunnelDevice any:any
|
||||
# PermitLocalCommand no
|
||||
# VisualHostKey no
|
32
openssh-6.5p1-disable-openssl-abi-check.patch
Normal file
32
openssh-6.5p1-disable-openssl-abi-check.patch
Normal file
@ -0,0 +1,32 @@
|
||||
# disable run-time check for OpenSSL ABI by version number as that is not a
|
||||
# reliable indicator of ABI changes and doesn't make much sense in a
|
||||
# distribution package
|
||||
|
||||
diff --git a/openssh-6.5p1/entropy.c b/openssh-6.5p1/entropy.c
|
||||
--- a/openssh-6.5p1/entropy.c
|
||||
+++ b/openssh-6.5p1/entropy.c
|
||||
@@ -212,22 +212,23 @@ seed_rng(void)
|
||||
#endif
|
||||
/*
|
||||
* OpenSSL version numbers: MNNFFPPS: major minor fix patch status
|
||||
* We match major, minor, fix and status (not patch) for <1.0.0.
|
||||
* After that, we acceptable compatible fix versions (so we
|
||||
* allow 1.0.1 to work with 1.0.0). Going backwards is only allowed
|
||||
* within a patch series.
|
||||
*/
|
||||
+#if 0
|
||||
u_long version_mask = SSLeay() >= 0x1000000f ? ~0xffff0L : ~0xff0L;
|
||||
if (((SSLeay() ^ OPENSSL_VERSION_NUMBER) & version_mask) ||
|
||||
(SSLeay() >> 12) < (OPENSSL_VERSION_NUMBER >> 12))
|
||||
fatal("OpenSSL version mismatch. Built against %lx, you "
|
||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
|
||||
-
|
||||
+#endif
|
||||
#ifndef OPENSSL_PRNG_ONLY
|
||||
if (RAND_status() == 1) {
|
||||
debug3("RNG is ready, skipping seeding");
|
||||
return;
|
||||
}
|
||||
|
||||
if (seed_from_prngd(buf, sizeof(buf)) == -1)
|
||||
fatal("Could not obtain seed from PRNGd");
|
85
openssh-6.5p1-eal3.patch
Normal file
85
openssh-6.5p1-eal3.patch
Normal file
@ -0,0 +1,85 @@
|
||||
# fix paths and references in sshd man pages
|
||||
|
||||
diff --git a/openssh-6.5p1/sshd.8 b/openssh-6.5p1/sshd.8
|
||||
--- a/openssh-6.5p1/sshd.8
|
||||
+++ b/openssh-6.5p1/sshd.8
|
||||
@@ -875,17 +875,17 @@ See
|
||||
If this file exists,
|
||||
.Nm
|
||||
refuses to let anyone except root log in.
|
||||
The contents of the file
|
||||
are displayed to anyone trying to log in, and non-root connections are
|
||||
refused.
|
||||
The file should be world-readable.
|
||||
.Pp
|
||||
-.It Pa /etc/shosts.equiv
|
||||
+.It Pa /etc/ssh/shosts.equiv
|
||||
This file is used in exactly the same way as
|
||||
.Pa hosts.equiv ,
|
||||
but allows host-based authentication without permitting login with
|
||||
rlogin/rsh.
|
||||
.Pp
|
||||
.It Pa /etc/ssh/ssh_host_key
|
||||
.It Pa /etc/ssh/ssh_host_dsa_key
|
||||
.It Pa /etc/ssh/ssh_host_ecdsa_key
|
||||
@@ -956,17 +956,17 @@ The content of this file is not sensitiv
|
||||
.Xr sftp 1 ,
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
.Xr ssh-agent 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr ssh-keyscan 1 ,
|
||||
.Xr chroot 2 ,
|
||||
.Xr hosts_access 5 ,
|
||||
-.Xr login.conf 5 ,
|
||||
+.Xr login.defs 5 ,
|
||||
.Xr moduli 5 ,
|
||||
.Xr sshd_config 5 ,
|
||||
.Xr inetd 8 ,
|
||||
.Xr sftp-server 8
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
diff --git a/openssh-6.5p1/sshd_config.5 b/openssh-6.5p1/sshd_config.5
|
||||
--- a/openssh-6.5p1/sshd_config.5
|
||||
+++ b/openssh-6.5p1/sshd_config.5
|
||||
@@ -278,18 +278,17 @@ The contents of the specified file are s
|
||||
authentication is allowed.
|
||||
If the argument is
|
||||
.Dq none
|
||||
then no banner is displayed.
|
||||
This option is only available for protocol version 2.
|
||||
By default, no banner is displayed.
|
||||
.It Cm ChallengeResponseAuthentication
|
||||
Specifies whether challenge-response authentication is allowed (e.g. via
|
||||
-PAM or though authentication styles supported in
|
||||
-.Xr login.conf 5 )
|
||||
+PAM)
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm ChrootDirectory
|
||||
Specifies the pathname of a directory to
|
||||
.Xr chroot 2
|
||||
to after authentication.
|
||||
All components of the pathname must be root-owned directories that are
|
||||
not writable by any other user or group.
|
||||
@@ -576,17 +575,17 @@ and
|
||||
.Pa .shosts
|
||||
files will not be used in
|
||||
.Cm RhostsRSAAuthentication
|
||||
or
|
||||
.Cm HostbasedAuthentication .
|
||||
.Pp
|
||||
.Pa /etc/hosts.equiv
|
||||
and
|
||||
-.Pa /etc/shosts.equiv
|
||||
+.Pa /etc/ssh/shosts.equiv
|
||||
are still used.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm IgnoreUserKnownHosts
|
||||
Specifies whether
|
||||
.Xr sshd 8
|
||||
should ignore the user's
|
||||
.Pa ~/.ssh/known_hosts
|
730
openssh-6.5p1-fingerprint_hash.patch
Normal file
730
openssh-6.5p1-fingerprint_hash.patch
Normal file
@ -0,0 +1,730 @@
|
||||
# HG changeset patch
|
||||
# Parent 450c3933f35c6801a682ea32c588e4c9ff73414a
|
||||
|
||||
# select fingerprint hash algorithms based on the environment variable
|
||||
# SSH_FP_TYPE_ENVVAR and append it to hex and randomart fingerprints
|
||||
# Petr Cerny <pcerny@suse.cz>
|
||||
|
||||
diff --git a/openssh-6.5p1/auth-rsa.c b/openssh-6.5p1/auth-rsa.c
|
||||
--- a/openssh-6.5p1/auth-rsa.c
|
||||
+++ b/openssh-6.5p1/auth-rsa.c
|
||||
@@ -226,17 +226,17 @@ rsa_key_allowed_in_file(struct passwd *p
|
||||
|
||||
/* check the real bits */
|
||||
keybits = BN_num_bits(key->rsa->n);
|
||||
if (keybits < 0 || bits != keybits)
|
||||
logit("Warning: %s, line %lu: keysize mismatch: "
|
||||
"actual %d vs. announced %d.",
|
||||
file, linenum, BN_num_bits(key->rsa->n), bits);
|
||||
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
||||
debug("matching key found: file %s, line %lu %s %s",
|
||||
file, linenum, key_type(key), fp);
|
||||
free(fp);
|
||||
|
||||
/* Never accept a revoked key */
|
||||
if (auth_key_is_revoked(key))
|
||||
break;
|
||||
|
||||
diff --git a/openssh-6.5p1/auth.c b/openssh-6.5p1/auth.c
|
||||
--- a/openssh-6.5p1/auth.c
|
||||
+++ b/openssh-6.5p1/auth.c
|
||||
@@ -680,17 +680,17 @@ auth_key_is_revoked(Key *key)
|
||||
case -1:
|
||||
/* Error opening revoked_keys_file: refuse all keys */
|
||||
error("Revoked keys file is unreadable: refusing public key "
|
||||
"authentication");
|
||||
return 1;
|
||||
case 1:
|
||||
revoked:
|
||||
/* Key revoked */
|
||||
- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ key_fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
||||
error("WARNING: authentication attempt with a revoked "
|
||||
"%s key %s ", key_type(key), key_fp);
|
||||
free(key_fp);
|
||||
return 1;
|
||||
}
|
||||
fatal("key_in_file returned junk");
|
||||
}
|
||||
|
||||
diff --git a/openssh-6.5p1/auth2-hostbased.c b/openssh-6.5p1/auth2-hostbased.c
|
||||
--- a/openssh-6.5p1/auth2-hostbased.c
|
||||
+++ b/openssh-6.5p1/auth2-hostbased.c
|
||||
@@ -202,23 +202,23 @@ hostbased_key_allowed(struct passwd *pw,
|
||||
_PATH_SSH_SYSTEM_HOSTFILE2,
|
||||
options.ignore_user_known_hosts ? NULL :
|
||||
_PATH_SSH_USER_HOSTFILE2);
|
||||
}
|
||||
|
||||
if (host_status == HOST_OK) {
|
||||
if (key_is_cert(key)) {
|
||||
fp = key_fingerprint(key->cert->signature_key,
|
||||
- SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ key_fp_type_select(), SSH_FP_HEX);
|
||||
verbose("Accepted certificate ID \"%s\" signed by "
|
||||
"%s CA %s from %s@%s", key->cert->key_id,
|
||||
key_type(key->cert->signature_key), fp,
|
||||
cuser, lookup);
|
||||
} else {
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
||||
verbose("Accepted %s public key %s from %s@%s",
|
||||
key_type(key), fp, cuser, lookup);
|
||||
}
|
||||
free(fp);
|
||||
}
|
||||
|
||||
return (host_status == HOST_OK);
|
||||
}
|
||||
diff --git a/openssh-6.5p1/auth2-pubkey.c b/openssh-6.5p1/auth2-pubkey.c
|
||||
--- a/openssh-6.5p1/auth2-pubkey.c
|
||||
+++ b/openssh-6.5p1/auth2-pubkey.c
|
||||
@@ -208,25 +208,25 @@ pubkey_auth_info(Authctxt *authctxt, con
|
||||
i = vasprintf(&extra, fmt, ap);
|
||||
va_end(ap);
|
||||
if (i < 0 || extra == NULL)
|
||||
fatal("%s: vasprintf failed", __func__);
|
||||
}
|
||||
|
||||
if (key_is_cert(key)) {
|
||||
fp = key_fingerprint(key->cert->signature_key,
|
||||
- SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ key_fp_type_select(), SSH_FP_HEX);
|
||||
auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s",
|
||||
key_type(key), key->cert->key_id,
|
||||
(unsigned long long)key->cert->serial,
|
||||
key_type(key->cert->signature_key), fp,
|
||||
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
|
||||
free(fp);
|
||||
} else {
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
||||
auth_info(authctxt, "%s %s%s%s", key_type(key), fp,
|
||||
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
|
||||
free(fp);
|
||||
}
|
||||
free(extra);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -360,17 +360,17 @@ check_authkeys_file(FILE *f, char *file,
|
||||
if (key_is_cert(key)) {
|
||||
if (!key_equal(found, key->cert->signature_key))
|
||||
continue;
|
||||
if (auth_parse_options(pw, key_options, file,
|
||||
linenum) != 1)
|
||||
continue;
|
||||
if (!key_is_cert_authority)
|
||||
continue;
|
||||
- fp = key_fingerprint(found, SSH_FP_MD5,
|
||||
+ fp = key_fingerprint(found, key_fp_type_select(),
|
||||
SSH_FP_HEX);
|
||||
debug("matching CA found: file %s, line %lu, %s %s",
|
||||
file, linenum, key_type(found), fp);
|
||||
/*
|
||||
* If the user has specified a list of principals as
|
||||
* a key option, then prefer that list to matching
|
||||
* their username in the certificate principals list.
|
||||
*/
|
||||
@@ -401,17 +401,17 @@ check_authkeys_file(FILE *f, char *file,
|
||||
break;
|
||||
} else if (key_equal(found, key)) {
|
||||
if (auth_parse_options(pw, key_options, file,
|
||||
linenum) != 1)
|
||||
continue;
|
||||
if (key_is_cert_authority)
|
||||
continue;
|
||||
found_key = 1;
|
||||
- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(found, key_fp_type_select(), SSH_FP_HEX);
|
||||
debug("matching key found: file %s, line %lu %s %s",
|
||||
file, linenum, key_type(found), fp);
|
||||
free(fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found != NULL)
|
||||
key_free(found);
|
||||
@@ -427,17 +427,17 @@ user_cert_trusted_ca(struct passwd *pw,
|
||||
char *ca_fp, *principals_file = NULL;
|
||||
const char *reason;
|
||||
int ret = 0;
|
||||
|
||||
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
||||
return 0;
|
||||
|
||||
ca_fp = key_fingerprint(key->cert->signature_key,
|
||||
- SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ key_fp_type_select(), SSH_FP_HEX);
|
||||
|
||||
if (key_in_file(key->cert->signature_key,
|
||||
options.trusted_user_ca_keys, 1) != 1) {
|
||||
debug2("%s: CA %s %s is not listed in %s", __func__,
|
||||
key_type(key->cert->signature_key), ca_fp,
|
||||
options.trusted_user_ca_keys);
|
||||
goto out;
|
||||
}
|
||||
diff --git a/openssh-6.5p1/key.c b/openssh-6.5p1/key.c
|
||||
--- a/openssh-6.5p1/key.c
|
||||
+++ b/openssh-6.5p1/key.c
|
||||
@@ -420,30 +420,39 @@ key_fingerprint_raw(const Key *k, enum f
|
||||
*dgst_raw_length = ssh_digest_bytes(hash_alg);
|
||||
} else {
|
||||
fatal("%s: blob is null", __func__);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static char *
|
||||
-key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
|
||||
+key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len, enum fp_type dgst_type)
|
||||
{
|
||||
char *retval;
|
||||
u_int i;
|
||||
|
||||
- retval = xcalloc(1, dgst_raw_len * 3 + 1);
|
||||
+ /* reserve space for both the key hash and the string for the hash type */
|
||||
+ retval = xcalloc(1, dgst_raw_len * 3 + 1 + SSH_FP_TYPE_STRLEN + 2);
|
||||
for (i = 0; i < dgst_raw_len; i++) {
|
||||
char hex[4];
|
||||
snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
|
||||
strlcat(retval, hex, dgst_raw_len * 3 + 1);
|
||||
}
|
||||
|
||||
/* Remove the trailing ':' character */
|
||||
- retval[(dgst_raw_len * 3) - 1] = '\0';
|
||||
+ retval[(dgst_raw_len * 3) - 1] = ' ';
|
||||
+
|
||||
+ /* Append hash type */
|
||||
+ {
|
||||
+ char hash[SSH_FP_TYPE_STRLEN + 2 + 1];
|
||||
+ snprintf(hash, sizeof(hash), "[%s]", key_fp_type_str(dgst_type));
|
||||
+ strlcat(retval, hash, dgst_raw_len * 3 + 1 + SSH_FP_TYPE_STRLEN + 2);
|
||||
+ }
|
||||
+
|
||||
return retval;
|
||||
}
|
||||
|
||||
static char *
|
||||
key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
|
||||
{
|
||||
char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
|
||||
char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
|
||||
@@ -518,17 +527,18 @@ key_fingerprint_bubblebabble(u_char *dgs
|
||||
* can be in the exact middle of the picture, and FLDBASE should be >=8 .
|
||||
* Else pictures would be too dense, and drawing the frame would
|
||||
* fail, too, because the key type would not fit in anymore.
|
||||
*/
|
||||
#define FLDBASE 8
|
||||
#define FLDSIZE_Y (FLDBASE + 1)
|
||||
#define FLDSIZE_X (FLDBASE * 2 + 1)
|
||||
static char *
|
||||
-key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
|
||||
+key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k,
|
||||
+ enum fp_type dgst_type)
|
||||
{
|
||||
/*
|
||||
* Chars to be used after each other every time the worm
|
||||
* intersects with itself. Matter of taste.
|
||||
*/
|
||||
char *augmentation_string = " .o+=*BOX@%&#/^SE";
|
||||
char *retval, *p;
|
||||
u_char field[FLDSIZE_X][FLDSIZE_Y];
|
||||
@@ -585,18 +595,19 @@ key_fingerprint_randomart(u_char *dgst_r
|
||||
*p++ = '|';
|
||||
for (x = 0; x < FLDSIZE_X; x++)
|
||||
*p++ = augmentation_string[MIN(field[x][y], len)];
|
||||
*p++ = '|';
|
||||
*p++ = '\n';
|
||||
}
|
||||
|
||||
/* output lower border */
|
||||
- *p++ = '+';
|
||||
- for (i = 0; i < FLDSIZE_X; i++)
|
||||
+ i = snprintf(p, FLDSIZE_X, "+--[%s]", key_fp_type_str(dgst_type));
|
||||
+ p += i;
|
||||
+ for (i--; i < FLDSIZE_X; i++)
|
||||
*p++ = '-';
|
||||
*p++ = '+';
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *
|
||||
key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
|
||||
@@ -605,34 +616,91 @@ key_fingerprint(const Key *k, enum fp_ty
|
||||
u_char *dgst_raw;
|
||||
u_int dgst_raw_len;
|
||||
|
||||
dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len);
|
||||
if (!dgst_raw)
|
||||
fatal("key_fingerprint: null from key_fingerprint_raw()");
|
||||
switch (dgst_rep) {
|
||||
case SSH_FP_HEX:
|
||||
- retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
|
||||
+ retval = key_fingerprint_hex(dgst_raw, dgst_raw_len, dgst_type);
|
||||
break;
|
||||
case SSH_FP_BUBBLEBABBLE:
|
||||
retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
|
||||
break;
|
||||
case SSH_FP_RANDOMART:
|
||||
- retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k);
|
||||
+ retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k, dgst_type);
|
||||
break;
|
||||
default:
|
||||
fatal("key_fingerprint: bad digest representation %d",
|
||||
dgst_rep);
|
||||
break;
|
||||
}
|
||||
memset(dgst_raw, 0, dgst_raw_len);
|
||||
free(dgst_raw);
|
||||
return retval;
|
||||
}
|
||||
|
||||
+enum fp_type
|
||||
+key_fp_type_select(void)
|
||||
+{
|
||||
+ static enum fp_type fp;
|
||||
+ static char fp_defined = 0;
|
||||
+ char *env;
|
||||
+
|
||||
+ if (!fp_defined) {
|
||||
+ env = getenv(SSH_FP_TYPE_ENVVAR);
|
||||
+ if (env) {
|
||||
+ if (!strcasecmp(env, "md5") ||
|
||||
+ !strcasecmp(env, "md-5"))
|
||||
+ fp = SSH_FP_MD5;
|
||||
+ else if (!strcasecmp(env, "sha1") ||
|
||||
+ !strcasecmp(env, "sha-1"))
|
||||
+ fp = SSH_FP_SHA1;
|
||||
+#ifdef HAVE_EVP_SHA256
|
||||
+ else if (!strcasecmp(env, "sha256") ||
|
||||
+ !strcasecmp(env, "sha-256"))
|
||||
+ fp = SSH_FP_SHA256;
|
||||
+#endif
|
||||
+ else {
|
||||
+ error("invalid key type in environment variable "
|
||||
+ SSH_FP_TYPE_ENVVAR ": '%s' - falling back to MD5.",
|
||||
+ env);
|
||||
+ fp = SSH_FP_MD5;
|
||||
+ }
|
||||
+ } else
|
||||
+ fp = SSH_FP_MD5;
|
||||
+
|
||||
+ fp_defined = 1;
|
||||
+ }
|
||||
+ return fp;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * string lengths must be less or equal to SSH_FP_TYPE_STRLEN (defined in
|
||||
+ * key.h) as to fit into the fingerprint string buffer
|
||||
+ */
|
||||
+char *
|
||||
+key_fp_type_str(enum fp_type dgst_type)
|
||||
+{
|
||||
+ switch (dgst_type) {
|
||||
+ case SSH_FP_MD5:
|
||||
+ return "MD5";
|
||||
+ case SSH_FP_SHA1:
|
||||
+ return "SHA-1";
|
||||
+#ifdef HAVE_EVP_SHA256
|
||||
+ case SSH_FP_SHA256:
|
||||
+ return "SHA-256";
|
||||
+#endif
|
||||
+ default:
|
||||
+ fatal("%s: unknown key fingerprint hash algorithm requested", __func__);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Reads a multiple-precision integer in decimal from the buffer, and advances
|
||||
* the pointer. The integer must already be initialized. This function is
|
||||
* permitted to modify the buffer. This leaves *cpp to point just beyond the
|
||||
* last processed (and maybe modified) character. Note that this may modify
|
||||
* the buffer containing the number.
|
||||
*/
|
||||
static int
|
||||
diff --git a/openssh-6.5p1/key.h b/openssh-6.5p1/key.h
|
||||
--- a/openssh-6.5p1/key.h
|
||||
+++ b/openssh-6.5p1/key.h
|
||||
@@ -53,16 +53,18 @@ enum fp_type {
|
||||
SSH_FP_MD5,
|
||||
SSH_FP_SHA256
|
||||
};
|
||||
enum fp_rep {
|
||||
SSH_FP_HEX,
|
||||
SSH_FP_BUBBLEBABBLE,
|
||||
SSH_FP_RANDOMART
|
||||
};
|
||||
+#define SSH_FP_TYPE_ENVVAR "SSH_FINGERPRINT_TYPE"
|
||||
+#define SSH_FP_TYPE_STRLEN 8
|
||||
|
||||
/* key is stored in external hardware */
|
||||
#define KEY_FLAG_EXT 0x0001
|
||||
|
||||
#define CERT_MAX_PRINCIPALS 256
|
||||
struct KeyCert {
|
||||
Buffer certblob; /* Kept around for use on wire */
|
||||
u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
|
||||
@@ -104,16 +106,18 @@ int key_equal_public(const Key *, cons
|
||||
int key_equal(const Key *, const Key *);
|
||||
char *key_fingerprint(const Key *, enum fp_type, enum fp_rep);
|
||||
u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
|
||||
const char *key_type(const Key *);
|
||||
const char *key_cert_type(const Key *);
|
||||
int key_write(const Key *, FILE *);
|
||||
int key_read(Key *, char **);
|
||||
u_int key_size(const Key *);
|
||||
+enum fp_type key_fp_type_select(void);
|
||||
+char *key_fp_type_str(enum fp_type);
|
||||
|
||||
Key *key_generate(int, u_int);
|
||||
Key *key_from_private(const Key *);
|
||||
int key_type_from_name(char *);
|
||||
int key_is_cert(const Key *);
|
||||
int key_type_is_cert(int);
|
||||
int key_type_plain(int);
|
||||
int key_to_certified(Key *, int);
|
||||
diff --git a/openssh-6.5p1/ssh-add.c b/openssh-6.5p1/ssh-add.c
|
||||
--- a/openssh-6.5p1/ssh-add.c
|
||||
+++ b/openssh-6.5p1/ssh-add.c
|
||||
@@ -325,17 +325,17 @@ list_identities(AuthenticationConnection
|
||||
int version;
|
||||
|
||||
for (version = 1; version <= 2; version++) {
|
||||
for (key = ssh_get_first_identity(ac, &comment, version);
|
||||
key != NULL;
|
||||
key = ssh_get_next_identity(ac, &comment, version)) {
|
||||
had_identities = 1;
|
||||
if (do_fp) {
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5,
|
||||
+ fp = key_fingerprint(key, key_fp_type_select(),
|
||||
SSH_FP_HEX);
|
||||
printf("%d %s %s (%s)\n",
|
||||
key_size(key), fp, comment, key_type(key));
|
||||
free(fp);
|
||||
} else {
|
||||
if (!key_write(key, stdout))
|
||||
fprintf(stderr, "key_write failed");
|
||||
fprintf(stdout, " %s\n", comment);
|
||||
diff --git a/openssh-6.5p1/ssh-agent.c b/openssh-6.5p1/ssh-agent.c
|
||||
--- a/openssh-6.5p1/ssh-agent.c
|
||||
+++ b/openssh-6.5p1/ssh-agent.c
|
||||
@@ -193,17 +193,17 @@ lookup_identity(Key *key, int version)
|
||||
|
||||
/* Check confirmation of keysign request */
|
||||
static int
|
||||
confirm_key(Identity *id)
|
||||
{
|
||||
char *p;
|
||||
int ret = -1;
|
||||
|
||||
- p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ p = key_fingerprint(id->key, key_fp_type_select(), SSH_FP_HEX);
|
||||
if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
|
||||
id->comment, p))
|
||||
ret = 0;
|
||||
free(p);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
diff --git a/openssh-6.5p1/ssh-keygen.c b/openssh-6.5p1/ssh-keygen.c
|
||||
--- a/openssh-6.5p1/ssh-keygen.c
|
||||
+++ b/openssh-6.5p1/ssh-keygen.c
|
||||
@@ -741,27 +741,27 @@ do_download(struct passwd *pw)
|
||||
{
|
||||
#ifdef ENABLE_PKCS11
|
||||
Key **keys = NULL;
|
||||
int i, nkeys;
|
||||
enum fp_rep rep;
|
||||
enum fp_type fptype;
|
||||
char *fp, *ra;
|
||||
|
||||
- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fp_type_select();
|
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
|
||||
|
||||
pkcs11_init(0);
|
||||
nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys);
|
||||
if (nkeys <= 0)
|
||||
fatal("cannot read public key from pkcs11");
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if (print_fingerprint) {
|
||||
fp = key_fingerprint(keys[i], fptype, rep);
|
||||
- ra = key_fingerprint(keys[i], SSH_FP_MD5,
|
||||
+ ra = key_fingerprint(keys[i], key_fp_type_select(),
|
||||
SSH_FP_RANDOMART);
|
||||
printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]),
|
||||
fp, key_type(keys[i]));
|
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE)
|
||||
printf("%s\n", ra);
|
||||
free(ra);
|
||||
free(fp);
|
||||
} else {
|
||||
@@ -784,29 +784,29 @@ do_fingerprint(struct passwd *pw)
|
||||
FILE *f;
|
||||
Key *public;
|
||||
char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
|
||||
int i, skip = 0, num = 0, invalid = 1;
|
||||
enum fp_rep rep;
|
||||
enum fp_type fptype;
|
||||
struct stat st;
|
||||
|
||||
- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fp_type_select();
|
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
|
||||
|
||||
if (!have_identity)
|
||||
ask_filename(pw, "Enter file in which the key is");
|
||||
if (stat(identity_file, &st) < 0) {
|
||||
perror(identity_file);
|
||||
exit(1);
|
||||
}
|
||||
public = key_load_public(identity_file, &comment);
|
||||
if (public != NULL) {
|
||||
fp = key_fingerprint(public, fptype, rep);
|
||||
- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
|
||||
+ ra = key_fingerprint(public, key_fp_type_select(), SSH_FP_RANDOMART);
|
||||
printf("%u %s %s (%s)\n", key_size(public), fp, comment,
|
||||
key_type(public));
|
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE)
|
||||
printf("%s\n", ra);
|
||||
key_free(public);
|
||||
free(comment);
|
||||
free(ra);
|
||||
free(fp);
|
||||
@@ -862,17 +862,17 @@ do_fingerprint(struct passwd *pw)
|
||||
public = key_new(KEY_UNSPEC);
|
||||
if (key_read(public, &cp) != 1) {
|
||||
key_free(public);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
comment = *cp ? cp : comment;
|
||||
fp = key_fingerprint(public, fptype, rep);
|
||||
- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
|
||||
+ ra = key_fingerprint(public, key_fp_type_select(), SSH_FP_RANDOMART);
|
||||
printf("%u %s %s (%s)\n", key_size(public), fp,
|
||||
comment ? comment : "no comment", key_type(public));
|
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE)
|
||||
printf("%s\n", ra);
|
||||
free(ra);
|
||||
free(fp);
|
||||
key_free(public);
|
||||
invalid = 0;
|
||||
@@ -983,20 +983,20 @@ do_gen_all_hostkeys(struct passwd *pw)
|
||||
static void
|
||||
printhost(FILE *f, const char *name, Key *public, int ca, int hash)
|
||||
{
|
||||
if (print_fingerprint) {
|
||||
enum fp_rep rep;
|
||||
enum fp_type fptype;
|
||||
char *fp, *ra;
|
||||
|
||||
- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fp_type_select();
|
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
|
||||
fp = key_fingerprint(public, fptype, rep);
|
||||
- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
|
||||
+ ra = key_fingerprint(public, key_fp_type_select(), SSH_FP_RANDOMART);
|
||||
printf("%u %s %s (%s)\n", key_size(public), fp, name,
|
||||
key_type(public));
|
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE)
|
||||
printf("%s\n", ra);
|
||||
free(ra);
|
||||
free(fp);
|
||||
} else {
|
||||
if (hash && (name = host_hash(name, NULL, 0)) == NULL)
|
||||
@@ -1873,19 +1873,19 @@ do_show_cert(struct passwd *pw)
|
||||
if (stat(identity_file, &st) < 0)
|
||||
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
|
||||
if ((key = key_load_public(identity_file, NULL)) == NULL)
|
||||
fatal("%s is not a public key", identity_file);
|
||||
if (!key_is_cert(key))
|
||||
fatal("%s is not a certificate", identity_file);
|
||||
v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
|
||||
|
||||
- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ key_fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
||||
ca_fp = key_fingerprint(key->cert->signature_key,
|
||||
- SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ key_fp_type_select(), SSH_FP_HEX);
|
||||
|
||||
printf("%s:\n", identity_file);
|
||||
printf(" Type: %s %s certificate\n", key_ssh_name(key),
|
||||
key_cert_type(key));
|
||||
printf(" Public key: %s %s\n", key_type(key), key_fp);
|
||||
printf(" Signing CA: %s %s\n",
|
||||
key_type(key->cert->signature_key), ca_fp);
|
||||
printf(" Key ID: \"%s\"\n", key->cert->key_id);
|
||||
@@ -2681,18 +2681,18 @@ passphrase_again:
|
||||
exit(1);
|
||||
}
|
||||
if (!key_write(public, f))
|
||||
fprintf(stderr, "write key failed\n");
|
||||
fprintf(f, " %s\n", comment);
|
||||
fclose(f);
|
||||
|
||||
if (!quiet) {
|
||||
- char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- char *ra = key_fingerprint(public, SSH_FP_MD5,
|
||||
+ char *fp = key_fingerprint(public, key_fp_type_select(), SSH_FP_HEX);
|
||||
+ char *ra = key_fingerprint(public, key_fp_type_select(),
|
||||
SSH_FP_RANDOMART);
|
||||
printf("Your public key has been saved in %s.\n",
|
||||
identity_file);
|
||||
printf("The key fingerprint is:\n");
|
||||
printf("%s %s\n", fp, comment);
|
||||
printf("The key's randomart image is:\n");
|
||||
printf("%s\n", ra);
|
||||
free(ra);
|
||||
diff --git a/openssh-6.5p1/sshconnect.c b/openssh-6.5p1/sshconnect.c
|
||||
--- a/openssh-6.5p1/sshconnect.c
|
||||
+++ b/openssh-6.5p1/sshconnect.c
|
||||
@@ -906,18 +906,18 @@ check_host_key(char *hostname, struct so
|
||||
"address '%.128s' to the list of known "
|
||||
"hosts (%.30s).", type, ip,
|
||||
user_hostfiles[0]);
|
||||
else
|
||||
logit("Warning: Permanently added the %s host "
|
||||
"key for IP address '%.128s' to the list "
|
||||
"of known hosts.", type, ip);
|
||||
} else if (options.visual_host_key) {
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- ra = key_fingerprint(host_key, SSH_FP_MD5,
|
||||
+ fp = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_HEX);
|
||||
+ ra = key_fingerprint(host_key, key_fp_type_select(),
|
||||
SSH_FP_RANDOMART);
|
||||
logit("Host key fingerprint is %s\n%s\n", fp, ra);
|
||||
free(ra);
|
||||
free(fp);
|
||||
}
|
||||
break;
|
||||
case HOST_NEW:
|
||||
if (options.host_key_alias == NULL && port != 0 &&
|
||||
@@ -947,18 +947,18 @@ check_host_key(char *hostname, struct so
|
||||
|
||||
if (show_other_keys(host_hostkeys, host_key))
|
||||
snprintf(msg1, sizeof(msg1),
|
||||
"\nbut keys of different type are already"
|
||||
" known for this host.");
|
||||
else
|
||||
snprintf(msg1, sizeof(msg1), ".");
|
||||
/* The default */
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- ra = key_fingerprint(host_key, SSH_FP_MD5,
|
||||
+ fp = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_HEX);
|
||||
+ ra = key_fingerprint(host_key, key_fp_type_select(),
|
||||
SSH_FP_RANDOMART);
|
||||
msg2[0] = '\0';
|
||||
if (options.verify_host_key_dns) {
|
||||
if (matching_host_key_dns)
|
||||
snprintf(msg2, sizeof(msg2),
|
||||
"Matching host key fingerprint"
|
||||
" found in DNS.\n");
|
||||
else
|
||||
@@ -1212,17 +1212,17 @@ fail:
|
||||
|
||||
/* returns 0 if key verifies or -1 if key does NOT verify */
|
||||
int
|
||||
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
|
||||
{
|
||||
int flags = 0;
|
||||
char *fp;
|
||||
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_HEX);
|
||||
debug("Server host key: %s %s", key_type(host_key), fp);
|
||||
free(fp);
|
||||
|
||||
/* XXX certs are not yet supported for DNS */
|
||||
if (!key_is_cert(host_key) && options.verify_host_key_dns &&
|
||||
verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
|
||||
if (flags & DNS_VERIFY_FOUND) {
|
||||
|
||||
@@ -1319,18 +1319,18 @@ show_other_keys(struct hostkeys *hostkey
|
||||
char *fp, *ra;
|
||||
const struct hostkey_entry *found;
|
||||
|
||||
for (i = 0; type[i] != -1; i++) {
|
||||
if (type[i] == key->type)
|
||||
continue;
|
||||
if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))
|
||||
continue;
|
||||
- fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART);
|
||||
+ fp = key_fingerprint(found->key, key_fp_type_select(), SSH_FP_HEX);
|
||||
+ ra = key_fingerprint(found->key, key_fp_type_select(), SSH_FP_RANDOMART);
|
||||
logit("WARNING: %s key found for host %s\n"
|
||||
"in %s:%lu\n"
|
||||
"%s key fingerprint %s.",
|
||||
key_type(found->key),
|
||||
found->host, found->file, found->line,
|
||||
key_type(found->key), fp);
|
||||
if (options.visual_host_key)
|
||||
logit("%s", ra);
|
||||
@@ -1341,17 +1341,17 @@ show_other_keys(struct hostkeys *hostkey
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
warn_changed_key(Key *host_key)
|
||||
{
|
||||
char *fp;
|
||||
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(host_key, key_fp_type_select(), SSH_FP_HEX);
|
||||
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
|
||||
error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
|
||||
error("It is also possible that a host key has just been changed.");
|
||||
error("The fingerprint for the %s key sent by the remote host is\n%s.",
|
||||
diff --git a/openssh-6.5p1/sshconnect2.c b/openssh-6.5p1/sshconnect2.c
|
||||
--- a/openssh-6.5p1/sshconnect2.c
|
||||
+++ b/openssh-6.5p1/sshconnect2.c
|
||||
@@ -592,17 +592,17 @@ input_userauth_pk_ok(int type, u_int32_t
|
||||
goto done;
|
||||
}
|
||||
if (key->type != pktype) {
|
||||
error("input_userauth_pk_ok: type mismatch "
|
||||
"for decoded key (received %d, expected %d)",
|
||||
key->type, pktype);
|
||||
goto done;
|
||||
}
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(key, key_fp_type_select(), SSH_FP_HEX);
|
||||
debug2("input_userauth_pk_ok: fp %s", fp);
|
||||
free(fp);
|
||||
|
||||
/*
|
||||
* search keys in the reverse order, because last candidate has been
|
||||
* moved to the end of the queue. this also avoids confusion by
|
||||
* duplicate keys
|
||||
*/
|
||||
@@ -1206,17 +1206,17 @@ sign_and_send_pubkey(Authctxt *authctxt,
|
||||
Buffer b;
|
||||
u_char *blob, *signature;
|
||||
u_int bloblen, slen;
|
||||
u_int skip = 0;
|
||||
int ret = -1;
|
||||
int have_sig = 1;
|
||||
char *fp;
|
||||
|
||||
- fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(id->key, key_fp_type_select(), SSH_FP_HEX);
|
||||
debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp);
|
||||
free(fp);
|
||||
|
||||
if (key_to_blob(id->key, &blob, &bloblen) == 0) {
|
||||
/* we cannot handle this key */
|
||||
debug3("sign_and_send_pubkey: cannot handle key");
|
||||
return 0;
|
||||
}
|
1186
openssh-6.5p1-fips.patch
Normal file
1186
openssh-6.5p1-fips.patch
Normal file
File diff suppressed because it is too large
Load Diff
3890
openssh-6.5p1-gssapi_key_exchange.patch
Normal file
3890
openssh-6.5p1-gssapi_key_exchange.patch
Normal file
File diff suppressed because it is too large
Load Diff
431
openssh-6.5p1-gssapimitm.patch
Normal file
431
openssh-6.5p1-gssapimitm.patch
Normal file
@ -0,0 +1,431 @@
|
||||
# The patch below adds support for the deprecated 'gssapi' authentication
|
||||
# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
|
||||
# in this release. The use of 'gssapi' is deprecated due to the presence of
|
||||
# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not
|
||||
# susceptible to.
|
||||
#
|
||||
# To use the patch apply it to a OpenSSH 3.8p1 source tree. After compiling,
|
||||
# backwards compatibility may be obtained by supplying the
|
||||
# 'GssapiEnableMitmAttack yes' option to either the client or server.
|
||||
#
|
||||
# It should be noted that this patch is being made available purely as a means
|
||||
# of easing the process of moving to OpenSSH 3.8p1. Any new installations are
|
||||
# recommended to use the 'gssapi-with-mic' mechanism. Existing installations
|
||||
# are encouraged to upgrade as soon as possible.
|
||||
|
||||
diff --git a/openssh-6.5p1/auth2-gss.c b/openssh-6.5p1/auth2-gss.c
|
||||
--- a/openssh-6.5p1/auth2-gss.c
|
||||
+++ b/openssh-6.5p1/auth2-gss.c
|
||||
@@ -173,16 +173,25 @@ input_gssapi_token(int type, u_int32_t p
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
if (flags & GSS_C_INTEG_FLAG)
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
|
||||
&input_gssapi_mic);
|
||||
else
|
||||
dispatch_set(
|
||||
SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
|
||||
&input_gssapi_exchange_complete);
|
||||
+
|
||||
+ /*
|
||||
+ * Old style 'gssapi' didn't have the GSSAPI_MIC
|
||||
+ * and went straight to sending exchange_complete
|
||||
+ */
|
||||
+ if (options.gss_enable_mitm)
|
||||
+ dispatch_set(
|
||||
+ SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
|
||||
+ &input_gssapi_exchange_complete);
|
||||
}
|
||||
}
|
||||
|
||||
gss_release_buffer(&min_status, &send_tok);
|
||||
}
|
||||
|
||||
static void
|
||||
input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
|
||||
@@ -291,9 +300,15 @@ input_gssapi_mic(int type, u_int32_t ple
|
||||
}
|
||||
|
||||
Authmethod method_gssapi = {
|
||||
"gssapi-with-mic",
|
||||
userauth_gssapi,
|
||||
&options.gss_authentication
|
||||
};
|
||||
|
||||
+Authmethod method_gssapi_old = {
|
||||
+ "gssapi",
|
||||
+ userauth_gssapi,
|
||||
+ &options.gss_enable_mitm
|
||||
+};
|
||||
+
|
||||
#endif /* GSSAPI */
|
||||
diff --git a/openssh-6.5p1/auth2.c b/openssh-6.5p1/auth2.c
|
||||
--- a/openssh-6.5p1/auth2.c
|
||||
+++ b/openssh-6.5p1/auth2.c
|
||||
@@ -65,26 +65,28 @@ extern Buffer loginmsg;
|
||||
|
||||
extern Authmethod method_none;
|
||||
extern Authmethod method_pubkey;
|
||||
extern Authmethod method_passwd;
|
||||
extern Authmethod method_kbdint;
|
||||
extern Authmethod method_hostbased;
|
||||
#ifdef GSSAPI
|
||||
extern Authmethod method_gssapi;
|
||||
+extern Authmethod method_gssapi_old;
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
extern Authmethod method_jpake;
|
||||
#endif
|
||||
|
||||
Authmethod *authmethods[] = {
|
||||
&method_none,
|
||||
&method_pubkey,
|
||||
#ifdef GSSAPI
|
||||
&method_gssapi,
|
||||
+ &method_gssapi_old,
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
&method_jpake,
|
||||
#endif
|
||||
&method_passwd,
|
||||
&method_kbdint,
|
||||
&method_hostbased,
|
||||
NULL
|
||||
diff --git a/openssh-6.5p1/readconf.c b/openssh-6.5p1/readconf.c
|
||||
--- a/openssh-6.5p1/readconf.c
|
||||
+++ b/openssh-6.5p1/readconf.c
|
||||
@@ -134,17 +134,17 @@ typedef enum {
|
||||
oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
|
||||
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
|
||||
oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
|
||||
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
|
||||
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
|
||||
oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
|
||||
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
|
||||
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
|
||||
- oAddressFamily, oGssAuthentication, oGssDelegateCreds,
|
||||
+ oAddressFamily, oGssAuthentication, oGssDelegateCreds, oGssEnableMITM,
|
||||
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
|
||||
oSendEnv, oControlPath, oControlMaster, oControlPersist,
|
||||
oHashKnownHosts,
|
||||
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
|
||||
oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
|
||||
oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
|
||||
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
|
||||
oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
|
||||
@@ -178,19 +178,21 @@ static struct {
|
||||
{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
|
||||
{ "tisauthentication", oChallengeResponseAuthentication }, /* alias */
|
||||
{ "kerberosauthentication", oUnsupported },
|
||||
{ "kerberostgtpassing", oUnsupported },
|
||||
{ "afstokenpassing", oUnsupported },
|
||||
#if defined(GSSAPI)
|
||||
{ "gssapiauthentication", oGssAuthentication },
|
||||
{ "gssapidelegatecredentials", oGssDelegateCreds },
|
||||
+ { "gssapienablemitmattack", oGssEnableMITM },
|
||||
#else
|
||||
{ "gssapiauthentication", oUnsupported },
|
||||
{ "gssapidelegatecredentials", oUnsupported },
|
||||
+ { "gssapienablemitmattack", oUnsupported },
|
||||
#endif
|
||||
{ "fallbacktorsh", oDeprecated },
|
||||
{ "usersh", oDeprecated },
|
||||
{ "identityfile", oIdentityFile },
|
||||
{ "identityfile2", oIdentityFile }, /* obsolete */
|
||||
{ "identitiesonly", oIdentitiesOnly },
|
||||
{ "hostname", oHostName },
|
||||
{ "hostkeyalias", oHostKeyAlias },
|
||||
@@ -837,16 +839,20 @@ parse_time:
|
||||
|
||||
case oGssAuthentication:
|
||||
intptr = &options->gss_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oGssDelegateCreds:
|
||||
intptr = &options->gss_deleg_creds;
|
||||
goto parse_flag;
|
||||
+
|
||||
+ case oGssEnableMITM:
|
||||
+ intptr = &options->gss_enable_mitm;
|
||||
+ goto parse_flag;
|
||||
|
||||
case oBatchMode:
|
||||
intptr = &options->batch_mode;
|
||||
goto parse_flag;
|
||||
|
||||
case oCheckHostIP:
|
||||
intptr = &options->check_host_ip;
|
||||
goto parse_flag;
|
||||
@@ -1484,16 +1490,17 @@ initialize_options(Options * options)
|
||||
options->xauth_location = NULL;
|
||||
options->gateway_ports = -1;
|
||||
options->use_privileged_port = -1;
|
||||
options->rsa_authentication = -1;
|
||||
options->pubkey_authentication = -1;
|
||||
options->challenge_response_authentication = -1;
|
||||
options->gss_authentication = -1;
|
||||
options->gss_deleg_creds = -1;
|
||||
+ options->gss_enable_mitm = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->kbd_interactive_devices = NULL;
|
||||
options->rhosts_rsa_authentication = -1;
|
||||
options->hostbased_authentication = -1;
|
||||
options->batch_mode = -1;
|
||||
options->check_host_ip = -1;
|
||||
options->strict_host_key_checking = -1;
|
||||
@@ -1591,16 +1598,18 @@ fill_default_options(Options * options)
|
||||
if (options->pubkey_authentication == -1)
|
||||
options->pubkey_authentication = 1;
|
||||
if (options->challenge_response_authentication == -1)
|
||||
options->challenge_response_authentication = 1;
|
||||
if (options->gss_authentication == -1)
|
||||
options->gss_authentication = 0;
|
||||
if (options->gss_deleg_creds == -1)
|
||||
options->gss_deleg_creds = 0;
|
||||
+ if (options->gss_enable_mitm == -1)
|
||||
+ options->gss_enable_mitm = 0;
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
options->kbd_interactive_authentication = 1;
|
||||
if (options->rhosts_rsa_authentication == -1)
|
||||
options->rhosts_rsa_authentication = 0;
|
||||
if (options->hostbased_authentication == -1)
|
||||
options->hostbased_authentication = 0;
|
||||
diff --git a/openssh-6.5p1/readconf.h b/openssh-6.5p1/readconf.h
|
||||
--- a/openssh-6.5p1/readconf.h
|
||||
+++ b/openssh-6.5p1/readconf.h
|
||||
@@ -50,16 +50,17 @@ typedef struct {
|
||||
* authentication. */
|
||||
int rsa_authentication; /* Try RSA authentication. */
|
||||
int pubkey_authentication; /* Try ssh2 pubkey authentication. */
|
||||
int hostbased_authentication; /* ssh2's rhosts_rsa */
|
||||
int challenge_response_authentication;
|
||||
/* Try S/Key or TIS, authentication. */
|
||||
int gss_authentication; /* Try GSS authentication */
|
||||
int gss_deleg_creds; /* Delegate GSS credentials */
|
||||
+ int gss_enable_mitm; /* Enable old style gssapi auth */
|
||||
int password_authentication; /* Try password
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
|
||||
char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
|
||||
int zero_knowledge_password_authentication; /* Try jpake */
|
||||
int batch_mode; /* Batch mode: do not ask for passwords. */
|
||||
int check_host_ip; /* Also keep track of keys for IP address */
|
||||
int strict_host_key_checking; /* Strict host key checking. */
|
||||
diff --git a/openssh-6.5p1/servconf.c b/openssh-6.5p1/servconf.c
|
||||
--- a/openssh-6.5p1/servconf.c
|
||||
+++ b/openssh-6.5p1/servconf.c
|
||||
@@ -104,16 +104,17 @@ initialize_server_options(ServerOptions
|
||||
options->rsa_authentication = -1;
|
||||
options->pubkey_authentication = -1;
|
||||
options->kerberos_authentication = -1;
|
||||
options->kerberos_or_local_passwd = -1;
|
||||
options->kerberos_ticket_cleanup = -1;
|
||||
options->kerberos_get_afs_token = -1;
|
||||
options->gss_authentication=-1;
|
||||
options->gss_cleanup_creds = -1;
|
||||
+ options->gss_enable_mitm = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->challenge_response_authentication = -1;
|
||||
options->permit_empty_passwd = -1;
|
||||
options->permit_user_env = -1;
|
||||
options->use_login = -1;
|
||||
options->compression = -1;
|
||||
options->rekey_limit = -1;
|
||||
@@ -242,16 +243,18 @@ fill_default_server_options(ServerOption
|
||||
if (options->kerberos_ticket_cleanup == -1)
|
||||
options->kerberos_ticket_cleanup = 1;
|
||||
if (options->kerberos_get_afs_token == -1)
|
||||
options->kerberos_get_afs_token = 0;
|
||||
if (options->gss_authentication == -1)
|
||||
options->gss_authentication = 0;
|
||||
if (options->gss_cleanup_creds == -1)
|
||||
options->gss_cleanup_creds = 1;
|
||||
+ if (options->gss_enable_mitm == -1)
|
||||
+ options->gss_enable_mitm = 0;
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
options->kbd_interactive_authentication = 0;
|
||||
if (options->challenge_response_authentication == -1)
|
||||
options->challenge_response_authentication = 1;
|
||||
if (options->permit_empty_passwd == -1)
|
||||
options->permit_empty_passwd = 0;
|
||||
@@ -338,17 +341,17 @@ typedef enum {
|
||||
sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
|
||||
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
|
||||
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
|
||||
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
|
||||
sMaxStartups, sMaxAuthTries, sMaxSessions,
|
||||
sBanner, sUseDNS, sHostbasedAuthentication,
|
||||
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
|
||||
sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
- sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
|
||||
+ sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sGssEnableMITM,
|
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
sZeroKnowledgePasswordAuthentication, sHostCertificate,
|
||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||
sKexAlgorithms, sIPQoS, sVersionAddendum,
|
||||
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
|
||||
sAuthenticationMethods, sHostKeyAgent,
|
||||
sDeprecated, sUnsupported
|
||||
@@ -405,19 +408,21 @@ static struct {
|
||||
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
#ifdef GSSAPI
|
||||
{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
|
||||
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
|
||||
+ { "gssapienablemitmattack", sGssEnableMITM },
|
||||
#else
|
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "gssapienablemitmattack", sUnsupported },
|
||||
#endif
|
||||
{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
|
||||
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
|
||||
{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
|
||||
{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
|
||||
#ifdef JPAKE
|
||||
{ "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
|
||||
#else
|
||||
@@ -1093,16 +1098,20 @@ process_server_config_line(ServerOptions
|
||||
case sGssAuthentication:
|
||||
intptr = &options->gss_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case sGssCleanupCreds:
|
||||
intptr = &options->gss_cleanup_creds;
|
||||
goto parse_flag;
|
||||
|
||||
+ case sGssEnableMITM:
|
||||
+ intptr = &options->gss_enable_mitm;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sPasswordAuthentication:
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case sZeroKnowledgePasswordAuthentication:
|
||||
intptr = &options->zero_knowledge_password_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
diff --git a/openssh-6.5p1/servconf.h b/openssh-6.5p1/servconf.h
|
||||
--- a/openssh-6.5p1/servconf.h
|
||||
+++ b/openssh-6.5p1/servconf.h
|
||||
@@ -108,16 +108,17 @@ typedef struct {
|
||||
* such as SecurID or
|
||||
* /etc/passwd */
|
||||
int kerberos_ticket_cleanup; /* If true, destroy ticket
|
||||
* file on logout. */
|
||||
int kerberos_get_afs_token; /* If true, try to get AFS token if
|
||||
* authenticated with Kerberos. */
|
||||
int gss_authentication; /* If true, permit GSSAPI authentication */
|
||||
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
|
||||
+ int gss_enable_mitm; /* If true, enable old style GSSAPI */
|
||||
int password_authentication; /* If true, permit password
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* If true, permit */
|
||||
int challenge_response_authentication;
|
||||
int zero_knowledge_password_authentication;
|
||||
/* If true, permit jpake auth */
|
||||
int permit_empty_passwd; /* If false, do not permit empty
|
||||
* passwords. */
|
||||
diff --git a/openssh-6.5p1/ssh_config b/openssh-6.5p1/ssh_config
|
||||
--- a/openssh-6.5p1/ssh_config
|
||||
+++ b/openssh-6.5p1/ssh_config
|
||||
@@ -51,9 +51,16 @@ ForwardX11Trusted yes
|
||||
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
|
||||
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
|
||||
# EscapeChar ~
|
||||
# Tunnel no
|
||||
# TunnelDevice any:any
|
||||
# PermitLocalCommand no
|
||||
# VisualHostKey no
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
+
|
||||
+# Set this to 'yes' to enable support for the deprecated 'gssapi' authentication
|
||||
+# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
|
||||
+# in this release. The use of 'gssapi' is deprecated due to the presence of
|
||||
+# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not susceptible to.
|
||||
+# GSSAPIEnableMITMAttack no
|
||||
+
|
||||
# RekeyLimit 1G 1h
|
||||
diff --git a/openssh-6.5p1/sshconnect2.c b/openssh-6.5p1/sshconnect2.c
|
||||
--- a/openssh-6.5p1/sshconnect2.c
|
||||
+++ b/openssh-6.5p1/sshconnect2.c
|
||||
@@ -324,16 +324,21 @@ static char *authmethods_get(void);
|
||||
|
||||
Authmethod authmethods[] = {
|
||||
#ifdef GSSAPI
|
||||
{"gssapi-with-mic",
|
||||
userauth_gssapi,
|
||||
NULL,
|
||||
&options.gss_authentication,
|
||||
NULL},
|
||||
+ {"gssapi",
|
||||
+ userauth_gssapi,
|
||||
+ NULL,
|
||||
+ &options.gss_enable_mitm,
|
||||
+ NULL},
|
||||
#endif
|
||||
{"hostbased",
|
||||
userauth_hostbased,
|
||||
NULL,
|
||||
&options.hostbased_authentication,
|
||||
NULL},
|
||||
{"publickey",
|
||||
userauth_pubkey,
|
||||
@@ -698,17 +703,19 @@ process_gssapi_token(void *ctxt, gss_buf
|
||||
|
||||
packet_put_string(send_tok.value, send_tok.length);
|
||||
packet_send();
|
||||
gss_release_buffer(&ms, &send_tok);
|
||||
}
|
||||
|
||||
if (status == GSS_S_COMPLETE) {
|
||||
/* send either complete or MIC, depending on mechanism */
|
||||
- if (!(flags & GSS_C_INTEG_FLAG)) {
|
||||
+
|
||||
+ if (strcmp(authctxt->method->name,"gssapi") == 0 ||
|
||||
+ (!(flags & GSS_C_INTEG_FLAG))) {
|
||||
packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
|
||||
packet_send();
|
||||
} else {
|
||||
ssh_gssapi_buildmic(&b, authctxt->server_user,
|
||||
authctxt->service, "gssapi-with-mic");
|
||||
|
||||
gssbuf.value = buffer_ptr(&b);
|
||||
gssbuf.length = buffer_len(&b);
|
||||
diff --git a/openssh-6.5p1/sshd_config b/openssh-6.5p1/sshd_config
|
||||
--- a/openssh-6.5p1/sshd_config
|
||||
+++ b/openssh-6.5p1/sshd_config
|
||||
@@ -80,16 +80,23 @@ PasswordAuthentication no
|
||||
#KerberosOrLocalPasswd yes
|
||||
#KerberosTicketCleanup yes
|
||||
#KerberosGetAFSToken no
|
||||
|
||||
# GSSAPI options
|
||||
#GSSAPIAuthentication no
|
||||
#GSSAPICleanupCredentials yes
|
||||
|
||||
+# Set this to 'yes' to enable support for the deprecated 'gssapi' authentication
|
||||
+# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
|
||||
+# in this release. The use of 'gssapi' is deprecated due to the presence of
|
||||
+# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not susceptible to.
|
||||
+#GSSAPIEnableMITMAttack no
|
||||
+
|
||||
+
|
||||
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||
# and session processing. If this is enabled, PAM authentication will
|
||||
# be allowed through the ChallengeResponseAuthentication and
|
||||
# PasswordAuthentication. Depending on your PAM configuration,
|
||||
# PAM authentication via ChallengeResponseAuthentication may bypass
|
||||
# the setting of "PermitRootLogin without-password".
|
||||
# If you just want the PAM account and session checks to run without
|
||||
# PAM authentication, then enable this but set PasswordAuthentication
|
28
openssh-6.5p1-host_ident.patch
Normal file
28
openssh-6.5p1-host_ident.patch
Normal file
@ -0,0 +1,28 @@
|
||||
# identify hashed hosts in known_hosts and suggest command line for their
|
||||
# removal
|
||||
|
||||
diff --git a/openssh-6.5p1/sshconnect.c b/openssh-6.5p1/sshconnect.c
|
||||
--- a/openssh-6.5p1/sshconnect.c
|
||||
+++ b/openssh-6.5p1/sshconnect.c
|
||||
@@ -1067,16 +1067,21 @@ check_host_key(char *hostname, struct so
|
||||
ip_found->file, ip_found->line);
|
||||
}
|
||||
/* The host key has changed. */
|
||||
warn_changed_key(host_key);
|
||||
error("Add correct host key in %.100s to get rid of this message.",
|
||||
user_hostfiles[0]);
|
||||
error("Offending %s key in %s:%lu", key_type(host_found->key),
|
||||
host_found->file, host_found->line);
|
||||
+ error("You can use following command to remove all keys for this IP:");
|
||||
+ if (host_found->file)
|
||||
+ error("ssh-keygen -R %s -f %s", hostname, host_found->file);
|
||||
+ else
|
||||
+ error("ssh-keygen -R %s", hostname);
|
||||
|
||||
/*
|
||||
* If strict host key checking is in use, the user will have
|
||||
* to edit the key manually and we can only abort.
|
||||
*/
|
||||
if (options.strict_host_key_checking) {
|
||||
error("%s host key for %.200s has changed and you have "
|
||||
"requested strict checking.", type, host);
|
534
openssh-6.5p1-key-converter.patch
Normal file
534
openssh-6.5p1-key-converter.patch
Normal file
@ -0,0 +1,534 @@
|
||||
# SSHv1 to SSHv2 RSA keys converter
|
||||
|
||||
diff --git a/openssh-6.5p1/converter/Makefile b/openssh-6.5p1/converter/Makefile
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/openssh-6.5p1/converter/Makefile
|
||||
@@ -0,0 +1,17 @@
|
||||
+
|
||||
+bindir=/usr/bin
|
||||
+mandir=/usr/share/man
|
||||
+
|
||||
+all : ssh-keyconverter
|
||||
+
|
||||
+ssh-keyconverter.o: ssh-keyconverter.c ../key.h ../authfile.h ../misc.h ../xmalloc.h
|
||||
+ gcc $(RPM_OPT_FLAGS) -c -I../ $< -o $@
|
||||
+
|
||||
+ssh-keyconverter: ssh-keyconverter.o ../libssh.a ../openbsd-compat/libopenbsd-compat.a
|
||||
+ gcc $< -Wl,--no-as-needed $(RPM_OPT_FLAGS) -L../ -L../openbsd-compat/ -lcrypto -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lpam -ldl -lwrap -lutil -lz -lnsl -lcrypt -lssl -o $@
|
||||
+
|
||||
+install: ssh-keyconverter ssh-keyconverter.1
|
||||
+ if [ ! -d $(DESTDIR)$(bindir) ]; then install -d -m 755 $(DESTDIR)$(bindir); fi
|
||||
+ install -m 755 ssh-keyconverter $(DESTDIR)$(bindir)
|
||||
+ if [ ! -d $(DESTDIR)$(mandir)/man1 ]; then install -d -m 755 $(DESTDIR)$(mandir)/man1; fi
|
||||
+ install -m 644 ssh-keyconverter.1 $(DESTDIR)$(mandir)/man1
|
||||
diff --git a/openssh-6.5p1/converter/ssh-keyconverter.1 b/openssh-6.5p1/converter/ssh-keyconverter.1
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/openssh-6.5p1/converter/ssh-keyconverter.1
|
||||
@@ -0,0 +1,155 @@
|
||||
+.\" Manpage for ssh-keyconverter
|
||||
+.\"
|
||||
+.Dd February 2, 2002
|
||||
+.Dt SSH-KEYCONVER 1
|
||||
+.Os
|
||||
+.Sh NAME
|
||||
+.Nm ssh-keyconvert
|
||||
+.Nd convert ssh v1 keys and authorization files
|
||||
+.Sh SYNOPSIS
|
||||
+.Nm ssh-keyconvert
|
||||
+.Op Fl k
|
||||
+.Op Fl o Ar output_file
|
||||
+.Ar identity_file ...
|
||||
+.Nm ssh-keyconvert
|
||||
+.Op Fl a
|
||||
+.Op Fl o Ar output_file
|
||||
+.Ar authorization_file ...
|
||||
+.Sh DESCRIPTION
|
||||
+.Nm
|
||||
+converts RSA public and private keys used for public key based
|
||||
+user authentication with protocol version 1 to the format
|
||||
+used with protocol version 2.
|
||||
+.Pp
|
||||
+When using RSA user authentication with SSH protocol version 1,
|
||||
+the client uses the private key from
|
||||
+.Pa $HOME/.ssh/identity
|
||||
+to provide its identity to the server. The server grants or denies
|
||||
+access based on whether the public part of this key is listed in
|
||||
+.Pa $HOME/.ssh/authorized_keys .
|
||||
+.Pp
|
||||
+SSH protocol version 2 supports both DSA and RSA keys, but the
|
||||
+way RSA keys are stored are differently. On the client, the default
|
||||
+file name is
|
||||
+.Pa .ssh/id_rsa
|
||||
+rather than
|
||||
+.Pa .ssh/identity ,
|
||||
+and the file's format is different as well. On the server, the
|
||||
+public porting of the key can still be stored in
|
||||
+.Pa .ssh/authorized_keys ,
|
||||
+but the key notation has changed as well.
|
||||
+Therefore, when switching from protocol version 1
|
||||
+to version 2, you either have to create a new identity key using
|
||||
+.Xr ssh-keygen 1
|
||||
+and add that key to the server's
|
||||
+.Pa authorized_keys
|
||||
+file, or you need to convert your keys using
|
||||
+.Nm ssh-keyconvert .
|
||||
+.Pp
|
||||
+By default,
|
||||
+.Nm
|
||||
+will try to guess the type of file that is to be converted.
|
||||
+If it fails to guess correctly, you can tell if what type of
|
||||
+conversion to perform by specifying the
|
||||
+.Fl k
|
||||
+option to convert the private key, or the
|
||||
+.Fl a
|
||||
+option to convert an authorisation file.
|
||||
+.Pp
|
||||
+When converting your private keys stored in
|
||||
+.Pa .ssh/identity ,
|
||||
+.Nm
|
||||
+will read the private key, prompting you for the pass phrase
|
||||
+if the key is protected by a pass phrase. If the
|
||||
+.Fl o
|
||||
+option is given, it will write the private key to the specified
|
||||
+file, using version 2 syntax. If the key was protected by a
|
||||
+pass phrase, it will use the same pass phrase to protect the new
|
||||
+file.
|
||||
+It will also write the public portion of the key to a second file,
|
||||
+using the specified file name with
|
||||
+.Dq .pub
|
||||
+appended.
|
||||
+If the
|
||||
+.Fl o
|
||||
+option was not given, private and public key will be written to
|
||||
+.Pa id_rsa
|
||||
+and
|
||||
+.Pa id_rsa.pub ,
|
||||
+respectively, relative to the directory of the input key file.
|
||||
+.Pp
|
||||
+If the destination file already exists,
|
||||
+.Nm
|
||||
+will prompt the user for confirmation before overwriting the
|
||||
+file, unless the
|
||||
+.Fl f
|
||||
+option is given.
|
||||
+.Pp
|
||||
+When converting your
|
||||
+.Pa authorized_keys
|
||||
+file,
|
||||
+.Nm
|
||||
+will ignore any keys in SSH version 2 format. Any public keys
|
||||
+in version 1 format will be converted and appended to the output file
|
||||
+using the new syntax. If the
|
||||
+.Fl o
|
||||
+option is given, keys are appended to the specified file. If it
|
||||
+is not given,
|
||||
+.Nm
|
||||
+will append all keys to the input file.
|
||||
+.Pp
|
||||
+Note that
|
||||
+.Nm
|
||||
+does not check for duplicate keys, so if you run it on
|
||||
+.Pa .ssh/authorized_keys
|
||||
+more several times, the converted keys will show up several times.
|
||||
+.Sh OPTIONS
|
||||
+.Bl -tag -width Ds
|
||||
+.It Fl k
|
||||
+Convert private key file(s). The default is to guess the
|
||||
+type of file that should be converted.
|
||||
+.It Fl a
|
||||
+Convert
|
||||
+.Pa authorized_keys
|
||||
+file(s). The default is to guess the
|
||||
+type of file that should be converted.
|
||||
+.It Fl o Ar outfile
|
||||
+Specify the name of the output file.
|
||||
+When converting an authorization file, all public keys will
|
||||
+be appended to this file.
|
||||
+For private key conversion, the private and public components of
|
||||
+the key will be stored in
|
||||
+.Pa outfile
|
||||
+and
|
||||
+.Pa outfile.pub ,
|
||||
+respectively.
|
||||
+Note that since every key must be stored in a separate file, you
|
||||
+cannot use this option when you specify several input files.
|
||||
+.It Fl f
|
||||
+When converting a key file, and the output file already exists,
|
||||
+.Nm
|
||||
+will ask the user whether to overwrite the file. Using this option
|
||||
+forces overwriting.
|
||||
+.El
|
||||
+.Sh AUTHORS
|
||||
+OpenSSH is a derivative of the original and free
|
||||
+ssh 1.2.12 release by Tatu Ylonen.
|
||||
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
+Theo de Raadt and Dug Song
|
||||
+removed many bugs, re-added newer features and
|
||||
+created OpenSSH.
|
||||
+.Nm
|
||||
+was contributed by Olaf Kirch.
|
||||
+.Sh SEE ALSO
|
||||
+.Xr ssh 1 ,
|
||||
+.Xr ssh-add 1 ,
|
||||
+.Xr ssh-agent 1 ,
|
||||
+.Xr sshd 8
|
||||
+.Rs
|
||||
+.%A J. Galbraith
|
||||
+.%A R. Thayer
|
||||
+.%T "SECSH Public Key File Format"
|
||||
+.%N draft-ietf-secsh-publickeyfile-01.txt
|
||||
+.%D March 2001
|
||||
+.%O work in progress material
|
||||
+.Re
|
||||
diff --git a/openssh-6.5p1/converter/ssh-keyconverter.c b/openssh-6.5p1/converter/ssh-keyconverter.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/openssh-6.5p1/converter/ssh-keyconverter.c
|
||||
@@ -0,0 +1,345 @@
|
||||
+/*
|
||||
+ * SSH v1 to v2 RSA key converter.
|
||||
+ *
|
||||
+ * Instead of a manpage:
|
||||
+ *
|
||||
+ * ssh-keyconverter ~/.ssh/identity
|
||||
+ * will put the old RSA key in ~/.ssh/id_rsa and id_rsa.pub
|
||||
+ * If a "-o foofah" is given, the keys will be written to
|
||||
+ * foofah and foofah.pub, respectively.
|
||||
+ *
|
||||
+ * ssh-keyconverter ~/.ssh/authorized_keys
|
||||
+ * will convert all old RSA keys and add them to the
|
||||
+ * input file. The -o foofah option will direct
|
||||
+ * output to a different file.
|
||||
+ * (Note that it's harmless to specify the same file
|
||||
+ * as input and output, as ssh-keyconverter will ignore
|
||||
+ * any v2 keys, and output is always appended, never
|
||||
+ * replacing the original file).
|
||||
+ *
|
||||
+ * To compile:
|
||||
+ *
|
||||
+ * gcc -g -Wall -o ssh-keyconverter converter.c \
|
||||
+ * -L. -Lopenbsd-compat/ -lssh -lopenbsd-compat -lssh \
|
||||
+ * -lpam -ldl -lwrap -lutil -lz -lnsl \
|
||||
+ * -Wl,-Bstatic -lcrypto -Wl,-dy
|
||||
+ *
|
||||
+ * Enjoy. --okir
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <getopt.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/param.h>
|
||||
+#include <unistd.h>
|
||||
+#include "key.h"
|
||||
+#include "authfile.h"
|
||||
+#include "misc.h"
|
||||
+#include "xmalloc.h"
|
||||
+
|
||||
+#define TYPE_KEY 0
|
||||
+#define TYPE_AUTHKEYS 1
|
||||
+
|
||||
+#define PASSPHRASE_ATTEMPTS 3
|
||||
+
|
||||
+static int opt_verbose = 0;
|
||||
+static int opt_force = 0;
|
||||
+
|
||||
+static void convert(int, const char *, const char *);
|
||||
+static void convert_private_key(const char *, const char *);
|
||||
+static void convert_authorized_keys(const char *, const char *);
|
||||
+static int fileok(const char *, char *, size_t);
|
||||
+static int guess_type(const char *);
|
||||
+
|
||||
+int
|
||||
+main(int argc, char **argv)
|
||||
+{
|
||||
+ int opt_type = -1;
|
||||
+ char *opt_outfile = NULL;
|
||||
+ int c;
|
||||
+
|
||||
+ while ((c = getopt(argc, argv, "afko:")) != -1) {
|
||||
+ switch (c) {
|
||||
+ case 'a':
|
||||
+ opt_type = TYPE_AUTHKEYS;
|
||||
+ break;
|
||||
+ case 'f':
|
||||
+ opt_force = 1;
|
||||
+ break;
|
||||
+ case 'k':
|
||||
+ opt_type = TYPE_KEY;
|
||||
+ break;
|
||||
+ case 'o':
|
||||
+ opt_outfile = optarg;
|
||||
+ break;
|
||||
+ case 'v':
|
||||
+ opt_verbose++;
|
||||
+ break;
|
||||
+ default:
|
||||
+ fprintf(stderr,
|
||||
+ "usage: ssh-keyconvert [-a | -k] "
|
||||
+ "[-o filename] [-v] ...\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Warning, nanny code follows */
|
||||
+#if 0
|
||||
+ if (opt_outfile && (argc - optind) > 1 && opt_type != TYPE_AUTHKEY) {
|
||||
+ fprintf(stderr,
|
||||
+ "Output file ambiguous: more than two "
|
||||
+ "input files given. Abort.\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ if (optind == argc) {
|
||||
+ fprintf(stderr,
|
||||
+ "Missing input file(s).\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ for (; optind < argc; optind++) {
|
||||
+ char *name = argv[optind];
|
||||
+ int type;
|
||||
+
|
||||
+ if ((type = opt_type) < 0)
|
||||
+ type = guess_type(name);
|
||||
+ convert(type, name, opt_outfile);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+convert(int type, const char *iname, const char *oname)
|
||||
+{
|
||||
+ if (type == TYPE_KEY) {
|
||||
+ convert_private_key(iname, oname);
|
||||
+ } else if (type == TYPE_AUTHKEYS) {
|
||||
+ convert_authorized_keys(iname, oname);
|
||||
+ } else {
|
||||
+ fprintf(stderr,
|
||||
+ "Conversion type not yet implemented.\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+convert_private_key(const char *iname, const char *oname)
|
||||
+{
|
||||
+ char prompt[1024], privname[PATH_MAX], pubname[PATH_MAX];
|
||||
+ char *comment = NULL, *passphrase;
|
||||
+ Key *key = NULL, *pk = NULL;
|
||||
+ int i;
|
||||
+ FILE *pf = NULL;
|
||||
+
|
||||
+ passphrase = xstrdup("");
|
||||
+ snprintf(prompt, sizeof(prompt),
|
||||
+ "Enter passphrase for key '%.100s': ",iname);
|
||||
+ for (i = 0; !key && i < PASSPHRASE_ATTEMPTS; i++) {
|
||||
+ if (i) {
|
||||
+ /* Zap old pass phrase */
|
||||
+ memset(passphrase, 0, strlen(passphrase));
|
||||
+ free(passphrase);
|
||||
+
|
||||
+ /* Get a pass phrase from the user */
|
||||
+ passphrase = read_passphrase(prompt, 0);
|
||||
+ }
|
||||
+ key = key_load_private(iname, passphrase, &comment);
|
||||
+ if (!key && i)
|
||||
+ printf("Bad passphrase, please try again.\n");
|
||||
+ }
|
||||
+
|
||||
+ if (oname != NULL) {
|
||||
+ strcpy(privname, oname);
|
||||
+ } else {
|
||||
+ const char *s;
|
||||
+
|
||||
+ if ((s = strrchr(iname, '/')) != NULL) {
|
||||
+ int n = s + 1 - iname;
|
||||
+
|
||||
+ strncpy(privname, iname, n);
|
||||
+ privname[n++] = '\0';
|
||||
+ }
|
||||
+ strcat(privname, "id_rsa");
|
||||
+ }
|
||||
+
|
||||
+ if (!fileok("private", privname, sizeof(privname)))
|
||||
+ goto out;
|
||||
+
|
||||
+ sprintf(pubname, "%s.pub", privname);
|
||||
+ if (!fileok("public", pubname, sizeof(pubname)))
|
||||
+ goto out;
|
||||
+
|
||||
+ /* "convert" from RSA1 to RSA */
|
||||
+ key->type = KEY_RSA;
|
||||
+ pk = key_from_private(key);
|
||||
+
|
||||
+ /* Now write the key in earnest */
|
||||
+ if (!key_save_private(key, privname, passphrase, comment)) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to save private key to %s: %m.\n", privname);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!(pf = fopen(pubname, "w"))) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to save public key to %s: %m.\n", pubname);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (!key_write(pk, pf)) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to save public key to %s: %m.\n", pubname);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (comment)
|
||||
+ fprintf(pf, " %s\n", comment);
|
||||
+
|
||||
+out:
|
||||
+ memset(passphrase, 0, strlen(passphrase));
|
||||
+ free(passphrase);
|
||||
+ if (key)
|
||||
+ key_free(key);
|
||||
+ if (pk)
|
||||
+ key_free(pk);
|
||||
+ if (pf)
|
||||
+ fclose(pf);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+convert_authorized_keys(const char *iname, const char *oname)
|
||||
+{
|
||||
+ char line[1024];
|
||||
+ FILE *ifp, *ofp;
|
||||
+ Key *key;
|
||||
+
|
||||
+ if (!(ifp = fopen(iname, "r"))) {
|
||||
+ perror(iname);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (oname == NULL)
|
||||
+ oname = iname;
|
||||
+
|
||||
+ if (!strcmp(oname, "-")) {
|
||||
+ ofp = stdout;
|
||||
+ } else {
|
||||
+ if ((ofp = fopen(oname, "a")) == NULL) {
|
||||
+ perror(oname);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
+ setlinebuf(ofp);
|
||||
+
|
||||
+#define whitespace(c) ((c) == ' ' || (c) == '\t')
|
||||
+ while (fgets(line, sizeof(line), ifp) != NULL) {
|
||||
+ char *cp = line, *options = NULL;
|
||||
+
|
||||
+ while (whitespace(*cp))
|
||||
+ cp++;
|
||||
+ if (!*cp || *cp == '\n' || *cp == '#')
|
||||
+ continue;
|
||||
+
|
||||
+ key = key_new(KEY_RSA1);
|
||||
+ if (key_read(key, &cp) != 1) {
|
||||
+ /* Skip options, if any */
|
||||
+ int quoted = 0;
|
||||
+
|
||||
+ options = cp;
|
||||
+ for (; *cp && (quoted || !whitespace(*cp)); cp++) {
|
||||
+ if (cp[0] == '\\' && cp[1] == '"')
|
||||
+ ++cp;
|
||||
+ else if (*cp == '"')
|
||||
+ quoted = !quoted;
|
||||
+ }
|
||||
+ if (quoted)
|
||||
+ goto next;
|
||||
+ *cp++ = '\0';
|
||||
+ while (whitespace(*cp))
|
||||
+ cp++;
|
||||
+ if (key_read(key, &cp) != 1)
|
||||
+ goto next;
|
||||
+ }
|
||||
+
|
||||
+ if (options)
|
||||
+ fprintf(ofp, "%s ", options);
|
||||
+ /* "convert" from RSA1 to RSA */
|
||||
+ key->type = KEY_RSA;
|
||||
+ key_write(key, ofp);
|
||||
+ fputs(cp, ofp);
|
||||
+ key_free(key);
|
||||
+
|
||||
+ next:
|
||||
+ ;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* if file exists, ask user whether to overwrite it */
|
||||
+static int
|
||||
+fileok(const char *what, char *filename, size_t size)
|
||||
+{
|
||||
+ char buffer[PATH_MAX];
|
||||
+ int n;
|
||||
+
|
||||
+checkagain:
|
||||
+ if (access(filename, F_OK) < 0)
|
||||
+ return 1;
|
||||
+ printf("%s key file %s already exists.\n", what, filename);
|
||||
+ if (opt_force) {
|
||||
+ printf("Overwriting because of -f option...\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+tryagain:
|
||||
+ printf("Please enter a different filename, "
|
||||
+ "or return to overwrite: ");
|
||||
+ fflush(stdout);
|
||||
+
|
||||
+ n = read(0, buffer, sizeof(buffer)-1);
|
||||
+ if (n <= 0)
|
||||
+ printf("\n");
|
||||
+ if (n < 0) {
|
||||
+ perror("read failed");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ if (n == 0) {
|
||||
+ fprintf(stderr, "EOF from standard input. Bye.\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ buffer[n] = '\0';
|
||||
+ while (n && buffer[n-1] == '\n')
|
||||
+ buffer[--n] = '\0';
|
||||
+ if (n == 0)
|
||||
+ return 1;
|
||||
+ if (n >= size) {
|
||||
+ fprintf(stderr, "Filename too long.\n");
|
||||
+ goto tryagain;
|
||||
+ }
|
||||
+ strcpy(filename, buffer);
|
||||
+ goto checkagain;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Guess the type of file to be converted.
|
||||
+ * XXX: should look at the file; v1 key files
|
||||
+ * start with "SSH PRIVATE KEY FILE"
|
||||
+ */
|
||||
+static int
|
||||
+guess_type(const char *name)
|
||||
+{
|
||||
+ printf("%s... ", name);
|
||||
+ if (strstr(name, "identity")) {
|
||||
+ printf("looks like a key file\n");
|
||||
+ return TYPE_KEY;
|
||||
+ }
|
||||
+ if (strstr(name, "authorized_keys")) {
|
||||
+ printf("looks like an authorized_keys file\n");
|
||||
+ return TYPE_AUTHKEYS;
|
||||
+ }
|
||||
+
|
||||
+ if (opt_verbose)
|
||||
+ printf("unable to identify.");
|
||||
+ fprintf(stderr, "Please specify the file type for %s. Abort.\n", name);
|
||||
+ exit(1);
|
||||
+}
|
24
openssh-6.5p1-lastlog.patch
Normal file
24
openssh-6.5p1-lastlog.patch
Normal file
@ -0,0 +1,24 @@
|
||||
# set uid for functions that use it to seek in lastlog and wtmp files
|
||||
# bnc#18024 (was suse #3024)
|
||||
|
||||
diff --git a/openssh-6.5p1/sshlogin.c b/openssh-6.5p1/sshlogin.c
|
||||
--- a/openssh-6.5p1/sshlogin.c
|
||||
+++ b/openssh-6.5p1/sshlogin.c
|
||||
@@ -128,16 +128,17 @@ record_login(pid_t pid, const char *tty,
|
||||
{
|
||||
struct logininfo *li;
|
||||
|
||||
/* save previous login details before writing new */
|
||||
store_lastlog_message(user, uid);
|
||||
|
||||
li = login_alloc_entry(pid, user, host, tty);
|
||||
login_set_addr(li, addr, addrlen);
|
||||
+ li->uid = uid;
|
||||
login_login(li);
|
||||
login_free_entry(li);
|
||||
}
|
||||
|
||||
#ifdef LOGIN_NEEDS_UTMPX
|
||||
void
|
||||
record_utmp_only(pid_t pid, const char *ttyname, const char *user,
|
||||
const char *host, struct sockaddr *addr, socklen_t addrlen)
|
2805
openssh-6.5p1-ldap.patch
Normal file
2805
openssh-6.5p1-ldap.patch
Normal file
File diff suppressed because it is too large
Load Diff
28
openssh-6.5p1-login_options.patch
Normal file
28
openssh-6.5p1-login_options.patch
Normal file
@ -0,0 +1,28 @@
|
||||
# login-pam cannot handle the option terminator "--" as login from util-linux
|
||||
# (this is correct behaviour considering its man-page), hence use option which
|
||||
# selects the compile-time branch in the code which doesn't use the terminator
|
||||
#
|
||||
# bnc#833605
|
||||
|
||||
diff --git a/openssh-6.5p1/configure.ac b/openssh-6.5p1/configure.ac
|
||||
--- a/openssh-6.5p1/configure.ac
|
||||
+++ b/openssh-6.5p1/configure.ac
|
||||
@@ -695,16 +695,18 @@ main() { if (NSVersionOfRunTimeLibrary("
|
||||
AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
|
||||
AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins])
|
||||
;;
|
||||
*-*-linux*)
|
||||
no_dev_ptmx=1
|
||||
use_pie=auto
|
||||
check_for_libcrypt_later=1
|
||||
check_for_openpty_ctty_bug=1
|
||||
+ AC_DEFINE([LOGIN_NO_ENDOPT], [1],
|
||||
+ [Define if your login program cannot handle end of options ("--")])
|
||||
AC_DEFINE([PAM_TTY_KLUDGE], [1],
|
||||
[Work around problematic Linux PAM modules handling of PAM_TTY])
|
||||
AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"],
|
||||
[String used in /etc/passwd to denote locked account])
|
||||
AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV])
|
||||
AC_DEFINE([LINK_OPNOTSUPP_ERRNO], [EPERM],
|
||||
[Define to whatever link() returns for "not supported"
|
||||
if it doesn't return EOPNOTSUPP.])
|
24
openssh-6.5p1-no_fork-no_pid_file.patch
Normal file
24
openssh-6.5p1-no_fork-no_pid_file.patch
Normal file
@ -0,0 +1,24 @@
|
||||
# Do not write a PID file when not daemonizing (e.g. when running from systemd)
|
||||
|
||||
diff --git a/openssh-6.5p1/sshd.c b/openssh-6.5p1/sshd.c
|
||||
--- a/openssh-6.5p1/sshd.c
|
||||
+++ b/openssh-6.5p1/sshd.c
|
||||
@@ -1973,17 +1973,17 @@ main(int ac, char **av)
|
||||
signal(SIGCHLD, main_sigchld_handler);
|
||||
signal(SIGTERM, sigterm_handler);
|
||||
signal(SIGQUIT, sigterm_handler);
|
||||
|
||||
/*
|
||||
* Write out the pid file after the sigterm handler
|
||||
* is setup and the listen sockets are bound
|
||||
*/
|
||||
- if (!debug_flag) {
|
||||
+ if (!(debug_flag || no_daemon_flag)) {
|
||||
FILE *f = fopen(options.pid_file, "w");
|
||||
|
||||
if (f == NULL) {
|
||||
error("Couldn't create pid file \"%s\": %s",
|
||||
options.pid_file, strerror(errno));
|
||||
} else {
|
||||
fprintf(f, "%ld\n", (long) getpid());
|
||||
fclose(f);
|
226
openssh-6.5p1-pam-check-locks.patch
Normal file
226
openssh-6.5p1-pam-check-locks.patch
Normal file
@ -0,0 +1,226 @@
|
||||
# new option UsePAMCheckLocks to enforce checking for locked accounts while
|
||||
# UsePAM is used
|
||||
# bnc#708678, FATE#312033
|
||||
|
||||
diff --git a/openssh-6.5p1/auth.c b/openssh-6.5p1/auth.c
|
||||
--- a/openssh-6.5p1/auth.c
|
||||
+++ b/openssh-6.5p1/auth.c
|
||||
@@ -103,17 +103,17 @@ allowed_user(struct passwd * pw)
|
||||
struct spwd *spw = NULL;
|
||||
#endif
|
||||
|
||||
/* Shouldn't be called if pw is NULL, but better safe than sorry... */
|
||||
if (!pw || !pw->pw_name)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_SHADOW
|
||||
- if (!options.use_pam)
|
||||
+ if (!options.use_pam || options.use_pam_check_locks)
|
||||
spw = getspnam(pw->pw_name);
|
||||
#ifdef HAS_SHADOW_EXPIRE
|
||||
if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw))
|
||||
return 0;
|
||||
#endif /* HAS_SHADOW_EXPIRE */
|
||||
#endif /* USE_SHADOW */
|
||||
|
||||
/* grab passwd field for locked account check */
|
||||
@@ -123,17 +123,17 @@ allowed_user(struct passwd * pw)
|
||||
#ifdef USE_LIBIAF
|
||||
passwd = get_iaf_password(pw);
|
||||
#else
|
||||
passwd = spw->sp_pwdp;
|
||||
#endif /* USE_LIBIAF */
|
||||
#endif
|
||||
|
||||
/* check for locked account */
|
||||
- if (!options.use_pam && passwd && *passwd) {
|
||||
+ if ((!options.use_pam || options.use_pam_check_locks) && passwd && *passwd) {
|
||||
int locked = 0;
|
||||
|
||||
#ifdef LOCKED_PASSWD_STRING
|
||||
if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
|
||||
locked = 1;
|
||||
#endif
|
||||
#ifdef LOCKED_PASSWD_PREFIX
|
||||
if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
|
||||
diff --git a/openssh-6.5p1/servconf.c b/openssh-6.5p1/servconf.c
|
||||
--- a/openssh-6.5p1/servconf.c
|
||||
+++ b/openssh-6.5p1/servconf.c
|
||||
@@ -66,16 +66,17 @@ extern Buffer cfg;
|
||||
|
||||
void
|
||||
initialize_server_options(ServerOptions *options)
|
||||
{
|
||||
memset(options, 0, sizeof(*options));
|
||||
|
||||
/* Portable-specific options */
|
||||
options->use_pam = -1;
|
||||
+ options->use_pam_check_locks = -1;
|
||||
|
||||
/* Standard Options */
|
||||
options->num_ports = 0;
|
||||
options->ports_from_cmdline = 0;
|
||||
options->listen_addrs = NULL;
|
||||
options->address_family = -1;
|
||||
options->num_host_key_files = 0;
|
||||
options->num_host_cert_files = 0;
|
||||
@@ -158,16 +159,18 @@ initialize_server_options(ServerOptions
|
||||
}
|
||||
|
||||
void
|
||||
fill_default_server_options(ServerOptions *options)
|
||||
{
|
||||
/* Portable-specific options */
|
||||
if (options->use_pam == -1)
|
||||
options->use_pam = 0;
|
||||
+ if (options->use_pam_check_locks == -1)
|
||||
+ options->use_pam_check_locks = 0;
|
||||
|
||||
/* Standard Options */
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_2;
|
||||
if (options->num_host_key_files == 0) {
|
||||
/* fill default hostkeys for protocols */
|
||||
if (options->protocol & SSH_PROTO_1)
|
||||
options->host_key_files[options->num_host_key_files++] =
|
||||
@@ -320,17 +323,17 @@ fill_default_server_options(ServerOption
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Keyword tokens. */
|
||||
typedef enum {
|
||||
sBadOption, /* == unknown option */
|
||||
/* Portable-specific options */
|
||||
- sUsePAM,
|
||||
+ sUsePAM, sUsePAMChecklocks,
|
||||
/* Standard Options */
|
||||
sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
|
||||
sPermitRootLogin, sLogFacility, sLogLevel,
|
||||
sRhostsRSAAuthentication, sRSAAuthentication,
|
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
|
||||
sKerberosGetAFSToken,
|
||||
sKerberosTgtPassing, sChallengeResponseAuthentication,
|
||||
sPasswordAuthentication, sKbdInteractiveAuthentication,
|
||||
@@ -365,18 +368,20 @@ typedef enum {
|
||||
static struct {
|
||||
const char *name;
|
||||
ServerOpCodes opcode;
|
||||
u_int flags;
|
||||
} keywords[] = {
|
||||
/* Portable-specific options */
|
||||
#ifdef USE_PAM
|
||||
{ "usepam", sUsePAM, SSHCFG_GLOBAL },
|
||||
+ { "usepamchecklocks", sUsePAMChecklocks, SSHCFG_GLOBAL },
|
||||
#else
|
||||
{ "usepam", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "usepamchecklocks", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
|
||||
/* Standard Options */
|
||||
{ "port", sPort, SSHCFG_GLOBAL },
|
||||
{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
|
||||
{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
|
||||
{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
|
||||
{ "pidfile", sPidFile, SSHCFG_GLOBAL },
|
||||
@@ -878,16 +883,19 @@ process_server_config_line(ServerOptions
|
||||
}
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
/* Portable-specific options */
|
||||
case sUsePAM:
|
||||
intptr = &options->use_pam;
|
||||
goto parse_flag;
|
||||
+ case sUsePAMChecklocks:
|
||||
+ intptr = &options->use_pam_check_locks;
|
||||
+ goto parse_flag;
|
||||
|
||||
/* Standard Options */
|
||||
case sBadOption:
|
||||
return -1;
|
||||
case sPort:
|
||||
/* ignore ports from configfile if cmdline specifies ports */
|
||||
if (options->ports_from_cmdline)
|
||||
return 0;
|
||||
diff --git a/openssh-6.5p1/servconf.h b/openssh-6.5p1/servconf.h
|
||||
--- a/openssh-6.5p1/servconf.h
|
||||
+++ b/openssh-6.5p1/servconf.h
|
||||
@@ -162,16 +162,17 @@ typedef struct {
|
||||
*/
|
||||
|
||||
u_int num_authkeys_files; /* Files containing public keys */
|
||||
char *authorized_keys_files[MAX_AUTHKEYS_FILES];
|
||||
|
||||
char *adm_forced_command;
|
||||
|
||||
int use_pam; /* Enable auth via PAM */
|
||||
+ int use_pam_check_locks; /* internally check for locked accounts even when using PAM */
|
||||
|
||||
int permit_tun;
|
||||
|
||||
int num_permitted_opens;
|
||||
|
||||
char *chroot_directory;
|
||||
char *revoked_keys_file;
|
||||
char *trusted_user_ca_keys;
|
||||
diff --git a/openssh-6.5p1/sshd_config.0 b/openssh-6.5p1/sshd_config.0
|
||||
--- a/openssh-6.5p1/sshd_config.0
|
||||
+++ b/openssh-6.5p1/sshd_config.0
|
||||
@@ -720,16 +720,24 @@ DESCRIPTION
|
||||
|
||||
Because PAM challenge-response authentication usually serves an
|
||||
equivalent role to password authentication, you should disable
|
||||
either PasswordAuthentication or ChallengeResponseAuthentication.
|
||||
|
||||
If UsePAM is enabled, you will not be able to run sshd(8) as a
|
||||
non-root user. The default is ``no''.
|
||||
|
||||
+ UsePAMCheckLocks
|
||||
+ When set to ``yes'', the checks whether the account has been
|
||||
+ locked with `passwd -l' are performed even when PAM authentication
|
||||
+ is enabled via UsePAM. This is to ensure that it is not possible
|
||||
+ to log in with e.g. a public key (in such a case PAM is used only
|
||||
+ to set up the session and some PAM modules will not check whether
|
||||
+ the account is locked in this scenario). The default is ``no''.
|
||||
+
|
||||
UsePrivilegeSeparation
|
||||
Specifies whether sshd(8) separates privileges by creating an
|
||||
unprivileged child process to deal with incoming network traffic.
|
||||
After successful authentication, another process will be created
|
||||
that has the privilege of the authenticated user. The goal of
|
||||
privilege separation is to prevent privilege escalation by
|
||||
containing any corruption within the unprivileged processes. The
|
||||
default is ``yes''. If UsePrivilegeSeparation is set to
|
||||
diff --git a/openssh-6.5p1/sshd_config.5 b/openssh-6.5p1/sshd_config.5
|
||||
--- a/openssh-6.5p1/sshd_config.5
|
||||
+++ b/openssh-6.5p1/sshd_config.5
|
||||
@@ -1199,16 +1199,28 @@ or
|
||||
.Pp
|
||||
If
|
||||
.Cm UsePAM
|
||||
is enabled, you will not be able to run
|
||||
.Xr sshd 8
|
||||
as a non-root user.
|
||||
The default is
|
||||
.Dq no .
|
||||
+.It Cm UsePAMCheckLocks
|
||||
+When set to
|
||||
+.Dq yes
|
||||
+, the checks whether the account has been locked with
|
||||
+.Pa passwd -l
|
||||
+are performed even when PAM authentication is enabled via
|
||||
+.Cm UsePAM .
|
||||
+This is to ensure that it is not possible to log in with e.g. a
|
||||
+public key (in such a case PAM is used only to set up the session and some PAM
|
||||
+modules will not check whether the account is locked in this scenario). The
|
||||
+default is
|
||||
+.Dq no .
|
||||
.It Cm UsePrivilegeSeparation
|
||||
Specifies whether
|
||||
.Xr sshd 8
|
||||
separates privileges by creating an unprivileged child process
|
||||
to deal with incoming network traffic.
|
||||
After successful authentication, another process will be created that has
|
||||
the privilege of the authenticated user.
|
||||
The goal of privilege separation is to prevent privilege
|
44
openssh-6.5p1-pam-fix2.patch
Normal file
44
openssh-6.5p1-pam-fix2.patch
Normal file
@ -0,0 +1,44 @@
|
||||
# force PAM in defaullt install (this was removed from upstream in 3.8p1)
|
||||
# bnc#46749
|
||||
|
||||
diff --git a/openssh-6.5p1/sshd_config b/openssh-6.5p1/sshd_config
|
||||
--- a/openssh-6.5p1/sshd_config
|
||||
+++ b/openssh-6.5p1/sshd_config
|
||||
@@ -64,17 +64,17 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
#HostbasedAuthentication no
|
||||
# Change to yes if you don't trust ~/.ssh/known_hosts for
|
||||
# RhostsRSAAuthentication and HostbasedAuthentication
|
||||
#IgnoreUserKnownHosts no
|
||||
# Don't read the user's ~/.rhosts and ~/.shosts files
|
||||
#IgnoreRhosts yes
|
||||
|
||||
# To disable tunneled clear text passwords, change to no here!
|
||||
-#PasswordAuthentication yes
|
||||
+PasswordAuthentication no
|
||||
#PermitEmptyPasswords no
|
||||
|
||||
# Change to no to disable s/key passwords
|
||||
#ChallengeResponseAuthentication yes
|
||||
|
||||
# Kerberos options
|
||||
#KerberosAuthentication no
|
||||
#KerberosOrLocalPasswd yes
|
||||
@@ -89,17 +89,17 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
# and session processing. If this is enabled, PAM authentication will
|
||||
# be allowed through the ChallengeResponseAuthentication and
|
||||
# PasswordAuthentication. Depending on your PAM configuration,
|
||||
# PAM authentication via ChallengeResponseAuthentication may bypass
|
||||
# the setting of "PermitRootLogin without-password".
|
||||
# If you just want the PAM account and session checks to run without
|
||||
# PAM authentication, then enable this but set PasswordAuthentication
|
||||
# and ChallengeResponseAuthentication to 'no'.
|
||||
-#UsePAM no
|
||||
+UsePAM yes
|
||||
|
||||
#AllowAgentForwarding yes
|
||||
#AllowTcpForwarding yes
|
||||
#GatewayPorts no
|
||||
X11Forwarding yes
|
||||
#X11DisplayOffset 10
|
||||
#X11UseLocalhost yes
|
||||
#PermitTTY yes
|
26
openssh-6.5p1-pam-fix3.patch
Normal file
26
openssh-6.5p1-pam-fix3.patch
Normal file
@ -0,0 +1,26 @@
|
||||
# posix threads are generally not supported nor safe
|
||||
# (see upstream log from 2005-05-24)
|
||||
|
||||
diff --git a/openssh-6.5p1/auth-pam.c b/openssh-6.5p1/auth-pam.c
|
||||
--- a/openssh-6.5p1/auth-pam.c
|
||||
+++ b/openssh-6.5p1/auth-pam.c
|
||||
@@ -781,17 +781,19 @@ sshpam_query(void *ctx, char **name, cha
|
||||
}
|
||||
if (type == PAM_SUCCESS) {
|
||||
if (!sshpam_authctxt->valid ||
|
||||
(sshpam_authctxt->pw->pw_uid == 0 &&
|
||||
options.permit_root_login != PERMIT_YES))
|
||||
fatal("Internal error: PAM auth "
|
||||
"succeeded when it should have "
|
||||
"failed");
|
||||
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
|
||||
import_environments(&buffer);
|
||||
+#endif
|
||||
*num = 0;
|
||||
**echo_on = 0;
|
||||
ctxt->pam_done = 1;
|
||||
free(msg);
|
||||
return (0);
|
||||
}
|
||||
error("PAM: %s for %s%.100s from %.100s", msg,
|
||||
sshpam_authctxt->valid ? "" : "illegal user ",
|
46
openssh-6.5p1-pts.patch
Normal file
46
openssh-6.5p1-pts.patch
Normal file
@ -0,0 +1,46 @@
|
||||
# use same lines naming as utempter (prevents problems with using different
|
||||
# formats in ?tmp? files)
|
||||
|
||||
diff --git a/openssh-6.5p1/loginrec.c b/openssh-6.5p1/loginrec.c
|
||||
--- a/openssh-6.5p1/loginrec.c
|
||||
+++ b/openssh-6.5p1/loginrec.c
|
||||
@@ -538,17 +538,17 @@ getlast_entry(struct logininfo *li)
|
||||
/*
|
||||
* 'line' string utility functions
|
||||
*
|
||||
* These functions process the 'line' string into one of three forms:
|
||||
*
|
||||
* 1. The full filename (including '/dev')
|
||||
* 2. The stripped name (excluding '/dev')
|
||||
* 3. The abbreviated name (e.g. /dev/ttyp00 -> yp00
|
||||
- * /dev/pts/1 -> ts/1 )
|
||||
+ * /dev/pts/1 -> /1 )
|
||||
*
|
||||
* Form 3 is used on some systems to identify a .tmp.? entry when
|
||||
* attempting to remove it. Typically both addition and removal is
|
||||
* performed by one application - say, sshd - so as long as the choice
|
||||
* uniquely identifies a terminal it's ok.
|
||||
*/
|
||||
|
||||
|
||||
@@ -599,16 +599,20 @@ line_abbrevname(char *dst, const char *s
|
||||
/* Always skip prefix if present */
|
||||
if (strncmp(src, "/dev/", 5) == 0)
|
||||
src += 5;
|
||||
|
||||
#ifdef WITH_ABBREV_NO_TTY
|
||||
if (strncmp(src, "tty", 3) == 0)
|
||||
src += 3;
|
||||
#endif
|
||||
+ if (strncmp(src, "pts/", 4) == 0) {
|
||||
+ src += 3;
|
||||
+ if (strlen(src) > 4) src++;
|
||||
+ }
|
||||
|
||||
len = strlen(src);
|
||||
|
||||
if (len > 0) {
|
||||
if (((int)len - dstsize) > 0)
|
||||
src += ((int)len - dstsize);
|
||||
|
||||
/* note: _don't_ change this to strlcpy */
|
28
openssh-6.5p1-saveargv-fix.patch
Normal file
28
openssh-6.5p1-saveargv-fix.patch
Normal file
@ -0,0 +1,28 @@
|
||||
# related to bnc#49845, upstream bug #529
|
||||
|
||||
diff --git a/openssh-6.5p1/sshd.c b/openssh-6.5p1/sshd.c
|
||||
--- a/openssh-6.5p1/sshd.c
|
||||
+++ b/openssh-6.5p1/sshd.c
|
||||
@@ -1399,17 +1399,21 @@ main(int ac, char **av)
|
||||
saved_argv = xcalloc(ac + 1, sizeof(*saved_argv));
|
||||
for (i = 0; i < ac; i++)
|
||||
saved_argv[i] = xstrdup(av[i]);
|
||||
saved_argv[i] = NULL;
|
||||
|
||||
#ifndef HAVE_SETPROCTITLE
|
||||
/* Prepare for later setproctitle emulation */
|
||||
compat_init_setproctitle(ac, av);
|
||||
- av = saved_argv;
|
||||
+
|
||||
+ av = xmalloc(sizeof(*saved_argv) * (saved_argc + 1));
|
||||
+ for (i = 0; i < saved_argc; i++)
|
||||
+ av[i] = xstrdup(saved_argv[i]);
|
||||
+ av[i] = NULL;
|
||||
#endif
|
||||
|
||||
if (geteuid() == 0 && setgroups(0, NULL) == -1)
|
||||
debug("setgroups(): %.200s", strerror(errno));
|
||||
|
||||
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
||||
sanitise_stdfd();
|
||||
|
542
openssh-6.5p1-seed-prng.patch
Normal file
542
openssh-6.5p1-seed-prng.patch
Normal file
@ -0,0 +1,542 @@
|
||||
# extended support for (re-)seeding the OpenSSL PRNG from /dev/random
|
||||
# bnc#703221, FATE#312172
|
||||
|
||||
diff --git a/openssh-6.5p1/audit-bsm.c b/openssh-6.5p1/audit-bsm.c
|
||||
--- a/openssh-6.5p1/audit-bsm.c
|
||||
+++ b/openssh-6.5p1/audit-bsm.c
|
||||
@@ -504,9 +504,15 @@ audit_destroy_sensitive_data(const char
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_generate_ephemeral_server_key(const char *fp)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
+
|
||||
+void
|
||||
+audit_linux_prng_seed(long bytes, const char *rf)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
#endif /* BSM */
|
||||
diff --git a/openssh-6.5p1/audit-linux.c b/openssh-6.5p1/audit-linux.c
|
||||
--- a/openssh-6.5p1/audit-linux.c
|
||||
+++ b/openssh-6.5p1/audit-linux.c
|
||||
@@ -398,9 +398,31 @@ audit_generate_ephemeral_server_key(cons
|
||||
}
|
||||
audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
|
||||
buf, NULL, 0, NULL, 1);
|
||||
audit_close(audit_fd);
|
||||
/* do not abort if the error is EPERM and sshd is run as non root user */
|
||||
if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
|
||||
error("cannot write into audit");
|
||||
}
|
||||
+
|
||||
+void
|
||||
+audit_linux_prng_seed(long bytes, const char *rf)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, audit_ok;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=prng_seed kind=server bytes=%li source=%s ", bytes, rf);
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno != EINVAL && errno != EPROTONOSUPPORT &&
|
||||
+ errno != EAFNOSUPPORT)
|
||||
+ error("cannot open audit");
|
||||
+ return;
|
||||
+ }
|
||||
+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_PARAM_CHANGE_USER,
|
||||
+ buf, NULL, 0, NULL, 1);
|
||||
+ audit_close(audit_fd);
|
||||
+ /* do not abort if the error is EPERM and sshd is run as non root user */
|
||||
+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
|
||||
+ error("cannot write into audit");
|
||||
+}
|
||||
#endif /* USE_LINUX_AUDIT */
|
||||
diff --git a/openssh-6.5p1/audit.c b/openssh-6.5p1/audit.c
|
||||
--- a/openssh-6.5p1/audit.c
|
||||
+++ b/openssh-6.5p1/audit.c
|
||||
@@ -304,10 +304,16 @@ audit_destroy_sensitive_data(const char
|
||||
/*
|
||||
* This will be called on generation of the ephemeral server key
|
||||
*/
|
||||
void
|
||||
audit_generate_ephemeral_server_key(const char *)
|
||||
{
|
||||
debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+audit_linux_prng_seed(long bytes, const char *rf)
|
||||
+{
|
||||
+ debug("audit PRNG seed euid %d bytes %li source %s", geteuid(), bytes, rf);
|
||||
+}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/openssh-6.5p1/audit.h b/openssh-6.5p1/audit.h
|
||||
--- a/openssh-6.5p1/audit.h
|
||||
+++ b/openssh-6.5p1/audit.h
|
||||
@@ -63,10 +63,11 @@ void audit_key(int, int *, const Key *);
|
||||
void audit_unsupported(int);
|
||||
void audit_kex(int, char *, char *, char *);
|
||||
void audit_unsupported_body(int);
|
||||
void audit_kex_body(int, char *, char *, char *, pid_t, uid_t);
|
||||
void audit_session_key_free(int ctos);
|
||||
void audit_session_key_free_body(int ctos, pid_t, uid_t);
|
||||
void audit_destroy_sensitive_data(const char *, pid_t, uid_t);
|
||||
void audit_generate_ephemeral_server_key(const char *);
|
||||
+void audit_linux_prng_seed(long, const char *);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff --git a/openssh-6.5p1/entropy.c b/openssh-6.5p1/entropy.c
|
||||
--- a/openssh-6.5p1/entropy.c
|
||||
+++ b/openssh-6.5p1/entropy.c
|
||||
@@ -45,16 +45,17 @@
|
||||
|
||||
#include "ssh.h"
|
||||
#include "misc.h"
|
||||
#include "xmalloc.h"
|
||||
#include "atomicio.h"
|
||||
#include "pathnames.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
+#include "openbsd-compat/port-linux.h"
|
||||
|
||||
/*
|
||||
* Portable OpenSSH PRNG seeding:
|
||||
* If OpenSSL has not "internally seeded" itself (e.g. pulled data from
|
||||
* /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from
|
||||
* PRNGd.
|
||||
*/
|
||||
#ifndef OPENSSL_PRNG_ONLY
|
||||
@@ -229,11 +230,14 @@ seed_rng(void)
|
||||
}
|
||||
|
||||
if (seed_from_prngd(buf, sizeof(buf)) == -1)
|
||||
fatal("Could not obtain seed from PRNGd");
|
||||
RAND_add(buf, sizeof(buf), sizeof(buf));
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
|
||||
#endif /* OPENSSL_PRNG_ONLY */
|
||||
+
|
||||
+ linux_seed();
|
||||
+
|
||||
if (RAND_status() != 1)
|
||||
fatal("PRNG is not seeded");
|
||||
}
|
||||
diff --git a/openssh-6.5p1/openbsd-compat/Makefile.in b/openssh-6.5p1/openbsd-compat/Makefile.in
|
||||
--- a/openssh-6.5p1/openbsd-compat/Makefile.in
|
||||
+++ b/openssh-6.5p1/openbsd-compat/Makefile.in
|
||||
@@ -15,17 +15,17 @@ AR=@AR@
|
||||
RANLIB=@RANLIB@
|
||||
INSTALL=@INSTALL@
|
||||
LDFLAGS=-L. @LDFLAGS@
|
||||
|
||||
OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o
|
||||
|
||||
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.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-prng.o port-solaris.o port-tun.o port-uw.o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||
|
||||
all: libopenbsd-compat.a
|
||||
|
||||
$(COMPAT): ../config.h
|
||||
$(OPENBSD): ../config.h
|
||||
diff --git a/openssh-6.5p1/openbsd-compat/port-linux-prng.c b/openssh-6.5p1/openbsd-compat/port-linux-prng.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/openssh-6.5p1/openbsd-compat/port-linux-prng.c
|
||||
@@ -0,0 +1,79 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2011 Jan F. Chadima <jchadima@redhat.com>
|
||||
+ * (c) 2011 Petr Cerny <pcerny@suse.cz>
|
||||
+ *
|
||||
+ * 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 "defines.h"
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+#include <openssl/rand.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+#include "port-linux.h"
|
||||
+#include "audit.h"
|
||||
+
|
||||
+#define RNG_BYTES_DEFAULT 6L
|
||||
+#define RNG_ENV_VAR "SSH_USE_STRONG_RNG"
|
||||
+
|
||||
+long rand_bytes = 0;
|
||||
+char *rand_file = NULL;
|
||||
+
|
||||
+static void
|
||||
+linux_seed_init(void)
|
||||
+{
|
||||
+ long elen = 0;
|
||||
+ char *env = getenv(RNG_ENV_VAR);
|
||||
+
|
||||
+ if (env) {
|
||||
+ errno = 0;
|
||||
+ elen = strtol(env, NULL, 10);
|
||||
+ if (errno) {
|
||||
+ debug("bogus value in the %s environment variable, using default %li\n",
|
||||
+ RNG_ENV_VAR, RNG_BYTES_DEFAULT);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (elen)
|
||||
+ rand_file = "/dev/random";
|
||||
+ else
|
||||
+ rand_file = "/dev/urandom";
|
||||
+
|
||||
+ rand_bytes = MAX(elen, RNG_BYTES_DEFAULT);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+linux_seed(void)
|
||||
+{
|
||||
+ long len;
|
||||
+ if (!rand_file)
|
||||
+ linux_seed_init();
|
||||
+
|
||||
+ errno = 0;
|
||||
+ len = RAND_load_file(rand_file, rand_bytes);
|
||||
+ if (len != rand_bytes) {
|
||||
+ if (errno)
|
||||
+ fatal ("cannot read from %s, %s", random, strerror(errno));
|
||||
+ else
|
||||
+ fatal ("EOF reading %s", random);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/openssh-6.5p1/openbsd-compat/port-linux.h b/openssh-6.5p1/openbsd-compat/port-linux.h
|
||||
--- a/openssh-6.5p1/openbsd-compat/port-linux.h
|
||||
+++ b/openssh-6.5p1/openbsd-compat/port-linux.h
|
||||
@@ -14,16 +14,20 @@
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _PORT_LINUX_H
|
||||
#define _PORT_LINUX_H
|
||||
|
||||
+extern long rand_bytes;
|
||||
+extern char *rand_file;
|
||||
+void linux_seed(void);
|
||||
+
|
||||
#ifdef WITH_SELINUX
|
||||
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_setfscreatecon(const char *);
|
||||
#endif
|
||||
|
||||
diff --git a/openssh-6.5p1/ssh-add.1 b/openssh-6.5p1/ssh-add.1
|
||||
--- a/openssh-6.5p1/ssh-add.1
|
||||
+++ b/openssh-6.5p1/ssh-add.1
|
||||
@@ -156,16 +156,30 @@ or related script.
|
||||
(Note that on some machines it
|
||||
may be necessary to redirect the input from
|
||||
.Pa /dev/null
|
||||
to make this work.)
|
||||
.It Ev SSH_AUTH_SOCK
|
||||
Identifies the path of a
|
||||
.Ux Ns -domain
|
||||
socket used to communicate with the agent.
|
||||
+.It Ev SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm /dev/urandom .
|
||||
+If the
|
||||
+.Cm SSH_USE_STRONG_RNG
|
||||
+environment variable is set to value other than
|
||||
+.Cm 0
|
||||
+the OpenSSL random generator is reseeded from
|
||||
+.Cm /dev/random .
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 6 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa ~/.ssh/identity
|
||||
Contains the protocol version 1 RSA authentication identity of the user.
|
||||
.It Pa ~/.ssh/id_dsa
|
||||
Contains the protocol version 2 DSA authentication identity of the user.
|
||||
.It Pa ~/.ssh/id_ecdsa
|
||||
diff --git a/openssh-6.5p1/ssh-agent.1 b/openssh-6.5p1/ssh-agent.1
|
||||
--- a/openssh-6.5p1/ssh-agent.1
|
||||
+++ b/openssh-6.5p1/ssh-agent.1
|
||||
@@ -196,16 +196,33 @@ Contains the protocol version 2 ED25519
|
||||
.It Pa ~/.ssh/id_rsa
|
||||
Contains the protocol version 2 RSA authentication identity of the user.
|
||||
.It Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt
|
||||
.Ux Ns -domain
|
||||
sockets used to contain the connection to the authentication agent.
|
||||
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.
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr sshd 8
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
diff --git a/openssh-6.5p1/ssh-keygen.1 b/openssh-6.5p1/ssh-keygen.1
|
||||
--- a/openssh-6.5p1/ssh-keygen.1
|
||||
+++ b/openssh-6.5p1/ssh-keygen.1
|
||||
@@ -827,16 +827,33 @@ on all machines
|
||||
where the user wishes to log in using public key authentication.
|
||||
There is no need to keep the contents of this file secret.
|
||||
.Pp
|
||||
.It Pa /etc/moduli
|
||||
Contains Diffie-Hellman groups used for DH-GEX.
|
||||
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.
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
.Xr ssh-agent 1 ,
|
||||
.Xr moduli 5 ,
|
||||
.Xr sshd 8
|
||||
.Rs
|
||||
.%R RFC 4716
|
||||
diff --git a/openssh-6.5p1/ssh-keysign.8 b/openssh-6.5p1/ssh-keysign.8
|
||||
--- a/openssh-6.5p1/ssh-keysign.8
|
||||
+++ b/openssh-6.5p1/ssh-keysign.8
|
||||
@@ -75,16 +75,33 @@ must be set-uid root if host-based authe
|
||||
.Pp
|
||||
.It Pa /etc/ssh/ssh_host_dsa_key-cert.pub
|
||||
.It Pa /etc/ssh/ssh_host_ecdsa_key-cert.pub
|
||||
.It Pa /etc/ssh/ssh_host_ed25519_key-cert.pub
|
||||
.It Pa /etc/ssh/ssh_host_rsa_key-cert.pub
|
||||
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.
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr ssh_config 5 ,
|
||||
.Xr sshd 8
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
first appeared in
|
||||
diff --git a/openssh-6.5p1/ssh.1 b/openssh-6.5p1/ssh.1
|
||||
--- a/openssh-6.5p1/ssh.1
|
||||
+++ b/openssh-6.5p1/ssh.1
|
||||
@@ -1304,16 +1304,30 @@ reads
|
||||
and adds lines of the format
|
||||
.Dq VARNAME=value
|
||||
to the environment if the file exists and users are allowed to
|
||||
change their environment.
|
||||
For more information, see the
|
||||
.Cm PermitUserEnvironment
|
||||
option in
|
||||
.Xr sshd_config 5 .
|
||||
+.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 -compact
|
||||
.It Pa ~/.rhosts
|
||||
This file is used for host-based authentication (see above).
|
||||
On some machines this file may need to be
|
||||
world-readable if the user's home directory is on an NFS partition,
|
||||
because
|
||||
.Xr sshd 8
|
||||
diff --git a/openssh-6.5p1/sshd.8 b/openssh-6.5p1/sshd.8
|
||||
--- a/openssh-6.5p1/sshd.8
|
||||
+++ b/openssh-6.5p1/sshd.8
|
||||
@@ -946,16 +946,33 @@ and not group or world-writable.
|
||||
.It Pa /var/run/sshd.pid
|
||||
Contains the process ID of the
|
||||
.Nm
|
||||
listening for connections (if there are several daemons running
|
||||
concurrently for different ports, this contains the process ID of the one
|
||||
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.
|
||||
.Sh SEE ALSO
|
||||
.Xr scp 1 ,
|
||||
.Xr sftp 1 ,
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
.Xr ssh-agent 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr ssh-keyscan 1 ,
|
||||
diff --git a/openssh-6.5p1/sshd.c b/openssh-6.5p1/sshd.c
|
||||
--- a/openssh-6.5p1/sshd.c
|
||||
+++ b/openssh-6.5p1/sshd.c
|
||||
@@ -50,16 +50,18 @@
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include "openbsd-compat/sys-tree.h"
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
+#include "openbsd-compat/port-linux.h"
|
||||
+
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
#endif
|
||||
@@ -215,16 +217,23 @@ struct {
|
||||
Key **host_pubkeys; /* all public host keys */
|
||||
Key **host_certificates; /* all public host certificates */
|
||||
int have_ssh1_key;
|
||||
int have_ssh2_key;
|
||||
u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH];
|
||||
} sensitive_data;
|
||||
|
||||
/*
|
||||
+ * Every RESEED_AFTERth connection triggers call to linux_seed() to re-seed the
|
||||
+ * random pool.
|
||||
+ */
|
||||
+#define RESEED_AFTER 100
|
||||
+static int re_seeding_counter = RESEED_AFTER;
|
||||
+
|
||||
+/*
|
||||
* Flag indicating whether the RSA server key needs to be regenerated.
|
||||
* Is set in the SIGALRM handler and cleared when the key is regenerated.
|
||||
*/
|
||||
static volatile sig_atomic_t key_do_regen = 0;
|
||||
|
||||
/* This is set to true when a signal is received. */
|
||||
static volatile sig_atomic_t received_sighup = 0;
|
||||
static volatile sig_atomic_t received_sigterm = 0;
|
||||
@@ -1313,16 +1322,21 @@ server_accept_loop(int *sock_in, int *so
|
||||
for (j = 0; j < options.max_startups; j++)
|
||||
if (startup_pipes[j] == -1) {
|
||||
startup_pipes[j] = startup_p[0];
|
||||
if (maxfd < startup_p[0])
|
||||
maxfd = startup_p[0];
|
||||
startups++;
|
||||
break;
|
||||
}
|
||||
+ if(!(--re_seeding_counter)) {
|
||||
+ re_seeding_counter = RESEED_AFTER;
|
||||
+ linux_seed();
|
||||
+ audit_linux_prng_seed(rand_bytes, rand_file);
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Got connection. Fork a child to handle it, unless
|
||||
* we are in debugging mode.
|
||||
*/
|
||||
if (debug_flag) {
|
||||
/*
|
||||
* In debugging mode. Close the listening
|
@ -1,23 +1,33 @@
|
||||
Index: ssh_config
|
||||
===================================================================
|
||||
--- ssh_config.orig
|
||||
+++ ssh_config
|
||||
@@ -63,6 +63,9 @@ ForwardX11Trusted yes
|
||||
# send locales in default configuration
|
||||
# bnc#65747
|
||||
|
||||
diff --git a/openssh-6.5p1/ssh_config b/openssh-6.5p1/ssh_config
|
||||
--- a/openssh-6.5p1/ssh_config
|
||||
+++ b/openssh-6.5p1/ssh_config
|
||||
@@ -58,9 +58,14 @@ ForwardX11Trusted yes
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
|
||||
# Set this to 'yes' to enable support for the deprecated 'gssapi' authentication
|
||||
# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
|
||||
# in this release. The use of 'gssapi' is deprecated due to the presence of
|
||||
# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not susceptible to.
|
||||
# GSSAPIEnableMITMAttack no
|
||||
|
||||
->>>>>>>
|
||||
+# This enables sending locale enviroment variables LC_* LANG, see ssh_config(5).
|
||||
+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
|
||||
# VisualHostKey no
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
Index: sshd_config
|
||||
===================================================================
|
||||
--- sshd_config.orig
|
||||
+++ sshd_config
|
||||
@@ -117,6 +117,11 @@ X11Forwarding yes
|
||||
+
|
||||
# RekeyLimit 1G 1h
|
||||
diff --git a/openssh-6.5p1/sshd_config b/openssh-6.5p1/sshd_config
|
||||
--- a/openssh-6.5p1/sshd_config
|
||||
+++ b/openssh-6.5p1/sshd_config
|
||||
@@ -127,14 +127,19 @@ UsePrivilegeSeparation sandbox # Defaul
|
||||
#VersionAddendum none
|
||||
|
||||
# no default banner path
|
||||
#Banner none
|
||||
|
||||
# override default of no subsystems
|
||||
Subsystem sftp /usr/libexec/sftp-server
|
||||
|
||||
@ -29,3 +39,6 @@ Index: sshd_config
|
||||
# Example of overriding settings on a per-user basis
|
||||
#Match User anoncvs
|
||||
# X11Forwarding no
|
||||
# AllowTcpForwarding no
|
||||
# PermitTTY no
|
||||
# ForceCommand cvs server
|
155
openssh-6.5p1-sftp_force_permissions.patch
Normal file
155
openssh-6.5p1-sftp_force_permissions.patch
Normal file
@ -0,0 +1,155 @@
|
||||
# additional option for sftp-server to force file mode for new files
|
||||
# FATE#312774
|
||||
# http://lists.mindrot.org/pipermail/openssh-unix-dev/2010-November/029044.html
|
||||
# http://marc.info/?l=openssh-unix-dev&m=128896838930893
|
||||
|
||||
diff --git a/openssh-6.5p1/sftp-server.8 b/openssh-6.5p1/sftp-server.8
|
||||
--- a/openssh-6.5p1/sftp-server.8
|
||||
+++ b/openssh-6.5p1/sftp-server.8
|
||||
@@ -33,16 +33,17 @@
|
||||
.Bk -words
|
||||
.Op Fl ehR
|
||||
.Op Fl d Ar start_directory
|
||||
.Op Fl f Ar log_facility
|
||||
.Op Fl l Ar log_level
|
||||
.Op Fl P Ar blacklisted_requests
|
||||
.Op Fl p Ar whitelisted_requests
|
||||
.Op Fl u Ar umask
|
||||
+.Op Fl m Ar force_file_permissions
|
||||
.Ek
|
||||
.Nm
|
||||
.Fl Q Ar protocol_feature
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a program that speaks the server side of SFTP protocol
|
||||
to stdout and expects client requests from stdin.
|
||||
.Nm
|
||||
@@ -133,16 +134,20 @@ Places this instance of
|
||||
into a read-only mode.
|
||||
Attempts to open files for writing, as well as other operations that change
|
||||
the state of the filesystem, will be denied.
|
||||
.It Fl u Ar umask
|
||||
Sets an explicit
|
||||
.Xr umask 2
|
||||
to be applied to newly-created files and directories, instead of the
|
||||
user's default mask.
|
||||
+.It Fl m Ar force_file_permissions
|
||||
+Sets explicit file permissions to be applied to newly-created files instead
|
||||
+of the default or client requested mode. Numeric values include:
|
||||
+777, 755, 750, 666, 644, 640, etc. Option -u is ineffective if -m is set.
|
||||
.El
|
||||
.Pp
|
||||
For logging to work,
|
||||
.Nm
|
||||
must be able to access
|
||||
.Pa /dev/log .
|
||||
Use of
|
||||
.Nm
|
||||
diff --git a/openssh-6.5p1/sftp-server.c b/openssh-6.5p1/sftp-server.c
|
||||
--- a/openssh-6.5p1/sftp-server.c
|
||||
+++ b/openssh-6.5p1/sftp-server.c
|
||||
@@ -75,16 +75,20 @@ static u_int version;
|
||||
static int init_done;
|
||||
|
||||
/* Disable writes */
|
||||
static int readonly;
|
||||
|
||||
/* Requests that are allowed/denied */
|
||||
static char *request_whitelist, *request_blacklist;
|
||||
|
||||
+/* Force file permissions */
|
||||
+int permforce = 0;
|
||||
+long permforcemode;
|
||||
+
|
||||
/* portable attributes, etc. */
|
||||
typedef struct Stat Stat;
|
||||
|
||||
struct Stat {
|
||||
char *name;
|
||||
char *long_name;
|
||||
Attrib attrib;
|
||||
};
|
||||
@@ -670,16 +674,20 @@ process_open(u_int32_t id)
|
||||
int handle, fd, flags, mode, status = SSH2_FX_FAILURE;
|
||||
|
||||
name = get_string(NULL);
|
||||
pflags = get_int(); /* portable flags */
|
||||
debug3("request %u: open flags %d", id, pflags);
|
||||
a = get_attrib();
|
||||
flags = flags_from_portable(pflags);
|
||||
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
|
||||
+ if (permforce == 1) {
|
||||
+ mode = permforcemode;
|
||||
+ (void)umask(0); /* so umask does not interfere */
|
||||
+ }
|
||||
logit("open \"%s\" flags %s mode 0%o",
|
||||
name, string_from_portable(pflags), mode);
|
||||
if (readonly &&
|
||||
((flags & O_ACCMODE) == O_WRONLY ||
|
||||
(flags & O_ACCMODE) == O_RDWR)) {
|
||||
verbose("Refusing open request in read-only mode");
|
||||
status = SSH2_FX_PERMISSION_DENIED;
|
||||
} else {
|
||||
@@ -1425,17 +1433,18 @@ sftp_server_cleanup_exit(int i)
|
||||
static void
|
||||
sftp_server_usage(void)
|
||||
{
|
||||
extern char *__progname;
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
|
||||
"[-l log_level]\n\t[-P blacklisted_requests] "
|
||||
- "[-p whitelisted_requests] [-u umask]\n"
|
||||
+ "[-p whitelisted_requests] [-u umask]\n\t"
|
||||
+ "[-m force_file_permissions]\n",
|
||||
" %s -Q protocol_feature\n",
|
||||
__progname, __progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
{
|
||||
@@ -1450,17 +1459,17 @@ sftp_server_main(int argc, char **argv,
|
||||
extern char *__progname;
|
||||
|
||||
__progname = ssh_get_progname(argv[0]);
|
||||
log_init(__progname, log_level, log_facility, log_stderr);
|
||||
|
||||
pw = pwcopy(user_pw);
|
||||
|
||||
while (!skipargs && (ch = getopt(argc, argv,
|
||||
- "d:f:l:P:p:Q:u:cehR")) != -1) {
|
||||
+ "d:f:l:P:p:Q:u:m:cehR")) != -1) {
|
||||
switch (ch) {
|
||||
case 'Q':
|
||||
if (strcasecmp(optarg, "requests") != 0) {
|
||||
fprintf(stderr, "Invalid query type\n");
|
||||
exit(1);
|
||||
}
|
||||
for (i = 0; handlers[i].handler != NULL; i++)
|
||||
printf("%s\n", handlers[i].name);
|
||||
@@ -1510,16 +1519,23 @@ sftp_server_main(int argc, char **argv,
|
||||
case 'u':
|
||||
errno = 0;
|
||||
mask = strtol(optarg, &cp, 8);
|
||||
if (mask < 0 || mask > 0777 || *cp != '\0' ||
|
||||
cp == optarg || (mask == 0 && errno != 0))
|
||||
fatal("Invalid umask \"%s\"", optarg);
|
||||
(void)umask((mode_t)mask);
|
||||
break;
|
||||
+ case 'm':
|
||||
+ permforce = 1;
|
||||
+ permforcemode = strtol(optarg, &cp, 8);
|
||||
+ if (permforcemode < 0 || permforcemode > 0777 || *cp != '\0' ||
|
||||
+ cp == optarg || (permforcemode == 0 && errno != 0))
|
||||
+ fatal("Invalid umask \"%s\"", optarg);
|
||||
+ break;
|
||||
case 'h':
|
||||
default:
|
||||
sftp_server_usage();
|
||||
}
|
||||
}
|
||||
|
||||
log_init(__progname, log_level, log_facility, log_stderr);
|
||||
|
@ -1,45 +1,14 @@
|
||||
Index: chrootenv.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ chrootenv.h
|
||||
@@ -0,0 +1,32 @@
|
||||
+/* $OpenBSD: session.h,v 1.30 2008/05/08 12:21:16 djm Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ * 1. Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+#ifndef CHROOTENV_H
|
||||
+#define CHROOTENV_H
|
||||
+
|
||||
+extern int chroot_no_tree;
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
Index: session.c
|
||||
===================================================================
|
||||
--- session.c.orig
|
||||
+++ session.c
|
||||
@@ -120,6 +120,8 @@ void do_child(Session *, const char *);
|
||||
# run sftp sessions inside a chroot
|
||||
|
||||
diff --git a/openssh-6.5p1/session.c b/openssh-6.5p1/session.c
|
||||
--- a/openssh-6.5p1/session.c
|
||||
+++ b/openssh-6.5p1/session.c
|
||||
@@ -120,16 +120,18 @@ int do_exec(Session *, const char *);
|
||||
void do_login(Session *, const char *);
|
||||
#ifdef LOGIN_NEEDS_UTMPX
|
||||
static void do_pre_login(Session *s);
|
||||
#endif
|
||||
void do_child(Session *, const char *);
|
||||
void do_motd(void);
|
||||
int check_quietlogin(Session *, const char *);
|
||||
|
||||
@ -48,8 +17,18 @@ Index: session.c
|
||||
static void do_authenticated1(Authctxt *);
|
||||
static void do_authenticated2(Authctxt *);
|
||||
|
||||
@@ -808,6 +810,11 @@ do_exec(Session *s, const char *command)
|
||||
debug("Forced command (key option) '%.900s'", command);
|
||||
static int session_pty_req(Session *);
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern char *__progname;
|
||||
@@ -827,16 +829,21 @@ do_exec(Session *s, const char *command)
|
||||
"subsystem '%.900s'", s->subsys);
|
||||
} else if (command == NULL) {
|
||||
snprintf(session_type, sizeof(session_type), "shell");
|
||||
} else {
|
||||
/* NB. we don't log unforced commands to preserve privacy */
|
||||
snprintf(session_type, sizeof(session_type), "command");
|
||||
}
|
||||
|
||||
+ if ((s->is_subsystem != SUBSYSTEM_INT_SFTP) && chroot_no_tree) {
|
||||
@ -57,10 +36,20 @@ Index: session.c
|
||||
+ exit (1);
|
||||
+ }
|
||||
+
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
if (command != NULL)
|
||||
PRIVSEP(audit_run_command(command));
|
||||
@@ -1421,6 +1428,63 @@ do_nologin(struct passwd *pw)
|
||||
if (s->ttyfd != -1) {
|
||||
tty = s->tty;
|
||||
if (strncmp(tty, "/dev/", 5) == 0)
|
||||
tty += 5;
|
||||
}
|
||||
|
||||
verbose("Starting session: %s%s%s for %s from %.200s port %d",
|
||||
session_type,
|
||||
@@ -1458,67 +1465,132 @@ do_nologin(struct passwd *pw)
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
fputs(buf, stderr);
|
||||
fclose(f);
|
||||
}
|
||||
exit(254);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -85,7 +74,7 @@ Index: session.c
|
||||
+ strerror (errno));
|
||||
+ if (!s) {
|
||||
+ pclose (f);
|
||||
+ fatal ("cannot found filesystem with the chroot directory");
|
||||
+ fatal ("cannot find filesystem with the chroot directory");
|
||||
+ }
|
||||
+ (void) strtok (buf, " ");
|
||||
+ on = strtok (NULL, " ");
|
||||
@ -116,7 +105,7 @@ Index: session.c
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ fatal ("chroot into directory without nodev or nosuid");
|
||||
+ fatal ("chroot into directory without nodev and either noexec or nosuid");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
@ -124,7 +113,9 @@ Index: session.c
|
||||
* Chroot into a directory after checking it for safety: all path components
|
||||
* must be root-owned directories with strict permissions.
|
||||
*/
|
||||
@@ -1430,6 +1494,7 @@ safely_chroot(const char *path, uid_t ui
|
||||
static void
|
||||
safely_chroot(const char *path, uid_t uid)
|
||||
{
|
||||
const char *cp;
|
||||
char component[MAXPATHLEN];
|
||||
struct stat st;
|
||||
@ -132,7 +123,11 @@ Index: session.c
|
||||
|
||||
if (*path != '/')
|
||||
fatal("chroot path does not begin at root");
|
||||
@@ -1441,7 +1506,7 @@ safely_chroot(const char *path, uid_t ui
|
||||
if (strlen(path) >= sizeof(component))
|
||||
fatal("chroot path too long");
|
||||
|
||||
/*
|
||||
* Descend the path, checking that each component is a
|
||||
* root-owned directory with strict permissions.
|
||||
*/
|
||||
for (cp = path; cp != NULL;) {
|
||||
@ -141,7 +136,12 @@ Index: session.c
|
||||
strlcpy(component, path, sizeof(component));
|
||||
else {
|
||||
cp++;
|
||||
@@ -1454,14 +1519,20 @@ safely_chroot(const char *path, uid_t ui
|
||||
memcpy(component, path, cp - path);
|
||||
component[cp - path] = '\0';
|
||||
}
|
||||
|
||||
debug3("%s: checking '%s'", __func__, component);
|
||||
|
||||
if (stat(component, &st) != 0)
|
||||
fatal("%s: stat(\"%s\"): %s", __func__,
|
||||
component, strerror(errno));
|
||||
@ -155,52 +155,93 @@ Index: session.c
|
||||
cp == NULL ? "" : "component ", component);
|
||||
+ }
|
||||
+ setenv ("TZ", "/etc/localtime", 0);
|
||||
+ tzset ();
|
||||
+ tzset();
|
||||
|
||||
+ if (st.st_uid) {
|
||||
+ test_nosuid (path, st.st_dev);
|
||||
+ test_nosuid(path, st.st_dev);
|
||||
+ ++chroot_no_tree;
|
||||
}
|
||||
|
||||
if (chdir(path) == -1)
|
||||
@@ -1472,6 +1543,10 @@ safely_chroot(const char *path, uid_t ui
|
||||
fatal("Unable to chdir to chroot path \"%s\": "
|
||||
"%s", path, strerror(errno));
|
||||
if (chroot(path) == -1)
|
||||
fatal("chroot(\"%s\"): %s", path, strerror(errno));
|
||||
if (chdir("/") == -1)
|
||||
fatal("%s: chdir(/) after chroot: %s",
|
||||
__func__, strerror(errno));
|
||||
+
|
||||
+ if (access ("/etc/localtime", R_OK) < 0)
|
||||
+ ++chroot_no_tree;
|
||||
+
|
||||
verbose("Changed root directory to \"%s\"", path);
|
||||
}
|
||||
|
||||
Index: sftp.c
|
||||
===================================================================
|
||||
--- sftp.c.orig
|
||||
+++ sftp.c
|
||||
@@ -106,6 +106,8 @@ int remote_glob(struct sftp_conn *, cons
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
+int chroot_no_tree = 0;
|
||||
/* Set login name, uid, gid, and groups. */
|
||||
void
|
||||
do_setusercontext(struct passwd *pw)
|
||||
{
|
||||
char *chroot_path, *tmp;
|
||||
diff --git a/openssh-6.5p1/sftp-chrootenv.h b/openssh-6.5p1/sftp-chrootenv.h
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/openssh-6.5p1/sftp-chrootenv.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2009 Jan F Chadima. All rights reserved.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ * 1. Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+#ifndef CHROOTENV_H
|
||||
+#define CHROOTENV_H
|
||||
+
|
||||
/* Separators for interactive commands */
|
||||
#define WHITESPACE " \t\r\n"
|
||||
+extern int chroot_no_tree;
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
diff --git a/openssh-6.5p1/sftp-common.c b/openssh-6.5p1/sftp-common.c
|
||||
--- a/openssh-6.5p1/sftp-common.c
|
||||
+++ b/openssh-6.5p1/sftp-common.c
|
||||
@@ -42,16 +42,17 @@
|
||||
#endif
|
||||
|
||||
Index: sftp-common.c
|
||||
===================================================================
|
||||
--- sftp-common.c.orig
|
||||
+++ sftp-common.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
+#include "chrootenv.h"
|
||||
|
||||
#include "sftp.h"
|
||||
#include "sftp-common.h"
|
||||
@@ -196,13 +197,13 @@ ls_file(const char *name, const struct s
|
||||
+#include "sftp-chrootenv.h"
|
||||
|
||||
/* Clear contents of attributes structure */
|
||||
void
|
||||
attrib_clear(Attrib *a)
|
||||
{
|
||||
a->flags = 0;
|
||||
a->size = 0;
|
||||
a->uid = 0;
|
||||
@@ -193,23 +194,23 @@ ls_file(const char *name, const struct s
|
||||
int ulen, glen, sz = 0;
|
||||
struct tm *ltime = localtime(&st->st_mtime);
|
||||
char *user, *group;
|
||||
char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1];
|
||||
char sbuf[FMT_SCALED_STRSIZE];
|
||||
time_t now;
|
||||
|
||||
strmode(st->st_mode, mode);
|
||||
- if (!remote) {
|
||||
@ -215,11 +256,20 @@ Index: sftp-common.c
|
||||
group = group_from_gid(st->st_gid, 0);
|
||||
} else {
|
||||
snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
|
||||
Index: sftp-server-main.c
|
||||
===================================================================
|
||||
--- sftp-server-main.c.orig
|
||||
+++ sftp-server-main.c
|
||||
@@ -22,11 +22,14 @@
|
||||
group = gbuf;
|
||||
}
|
||||
if (ltime != NULL) {
|
||||
now = time(NULL);
|
||||
if (now - (365*24*60*60)/2 < st->st_mtime &&
|
||||
diff --git a/openssh-6.5p1/sftp-server-main.c b/openssh-6.5p1/sftp-server-main.c
|
||||
--- a/openssh-6.5p1/sftp-server-main.c
|
||||
+++ b/openssh-6.5p1/sftp-server-main.c
|
||||
@@ -17,21 +17,24 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -229,16 +279,47 @@ Index: sftp-server-main.c
|
||||
#include "sftp.h"
|
||||
#include "misc.h"
|
||||
|
||||
+int chroot_no_tree = 0;
|
||||
+int chroot_no_tree = 0;
|
||||
+
|
||||
void
|
||||
cleanup_exit(int i)
|
||||
{
|
||||
Index: sshd_config.0
|
||||
===================================================================
|
||||
--- sshd_config.0.orig
|
||||
+++ sshd_config.0
|
||||
@@ -143,6 +143,14 @@ DESCRIPTION
|
||||
sftp_server_cleanup_exit(i);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
diff --git a/openssh-6.5p1/sftp.c b/openssh-6.5p1/sftp.c
|
||||
--- a/openssh-6.5p1/sftp.c
|
||||
+++ b/openssh-6.5p1/sftp.c
|
||||
@@ -109,16 +109,18 @@ struct complete_ctx {
|
||||
char **remote_pathp;
|
||||
};
|
||||
|
||||
int remote_glob(struct sftp_conn *, const char *, int,
|
||||
int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
+int chroot_no_tree = 0;
|
||||
+
|
||||
/* Separators for interactive commands */
|
||||
#define WHITESPACE " \t\r\n"
|
||||
|
||||
/* ls flags */
|
||||
#define LS_LONG_VIEW 0x0001 /* Full view ala ls -l */
|
||||
#define LS_SHORT_VIEW 0x0002 /* Single row view ala ls -1 */
|
||||
#define LS_NUMERIC_VIEW 0x0004 /* Long view with numeric uid/gid */
|
||||
#define LS_NAME_SORT 0x0008 /* Sort by name (default) */
|
||||
diff --git a/openssh-6.5p1/sshd_config.0 b/openssh-6.5p1/sshd_config.0
|
||||
--- a/openssh-6.5p1/sshd_config.0
|
||||
+++ b/openssh-6.5p1/sshd_config.0
|
||||
@@ -189,16 +189,24 @@ DESCRIPTION
|
||||
session this requires at least a shell, typically sh(1), and
|
||||
basic /dev nodes such as null(4), zero(4), stdin(4), stdout(4),
|
||||
stderr(4), arandom(4) and tty(4) devices. For file transfer
|
||||
sessions using ``sftp'', no additional configuration of the
|
||||
environment is necessary if the in-process sftp server is used,
|
||||
though sessions which use logging do require /dev/log inside the
|
||||
chroot directory (see sftp-server(8) for details).
|
||||
|
||||
@ -253,11 +334,20 @@ Index: sshd_config.0
|
||||
The default is not to chroot(2).
|
||||
|
||||
Ciphers
|
||||
Index: sshd_config.5
|
||||
===================================================================
|
||||
--- sshd_config.5.orig
|
||||
+++ sshd_config.5
|
||||
@@ -268,6 +268,17 @@ inside the chroot directory (see
|
||||
Specifies the ciphers allowed for protocol version 2. Multiple
|
||||
ciphers must be comma-separated. The supported ciphers are:
|
||||
|
||||
``3des-cbc'', ``aes128-cbc'', ``aes192-cbc'', ``aes256-cbc'',
|
||||
``aes128-ctr'', ``aes192-ctr'', ``aes256-ctr'',
|
||||
diff --git a/openssh-6.5p1/sshd_config.5 b/openssh-6.5p1/sshd_config.5
|
||||
--- a/openssh-6.5p1/sshd_config.5
|
||||
+++ b/openssh-6.5p1/sshd_config.5
|
||||
@@ -324,16 +324,27 @@ For file transfer sessions using
|
||||
no additional configuration of the environment is necessary if the
|
||||
in-process sftp server is used,
|
||||
though sessions which use logging do require
|
||||
.Pa /dev/log
|
||||
inside the chroot directory (see
|
||||
.Xr sftp-server 8
|
||||
for details).
|
||||
.Pp
|
||||
@ -275,3 +365,8 @@ Index: sshd_config.5
|
||||
The default is not to
|
||||
.Xr chroot 2 .
|
||||
.It Cm Ciphers
|
||||
Specifies the ciphers allowed for protocol version 2.
|
||||
Multiple ciphers must be comma-separated.
|
||||
The supported ciphers are:
|
||||
.Pp
|
||||
.Dq 3des-cbc ,
|
@ -1,8 +1,15 @@
|
||||
Index: session.c
|
||||
===================================================================
|
||||
--- session.c.orig
|
||||
+++ session.c
|
||||
@@ -2463,8 +2463,40 @@ void
|
||||
# try to remove xauth cookies on logout
|
||||
# bnc#98815
|
||||
|
||||
diff --git a/openssh-6.5p1/session.c b/openssh-6.5p1/session.c
|
||||
--- a/openssh-6.5p1/session.c
|
||||
+++ b/openssh-6.5p1/session.c
|
||||
@@ -2505,18 +2505,50 @@ session_exit_message(Session *s, int sta
|
||||
if (c->ostate != CHAN_OUTPUT_CLOSED)
|
||||
chan_write_failed(c);
|
||||
}
|
||||
|
||||
void
|
||||
session_close(Session *s)
|
||||
{
|
||||
u_int i;
|
||||
@ -10,7 +17,7 @@ Index: session.c
|
||||
|
||||
debug("session_close: session %d pid %ld", s->self, (long)s->pid);
|
||||
+
|
||||
+ do_xauth = s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
|
||||
+ do_xauth = (s->display != NULL) && (s->auth_proto != NULL) && (s->auth_data != NULL);
|
||||
+ if (do_xauth && options.xauth_location != NULL) {
|
||||
+ pid_t pid;
|
||||
+ FILE *f;
|
||||
@ -42,4 +49,9 @@ Index: session.c
|
||||
+
|
||||
if (s->ttyfd != -1)
|
||||
session_pty_cleanup(s);
|
||||
if (s->term)
|
||||
free(s->term);
|
||||
free(s->display);
|
||||
free(s->x11_chanids);
|
||||
free(s->auth_display);
|
||||
free(s->auth_data);
|
||||
free(s->auth_proto);
|
141
openssh-6.5p1-xauthlocalhostname.patch
Normal file
141
openssh-6.5p1-xauthlocalhostname.patch
Normal file
@ -0,0 +1,141 @@
|
||||
# handle hostname changes when forwarding X
|
||||
# bnc#98627
|
||||
|
||||
diff --git a/openssh-6.5p1/session.c b/openssh-6.5p1/session.c
|
||||
--- a/openssh-6.5p1/session.c
|
||||
+++ b/openssh-6.5p1/session.c
|
||||
@@ -1141,17 +1141,17 @@ copy_environment(char **source, char ***
|
||||
debug3("Copy environment: %s=%s", var_name, var_val);
|
||||
child_set_env(env, envsize, var_name, var_val);
|
||||
|
||||
free(var_name);
|
||||
}
|
||||
}
|
||||
|
||||
static char **
|
||||
-do_setup_env(Session *s, const char *shell)
|
||||
+do_setup_env(Session *s, const char *shell, int *env_size)
|
||||
{
|
||||
char buf[256];
|
||||
u_int i, envsize;
|
||||
char **env, *laddr;
|
||||
struct passwd *pw = s->pw;
|
||||
#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
|
||||
char *path = NULL;
|
||||
#endif
|
||||
@@ -1328,25 +1328,27 @@ do_setup_env(Session *s, const char *she
|
||||
read_environment_file(&env, &envsize, buf);
|
||||
}
|
||||
if (debug_flag) {
|
||||
/* dump the environment */
|
||||
fprintf(stderr, "Environment:\n");
|
||||
for (i = 0; env[i]; i++)
|
||||
fprintf(stderr, " %.200s\n", env[i]);
|
||||
}
|
||||
+
|
||||
+ *env_size = envsize;
|
||||
return env;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
|
||||
* first in this order).
|
||||
*/
|
||||
static void
|
||||
-do_rc_files(Session *s, const char *shell)
|
||||
+do_rc_files(Session *s, const char *shell, char **env, int *env_size)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
char cmd[1024];
|
||||
int do_xauth;
|
||||
struct stat st;
|
||||
|
||||
do_xauth =
|
||||
s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
|
||||
@@ -1390,22 +1392,30 @@ do_rc_files(Session *s, const char *shel
|
||||
"%.500s add %.100s %.100s %.100s\n",
|
||||
options.xauth_location, s->auth_display,
|
||||
s->auth_proto, s->auth_data);
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s -q -",
|
||||
options.xauth_location);
|
||||
f = popen(cmd, "w");
|
||||
if (f) {
|
||||
+ char hostname[MAXHOSTNAMELEN];
|
||||
+
|
||||
fprintf(f, "remove %s\n",
|
||||
s->auth_display);
|
||||
fprintf(f, "add %s %s %s\n",
|
||||
s->auth_display, s->auth_proto,
|
||||
s->auth_data);
|
||||
pclose(f);
|
||||
+ if (gethostname(hostname,sizeof(hostname)) >= 0)
|
||||
+ child_set_env(&env,env_size,"XAUTHLOCALHOSTNAME",
|
||||
+ hostname);
|
||||
+ else
|
||||
+ debug("Cannot set up XAUTHLOCALHOSTNAME %s\n",
|
||||
+ strerror(errno));
|
||||
} else {
|
||||
fprintf(stderr, "Could not run %s\n",
|
||||
cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1659,16 +1669,17 @@ child_close_fds(void)
|
||||
* ids, and executing the command or shell.
|
||||
*/
|
||||
#define ARGV_MAX 10
|
||||
void
|
||||
do_child(Session *s, const char *command)
|
||||
{
|
||||
extern char **environ;
|
||||
char **env;
|
||||
+ int env_size;
|
||||
char *argv[ARGV_MAX];
|
||||
const char *shell, *shell0, *hostname = NULL;
|
||||
struct passwd *pw = s->pw;
|
||||
int r = 0;
|
||||
|
||||
/* remove hostkey from the child's memory */
|
||||
destroy_sensitive_data();
|
||||
|
||||
@@ -1725,17 +1736,17 @@ do_child(Session *s, const char *command
|
||||
* legal, and means /bin/sh.
|
||||
*/
|
||||
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
|
||||
|
||||
/*
|
||||
* Make sure $SHELL points to the shell from the password file,
|
||||
* even if shell is overridden from login.conf
|
||||
*/
|
||||
- env = do_setup_env(s, shell);
|
||||
+ env = do_setup_env(s, shell, &env_size);
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
|
||||
#endif
|
||||
|
||||
/* we have to stash the hostname before we close our socket. */
|
||||
if (options.use_login)
|
||||
hostname = get_remote_name_or_ip(utmp_len,
|
||||
@@ -1794,17 +1805,17 @@ do_child(Session *s, const char *command
|
||||
strerror(errno));
|
||||
if (r)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
if (!options.use_login)
|
||||
- do_rc_files(s, shell);
|
||||
+ do_rc_files(s, shell, env, &env_size);
|
||||
|
||||
/* restore SIGPIPE for child */
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
|
||||
if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) {
|
||||
printf("This service allows sftp connections only.\n");
|
||||
fflush(NULL);
|
||||
exit(1);
|
3
openssh-6.5p1.tar.gz
Normal file
3
openssh-6.5p1.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a1195ed55db945252d5a1730d4a2a2a5c1c9a6aa01ef2e5af750a962623d9027
|
||||
size 1293187
|
@ -1,3 +1,18 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Feb 12 01:24:16 UTC 2014 - pcerny@suse.com
|
||||
|
||||
- Update of the underlying OpenSSH to 6.5p1
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 24 15:13:09 UTC 2014 - pcerny@suse.com
|
||||
|
||||
- Update of the underlying OpenSSH to 6.4p1
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Sep 19 02:02:56 UTC 2013 - pcerny@suse.com
|
||||
|
||||
- spec file cleanup (don't pointelssly build whole OpenSSH)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Aug 3 18:12:20 UTC 2013 - crrodriguez@opensuse.org
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file for package openssh-askpass-gnome
|
||||
#
|
||||
# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@ -26,7 +26,7 @@ BuildRequires: openssl-devel
|
||||
BuildRequires: pam-devel
|
||||
BuildRequires: tcpd-devel
|
||||
BuildRequires: update-desktop-files
|
||||
Version: 6.2p2
|
||||
Version: 6.5p1
|
||||
Release: 0
|
||||
Requires: openssh = %{version}
|
||||
Summary: A GNOME-Based Passphrase Dialog for OpenSSH
|
||||
@ -35,14 +35,6 @@ Group: Productivity/Networking/SSH
|
||||
Url: http://www.openssh.com/
|
||||
%define _name openssh
|
||||
Source: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
|
||||
Patch: %{_name}-5.9p1-sshd_config.diff
|
||||
Patch1: %{_name}-5.9p1-pam-fix2.diff
|
||||
Patch2: %{_name}-5.9p1-saveargv-fix.diff
|
||||
Patch3: %{_name}-5.9p1-pam-fix3.diff
|
||||
Patch4: %{_name}-5.9p1-gssapimitm.patch
|
||||
Patch5: %{_name}-5.9p1-eal3.diff
|
||||
Patch6: %{_name}-5.9p1-engines.diff
|
||||
Patch7: %{_name}-5.9p1-blocksigalrm.diff
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
|
||||
%description
|
||||
@ -52,35 +44,14 @@ GNOME-based passphrase dialog for OpenSSH.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{_name}-%{version}
|
||||
%patch
|
||||
%patch1
|
||||
%patch2
|
||||
%patch3
|
||||
%patch4
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7
|
||||
|
||||
%build
|
||||
aclocal
|
||||
autoheader
|
||||
autoconf
|
||||
%configure \
|
||||
--sysconfdir=%{_sysconfdir}/ssh \
|
||||
--libexecdir=%{_libexecdir}/ssh \
|
||||
--with-tcp-wrappers \
|
||||
--with-pam \
|
||||
--with-kerberos5=/usr \
|
||||
--with-privsep-path=/var/lib/empty \
|
||||
--disable-strip \
|
||||
--target=%{_target_cpu}-suse-linux
|
||||
cd contrib
|
||||
make %{?_smp_mflags} gnome-ssh-askpass2
|
||||
mv gnome-ssh-askpass2 gnome-ssh-askpass
|
||||
|
||||
%install
|
||||
install -d -m 755 %{buildroot}%{_libexecdir}/ssh/
|
||||
install contrib/gnome-ssh-askpass %{buildroot}%{_libexecdir}/ssh/gnome-ssh-askpass
|
||||
install contrib/gnome-ssh-askpass2 %{buildroot}%{_libexecdir}/ssh/gnome-ssh-askpass
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
|
@ -1,17 +0,0 @@
|
||||
--- entropy.c.orig
|
||||
+++ entropy.c
|
||||
@@ -216,12 +216,13 @@ seed_rng(void)
|
||||
* allow 1.0.1 to work with 1.0.0). Going backwards is only allowed
|
||||
* within a patch series.
|
||||
*/
|
||||
+#if 0
|
||||
u_long version_mask = SSLeay() >= 0x1000000f ? ~0xffff0L : ~0xff0L;
|
||||
if (((SSLeay() ^ OPENSSL_VERSION_NUMBER) & version_mask) ||
|
||||
(SSLeay() >> 12) < (OPENSSL_VERSION_NUMBER >> 12))
|
||||
fatal("OpenSSL version mismatch. Built against %lx, you "
|
||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
|
||||
-
|
||||
+#endif
|
||||
#ifndef OPENSSL_PRNG_ONLY
|
||||
if (RAND_status() == 1) {
|
||||
debug3("RNG is ready, skipping seeding");
|
@ -1,11 +0,0 @@
|
||||
--- sshd.c.orig
|
||||
+++ sshd.c
|
||||
@@ -1840,7 +1840,7 @@ main(int ac, char **av)
|
||||
* Write out the pid file after the sigterm handler
|
||||
* is setup and the listen sockets are bound
|
||||
*/
|
||||
- if (!debug_flag) {
|
||||
+ if (!(debug_flag || no_daemon_flag)) {
|
||||
FILE *f = fopen(options.pid_file, "w");
|
||||
|
||||
if (f == NULL) {
|
229
openssh.changes
229
openssh.changes
@ -1,3 +1,232 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Feb 12 01:24:16 UTC 2014 - pcerny@suse.com
|
||||
|
||||
- Update to 6.5p1
|
||||
Features since 6.4p1:
|
||||
* ssh(1), sshd(8): support for key exchange using ECDH in
|
||||
Daniel Bernstein's Curve25519; default when both the client
|
||||
and server support it.
|
||||
* ssh(1), sshd(8): support for Ed25519 as a public key type fo
|
||||
rboth server and client. Ed25519 is an EC signature offering
|
||||
better security than ECDSA and DSA and good performance.
|
||||
* Add a new private key format that uses a bcrypt KDF to better
|
||||
protect keys at rest. Used unconditionally for Ed25519 keys,
|
||||
on demand for other key types via the -o ssh-keygen(1)
|
||||
option. Intended to become default in the near future.
|
||||
Details documented in PROTOCOL.key.
|
||||
* ssh(1), sshd(8): new transport cipher
|
||||
"chacha20-poly1305@openssh.com" combining Daniel Bernstein's
|
||||
ChaCha20 stream cipher and Poly1305 MAC to build an
|
||||
authenticated encryption mode. Details documented
|
||||
PROTOCOL.chacha20poly1305.
|
||||
* ssh(1), sshd(8): refuse RSA keys from old proprietary clients
|
||||
and servers that use the obsolete RSA+MD5 signature scheme.
|
||||
It will still be possible to connect with these
|
||||
clients/servers but only DSA keys will be accepted, and
|
||||
OpenSSH will refuse connection entirely in a future release.
|
||||
* ssh(1), sshd(8): refuse old proprietary clients and servers
|
||||
that use a weaker key exchange hash calculation.
|
||||
* ssh(1): increase the size of the Diffie-Hellman groups
|
||||
requested for each symmetric key size. New values from NIST
|
||||
Special Publication 800-57 with the upper limit specified by
|
||||
RFC4419.
|
||||
* ssh(1), ssh-agent(1): support pkcs#11 tokens that only
|
||||
provide X.509 certs instead of raw public keys (requested as
|
||||
bz#1908).
|
||||
* ssh(1): new ssh_config(5) "Match" keyword that allows
|
||||
conditional configuration to be applied by matching on
|
||||
hostname, user and result of arbitrary commands.
|
||||
* ssh(1): support for client-side hostname canonicalisation
|
||||
using a set of DNS suffixes and rules in ssh_config(5). This
|
||||
allows unqualified names to be canonicalised to
|
||||
fully-qualified domain names to eliminate ambiguity when
|
||||
looking up keys in known_hosts or checking host certificate
|
||||
names.
|
||||
* sftp-server(8): ability to whitelist and/or blacklist sftp
|
||||
protocol requests by name.
|
||||
* sftp-server(8): sftp "fsync@openssh.com" to support calling
|
||||
fsync(2) on an open file handle.
|
||||
* sshd(8): ssh_config(5) PermitTTY to disallow TTY allocation,
|
||||
mirroring the longstanding no-pty authorized_keys option.
|
||||
* ssh(1): ssh_config ProxyUseFDPass option that supports the
|
||||
use of ProxyCommands that establish a connection and then
|
||||
pass a connected file descriptor back to ssh(1). This allows
|
||||
the ProxyCommand to exit rather than staying around to
|
||||
transfer data.
|
||||
Bugfixes since 6.4p1:
|
||||
* ssh(1), sshd(8): fix potential stack exhaustion caused by
|
||||
nested certificates.
|
||||
* ssh(1): bz#1211: make BindAddress work with
|
||||
UsePrivilegedPort.
|
||||
* sftp(1): bz#2137: fix the progress meter for resumed
|
||||
transfer.
|
||||
* ssh-add(1): bz#2187: do not request smartcard PIN when
|
||||
removing keys from ssh-agent.
|
||||
* sshd(8): bz#2139: fix re-exec fallback when original sshd
|
||||
binary cannot be executed.
|
||||
* ssh-keygen(1): make relative-specified certificate expiry
|
||||
times relative to current time and not the validity start
|
||||
time.
|
||||
* sshd(8): bz#2161: fix AuthorizedKeysCommand inside a Match
|
||||
block.
|
||||
* sftp(1): bz#2129: symlinking a file would incorrectly
|
||||
canonicalise the target path.
|
||||
* ssh-agent(1): bz#2175: fix a use-after-free in the PKCS#11
|
||||
agent helper executable.
|
||||
* sshd(8): improve logging of sessions to include the user
|
||||
name, remote host and port, the session type (shell, command,
|
||||
etc.) and allocated TTY (if any).
|
||||
* sshd(8): bz#1297: tell the client (via a debug message) when
|
||||
their preferred listen address has been overridden by the
|
||||
server's GatewayPorts setting.
|
||||
* sshd(8): bz#2162: include report port in bad protocol banner
|
||||
message.
|
||||
* sftp(1): bz#2163: fix memory leak in error path in
|
||||
do_readdir().
|
||||
* sftp(1): bz#2171: don't leak file descriptor on error.
|
||||
* sshd(8): include the local address and port in "Connection
|
||||
from ..." message (only shown at loglevel>=verbose).
|
||||
- systemd systems
|
||||
* create sysconfig file on systemd systems as well, yet do not
|
||||
require it at run-time (bnc#862600)
|
||||
* symlink rcsshd to /usr/bin/service
|
||||
- rename "-forcepermissions" patch to "-sftp_force_permissions"
|
||||
- disable key converter - ssh-keygen is able to do the same
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Feb 11 07:42:09 UTC 2014 - meissner@suse.com
|
||||
|
||||
- add a rcsshd symlink to /usr/sbin/service
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Feb 5 08:38:11 UTC 2014 - idonmez@suse.com
|
||||
|
||||
- Add openssh-6.2p1-forcepermissions.patch to implement a force
|
||||
permissions mode (fate#312774). The patch is based on
|
||||
http://marc.info/?l=openssh-unix-dev&m=128896838930893
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 24 15:13:09 UTC 2014 - pcerny@suse.com
|
||||
|
||||
- Update to 6.4p1
|
||||
Features since 6.2p2:
|
||||
* ssh-agent(1) support in sshd(8); allows encrypted hostkeys, or
|
||||
hostkeys on smartcards.
|
||||
* ssh(1)/sshd(8): allow optional time-based rekeying via a
|
||||
second argument to the existing RekeyLimit option. RekeyLimit
|
||||
is now supported in sshd_config as well as on the client.
|
||||
* sshd(8): standardise logging of information during user
|
||||
authentication.
|
||||
* The presented key/cert and the remote username (if available)
|
||||
is now logged in the authentication success/failure message on
|
||||
the same log line as the local username, remote host/port and
|
||||
protocol in use. Certificates contents and the key
|
||||
fingerprint of the signing CA are logged too.
|
||||
* ssh(1) ability to query what cryptographic algorithms are
|
||||
supported in the binary.
|
||||
* ssh(1): ProxyCommand=- for cases where stdin and stdout
|
||||
already point to the proxy.
|
||||
* ssh(1): allow IdentityFile=none
|
||||
* ssh(1)/sshd(8): -E option to append debugging logs to a
|
||||
specified file instead of stderr or syslog.
|
||||
* sftp(1): support resuming partial downloads with the "reget"
|
||||
command and on the sftp commandline or on the "get"
|
||||
commandline with the "-a" (append) option.
|
||||
* ssh(1): "IgnoreUnknown" configuration option to selectively
|
||||
suppress errors arising from unknown configuration directives.
|
||||
* sshd(8): support for submethods to be appended to required
|
||||
authentication methods listed via AuthenticationMethods.
|
||||
Bugfixes since 6.2p2:
|
||||
* sshd(8): fix refusal to accept certificate if a key of a
|
||||
different type to the CA key appeared in authorized_keys
|
||||
before the CA key.
|
||||
* ssh(1)/ssh-agent(1)/sshd(8): Use a monotonic time source for
|
||||
timers so that things like keepalives and rekeying will work
|
||||
properly over clock steps.
|
||||
* sftp(1): update progressmeter when data is acknowledged, not
|
||||
when it's sent. bz#2108
|
||||
* ssh(1)/ssh-keygen(1): improve error messages when the current
|
||||
user does not exist in /etc/passwd; bz#2125
|
||||
* ssh(1): reset the order in which public keys are tried after
|
||||
partial authentication success.
|
||||
* ssh-agent(1): clean up socket files after SIGINT when in debug
|
||||
mode; bz#2120
|
||||
* ssh(1) and others: avoid confusing error messages in the case
|
||||
of broken system resolver configurations; bz#2122
|
||||
* ssh(1): set TCP nodelay for connections started with -N;
|
||||
bz#2124
|
||||
* ssh(1): correct manual for permission requirements on
|
||||
~/.ssh/config; bz#2078
|
||||
* ssh(1): fix ControlPersist timeout not triggering in cases
|
||||
where TCP connections have hung. bz#1917
|
||||
* ssh(1): properly deatch a ControlPersist master from its
|
||||
controlling terminal.
|
||||
* sftp(1): avoid crashes in libedit when it has been compiled
|
||||
with multi- byte character support. bz#1990
|
||||
* sshd(8): when running sshd -D, close stderr unless we have
|
||||
explicitly requested logging to stderr. bz#1976,
|
||||
* ssh(1): fix incomplete bzero; bz#2100
|
||||
* sshd(8): log and error and exit if ChrootDirectory is
|
||||
specified and running without root privileges.
|
||||
* Many improvements to the regression test suite. In particular
|
||||
log files are now saved from ssh and sshd after failures.
|
||||
* Fix a number of memory leaks. bz#1967 bz#2096 and others
|
||||
* sshd(8): fix public key authentication when a :style is
|
||||
appended to the requested username.
|
||||
* ssh(1): do not fatally exit when attempting to cleanup
|
||||
multiplexing- created channels that are incompletely opened.
|
||||
bz#2079
|
||||
* sshd(8): fix a memory corruption problem triggered during
|
||||
rekeying when an AES-GCM cipher is selected
|
||||
* Fix unaligned accesses in umac.c for strict-alignment
|
||||
architectures. bz#2101
|
||||
* Fix broken incorrect commandline reporting errors. bz#1448
|
||||
* Only include SHA256 and ECC-based key exchange methods if
|
||||
libcrypto has the required support.
|
||||
* Fix crash in SOCKS5 dynamic forwarding code on
|
||||
strict-alignment architectures.
|
||||
- FIPS and GSSKEX patched disabled for now
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Oct 4 17:50:32 UTC 2013 - pcerny@suse.com
|
||||
|
||||
- fix server crashes when using AES-GCM
|
||||
- removed superfluous build dependency on X
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Sep 19 02:02:56 UTC 2013 - pcerny@suse.com
|
||||
|
||||
- spec file and patch cleanup
|
||||
* key converter is now in the -key-converter.patch
|
||||
* openssh-nodaemon-nopid.patch is -no_fork-no_pid_file.patch
|
||||
* openssh-nocrazyabicheck.patch is
|
||||
-disable-openssl-abi-check.patch
|
||||
* removing obsolete -engines.diff patch
|
||||
- patches from SLE11
|
||||
* use auditing infrastructure extending upstream hooks
|
||||
(-auditX-*.patch) instead of the single old patch
|
||||
(-audit.patch)
|
||||
* FIPS enablement (currently disabled)
|
||||
(-fingerprint_hash.patch, -fips.patch)
|
||||
* GSSAPI key exchange
|
||||
(bnc#784689, fate#313068, -gssapi_key_exchange.patch)
|
||||
* SysV init script update - 'stop' now terminates all sshd
|
||||
processes and closes all connections, 'soft-stop' only
|
||||
terminates the listener process (keeps active sessions intact)
|
||||
(fate#314243)
|
||||
* helper application for retrieving users' public keys from
|
||||
an LDAP server (bnc#683733, fate#302144, -ldap.patch)
|
||||
- subpackage openssh-akc-ldap
|
||||
* several bugfixes:
|
||||
- login invocation
|
||||
(bnc#833605, -login_options.patch)
|
||||
- disable locked accounts when using PAM
|
||||
(bnc#708678, fate#312033, -pam-check-locks.patch)
|
||||
- fix wtmp handling
|
||||
(bnc#18024, -lastlog.patch)
|
||||
- init script is moved into documentation for openSUSE 12.3+
|
||||
(as it confused systemd)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Sep 10 21:15:59 UTC 2013 - crrodriguez@opensuse.org
|
||||
|
||||
|
394
openssh.spec
394
openssh.spec
@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file for package openssh
|
||||
#
|
||||
# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@ -16,27 +16,83 @@
|
||||
#
|
||||
|
||||
|
||||
%if 0%{suse_version} >= 1100
|
||||
%define has_fw_dir 1
|
||||
%else
|
||||
%define has_fw_dir 0
|
||||
%endif
|
||||
|
||||
%if 0%{suse_version} >= 1110
|
||||
%define has_libselinux 1
|
||||
%else
|
||||
%define has_libselinux 0
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version} >= 1130
|
||||
%define needs_all_dirs 1
|
||||
%else
|
||||
%define needs_all_dirs 0
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version} >= 1140
|
||||
%define needs_libedit 1
|
||||
%else
|
||||
%define needs_libedit 0
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version} > 1140
|
||||
%define has_krb_mini 1
|
||||
%else
|
||||
%define has_krb_mini 0
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version} > 1220
|
||||
%define uses_systemd 1
|
||||
%else
|
||||
%define uses_systemd 0
|
||||
%endif
|
||||
|
||||
%define sandbox_seccomp 0
|
||||
%ifarch %ix86 x86_64
|
||||
%if 0%{?suse_version} > 1220
|
||||
%define sandbox_seccomp 1
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%define _fwdir %{_sysconfdir}/sysconfig/SuSEfirewall2.d
|
||||
%define _fwdefdir %{_fwdir}/services
|
||||
%define _appdefdir %( grep "configdirspec=" $( which xmkmf ) | sed -r 's,^[^=]+=.*-I(.*)/config.*$,\\1/app-defaults,' )
|
||||
%{!?_initddir:%global _initddir %{_initrddir}}
|
||||
|
||||
Name: openssh
|
||||
%define _fwdefdir %{_sysconfdir}/sysconfig/SuSEfirewall2.d/services
|
||||
%define _appdefdir %{_prefix}/share/X11/app-defaults
|
||||
BuildRequires: audit-devel
|
||||
BuildRequires: autoconf
|
||||
BuildRequires: groff
|
||||
%if %{has_krb_mini}
|
||||
BuildRequires: krb5-mini-devel
|
||||
%else
|
||||
BuildRequires: krb5-devel
|
||||
%endif
|
||||
%if %{needs_libedit}
|
||||
BuildRequires: libedit-devel
|
||||
%if 0%{suse_version} > 1100
|
||||
%endif
|
||||
%if %{has_libselinux}
|
||||
BuildRequires: libselinux-devel
|
||||
%endif
|
||||
BuildRequires: openldap2-devel
|
||||
BuildRequires: openssl-devel
|
||||
BuildRequires: pam-devel
|
||||
%if %{uses_systemd}
|
||||
BuildRequires: pkgconfig(systemd)
|
||||
%{?systemd_requires}
|
||||
%endif
|
||||
BuildRequires: tcpd-devel
|
||||
Requires: /bin/netstat
|
||||
PreReq: pwdutils %{insserv_prereq} %{fillup_prereq} coreutils
|
||||
Conflicts: nonfreessh
|
||||
Recommends: xauth
|
||||
Version: 6.2p2
|
||||
Recommends: %{name}-helpers
|
||||
Version: 6.5p1
|
||||
Release: 0
|
||||
%define xversion 1.2.4.1
|
||||
Summary: Secure Shell Client and Server (Remote Login Program)
|
||||
License: BSD-3-Clause and MIT
|
||||
Group: Productivity/Networking/SSH
|
||||
@ -44,43 +100,50 @@ Url: http://www.openssh.com/
|
||||
Source: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
|
||||
Source1: sshd.init
|
||||
Source2: sshd.pamd
|
||||
Source4: README.SuSE
|
||||
Source5: converter.tar.bz2
|
||||
Source6: README.kerberos
|
||||
Source7: ssh.reg
|
||||
Source8: ssh-askpass
|
||||
Source9: sshd.fw
|
||||
Source10: sysconfig.ssh
|
||||
Source11: sshd-gen-keys-start
|
||||
Source12: sshd.service
|
||||
Patch: %{name}-5.9p1-sshd_config.diff
|
||||
Patch2: %{name}-5.9p1-pam-fix2.diff
|
||||
Patch3: %{name}-5.9p1-saveargv-fix.diff
|
||||
Patch4: %{name}-5.9p1-pam-fix3.diff
|
||||
Patch5: %{name}-5.9p1-gssapimitm.patch
|
||||
Patch6: %{name}-5.9p1-eal3.diff
|
||||
Patch7: %{name}-5.9p1-engines.diff
|
||||
Patch8: %{name}-5.9p1-blocksigalrm.diff
|
||||
Patch9: %{name}-5.9p1-send_locale.diff
|
||||
Patch10: %{name}-5.9p1-xauthlocalhostname.diff
|
||||
Patch12: %{name}-5.9p1-xauth.diff
|
||||
Patch14: %{name}-5.9p1-default-protocol.diff
|
||||
Patch15: %{name}-5.9p1-audit.patch
|
||||
Patch16: %{name}-5.9p1-pts.diff
|
||||
Patch17: %{name}-5.9p1-homechroot.patch
|
||||
Patch18: %{name}-5.9p1-sshconfig-knownhostschanges.diff
|
||||
Patch19: %{name}-5.9p1-host_ident.diff
|
||||
Patch20: converter-linking.patch
|
||||
Patch21: openssh-nocrazyabicheck.patch
|
||||
Patch22: openssh-nodaemon-nopid.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
%if 0%{?suse_version} > 1140
|
||||
BuildRequires: pkgconfig(systemd)
|
||||
%{?systemd_requires}
|
||||
%define has_systemd 1
|
||||
%endif
|
||||
Source3: README.SuSE
|
||||
Source4: README.kerberos
|
||||
Source5: ssh.reg
|
||||
Source6: ssh-askpass
|
||||
Source7: sshd.fw
|
||||
Source8: sysconfig.ssh
|
||||
Source9: sshd-gen-keys-start
|
||||
Source10: sshd.service
|
||||
Patch1: openssh-6.5p1-key-converter.patch
|
||||
Patch2: openssh-6.5p1-X11-forwarding.patch
|
||||
Patch3: openssh-6.5p1-lastlog.patch
|
||||
Patch4: openssh-6.5p1-pam-fix2.patch
|
||||
Patch5: openssh-6.5p1-saveargv-fix.patch
|
||||
Patch6: openssh-6.5p1-pam-fix3.patch
|
||||
Patch7: openssh-6.5p1-gssapimitm.patch
|
||||
Patch8: openssh-6.5p1-eal3.patch
|
||||
Patch9: openssh-6.5p1-blocksigalrm.patch
|
||||
Patch10: openssh-6.5p1-send_locale.patch
|
||||
Patch11: openssh-6.5p1-xauthlocalhostname.patch
|
||||
Patch12: openssh-6.5p1-xauth.patch
|
||||
Patch13: openssh-6.5p1-default-protocol.patch
|
||||
Patch14: openssh-6.5p1-pts.patch
|
||||
Patch15: openssh-6.5p1-pam-check-locks.patch
|
||||
Patch16: openssh-6.5p1-fingerprint_hash.patch
|
||||
Patch17: openssh-6.5p1-audit1-remove_duplicit_audit.patch
|
||||
Patch18: openssh-6.5p1-audit2-better_audit_of_user_actions.patch
|
||||
Patch19: openssh-6.5p1-audit3-key_auth_usage.patch
|
||||
Patch20: openssh-6.5p1-audit4-kex_results.patch
|
||||
Patch21: openssh-6.5p1-audit5-session_key_destruction.patch
|
||||
Patch22: openssh-6.5p1-audit6-server_key_destruction.patch
|
||||
Patch23: openssh-6.5p1-audit7-libaudit_compat.patch
|
||||
Patch24: openssh-6.5p1-audit8-libaudit_dns_timeouts.patch
|
||||
Patch25: openssh-6.5p1-seed-prng.patch
|
||||
Patch26: openssh-6.5p1-ldap.patch
|
||||
Patch27: openssh-6.5p1-fips.patch
|
||||
Patch28: openssh-6.5p1-gssapi_key_exchange.patch
|
||||
Patch29: openssh-6.5p1-login_options.patch
|
||||
Patch30: openssh-6.5p1-disable-openssl-abi-check.patch
|
||||
Patch31: openssh-6.5p1-no_fork-no_pid_file.patch
|
||||
Patch32: openssh-6.5p1-host_ident.patch
|
||||
Patch33: openssh-6.5p1-sftp_homechroot.patch
|
||||
Patch34: openssh-6.5p1-sftp_force_permissions.patch
|
||||
|
||||
%{!?_initddir:%global _initddir %{_initrddir}}
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
|
||||
%description
|
||||
SSH (Secure Shell) is a program for logging into and executing commands
|
||||
@ -91,119 +154,185 @@ hosts over an insecure network.
|
||||
xorg-x11 (X Window System) connections and arbitrary TCP/IP ports can
|
||||
also be forwarded over the secure channel.
|
||||
|
||||
|
||||
%package helpers
|
||||
Summary: OpenSSH AuthorizedKeysCommand helpers
|
||||
Group: Productivity/Networking/SSH
|
||||
Requires: openldap2
|
||||
Requires: openssh
|
||||
|
||||
%description helpers
|
||||
Helper applications for OpenSSH which retrieve keys from various sources.
|
||||
|
||||
|
||||
%prep
|
||||
%setup -q -a 5
|
||||
%patch
|
||||
%patch2
|
||||
%patch3
|
||||
%patch4
|
||||
%patch5
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8
|
||||
%patch9
|
||||
%patch10
|
||||
%patch12
|
||||
%patch14
|
||||
%patch15 -p1
|
||||
%patch16
|
||||
%patch17
|
||||
%patch18
|
||||
%patch19 -p1
|
||||
%patch20
|
||||
%patch21
|
||||
%patch22
|
||||
cp -v %{SOURCE4} .
|
||||
cp -v %{SOURCE6} .
|
||||
%setup -q
|
||||
#patch1 -p2
|
||||
%patch2 -p2
|
||||
%patch3 -p2
|
||||
%patch4 -p2
|
||||
%patch5 -p2
|
||||
%patch6 -p2
|
||||
%patch7 -p2
|
||||
%patch8 -p2
|
||||
%patch9 -p2
|
||||
%patch10 -p2
|
||||
%patch11 -p2
|
||||
%patch12 -p2
|
||||
%patch13 -p2
|
||||
%patch14 -p2
|
||||
%patch15 -p2
|
||||
%patch16 -p2
|
||||
%patch17 -p2
|
||||
%patch18 -p2
|
||||
%patch19 -p2
|
||||
%patch20 -p2
|
||||
%patch21 -p2
|
||||
%patch22 -p2
|
||||
%patch23 -p2
|
||||
%patch24 -p2
|
||||
%patch25 -p2
|
||||
%patch26 -p2
|
||||
#patch27 -p2
|
||||
#patch28 -p2
|
||||
%patch29 -p2
|
||||
%patch30 -p2
|
||||
%patch31 -p2
|
||||
%patch32 -p2
|
||||
%patch33 -p2
|
||||
%patch34 -p2
|
||||
cp %{SOURCE3} %{SOURCE4} .
|
||||
|
||||
%build
|
||||
# set libexec dir in the LDAP patch
|
||||
sed -i.libexec 's,@LIBEXECDIR@,%{_libexecdir}/ssh,' \
|
||||
$( grep -Rl @LIBEXECDIR@ \
|
||||
$( grep "^+++" %{PATCH26} | sed -r 's@^.+/([^/\t ]+).*$@\1@' )
|
||||
)
|
||||
|
||||
autoreconf -fiv
|
||||
%ifarch s390 s390x %sparc
|
||||
PIEFLAGS="-fPIE"
|
||||
%else
|
||||
PIEFLAGS="-fpie"
|
||||
%endif
|
||||
export CFLAGS="%{optflags} $PIEFLAGS -fstack-protector"
|
||||
export CXXFLAGS="%{optflags} $PIEFLAGS -fstack-protector"
|
||||
export LDFLAGS="-pie"
|
||||
%configure \
|
||||
%if 0%{?has_systemd}
|
||||
--with-pid-dir=/run \
|
||||
%endif
|
||||
--with-ssl-engine \
|
||||
%if 0%{suse_version} >= 1140
|
||||
--with-libedit \
|
||||
%endif
|
||||
CFLAGS="%{optflags} $PIEFLAGS -fstack-protector"
|
||||
#%if 0%{?suse_version} < 1230
|
||||
#CFLAGS="-lrt $CFLAGS"
|
||||
#%endif
|
||||
CXXFLAGS="%{optflags} $PIEFLAGS -fstack-protector"
|
||||
LDFLAGS="-pie -Wl,--as-needed"
|
||||
#%if 0%{?suse_version} < 1230
|
||||
#LDFLAGS="-lrt $LDFLAGS"
|
||||
#%endif
|
||||
#CPPFLAGS="%{optflags} -DUSE_INTERNAL_B64"
|
||||
export LDFLAGS CFLAGS CXXFLAGS CPPFLAGS
|
||||
./configure \
|
||||
--prefix=%{_prefix} \
|
||||
--mandir=%{_mandir} \
|
||||
--infodir=%{_infodir} \
|
||||
--sysconfdir=%{_sysconfdir}/ssh \
|
||||
--libexecdir=%{_libexecdir}/ssh \
|
||||
--with-tcp-wrappers \
|
||||
%if 0%{suse_version} > 1100
|
||||
%if %{has_libselinux}
|
||||
--with-selinux \
|
||||
%endif
|
||||
%if %{uses_systemd}
|
||||
--with-pid-dir=/run \
|
||||
%endif
|
||||
--with-ssl-engine \
|
||||
--with-pam \
|
||||
--with-kerberos5=/usr \
|
||||
--with-kerberos5=%{_prefix} \
|
||||
--with-privsep-path=/var/lib/empty \
|
||||
%if %{sandbox_seccomp}
|
||||
--with-sandbox=seccomp_filter \
|
||||
%else
|
||||
--with-sandbox=rlimit \
|
||||
%endif
|
||||
%ifnarch s390 s390x
|
||||
--with-opensc \
|
||||
%endif
|
||||
--disable-strip \
|
||||
--with-linux-audit \
|
||||
--with-xauth=%{_prefix}/bin/xauth \
|
||||
--target=%{_target_cpu}-suse-linux
|
||||
# --with-afs=/usr \
|
||||
--with-audit=linux \
|
||||
--with-ldap \
|
||||
--with-xauth=%{_bindir}/xauth \
|
||||
%if %{needs_libedit}
|
||||
--with-libedit \
|
||||
%endif
|
||||
--target=%{_target_cpu}-suse-linux \
|
||||
|
||||
### configure end
|
||||
make %{?_smp_mflags}
|
||||
(cd converter; make %{?_smp_mflags})
|
||||
|
||||
#make %{?_smp_mflags} -C converter
|
||||
|
||||
%install
|
||||
make DESTDIR=%{buildroot}/ install
|
||||
make install DESTDIR=%{buildroot}
|
||||
#make install DESTDIR=%{buildroot} -C converter
|
||||
|
||||
install -d -m 755 %{buildroot}%{_sysconfdir}/pam.d
|
||||
install -d -m 755 %{buildroot}/var/lib/sshd
|
||||
install -m 644 %{S:2} %{buildroot}%{_sysconfdir}/pam.d/sshd
|
||||
install -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/pam.d/sshd
|
||||
install -d -m 755 %{buildroot}%{_sysconfdir}/slp.reg.d/
|
||||
install -m 644 %{S:7} %{buildroot}%{_sysconfdir}/slp.reg.d/
|
||||
install -m 644 %{SOURCE5} %{buildroot}%{_sysconfdir}/slp.reg.d/
|
||||
install -d -m 755 %{buildroot}%{_initddir}
|
||||
install -m 755 %{S:1} %{buildroot}%{_initddir}/sshd
|
||||
ln -vs ../..%{_initddir}/sshd %{buildroot}%{_sbindir}/rcsshd
|
||||
%if %{uses_systemd}
|
||||
install -m 0755 %{SOURCE1} .
|
||||
install -D -m 0644 %{SOURCE10} %{buildroot}%{_unitdir}/sshd.service
|
||||
ln -s /usr/sbin/service %{buildroot}%{_sbindir}/rcsshd
|
||||
%else
|
||||
install -D -m 0755 %{SOURCE1} %{buildroot}%{_initddir}/sshd
|
||||
install -m 0644 %{SOURCE10} .
|
||||
ln -s ../..%{_initddir}/sshd %{buildroot}%{_sbindir}/rcsshd
|
||||
%endif
|
||||
install -d -m 755 %{buildroot}/var/adm/fillup-templates
|
||||
install -m 644 %{S:10} %{buildroot}/var/adm/fillup-templates
|
||||
install -m 644 %{SOURCE8} %{buildroot}/var/adm/fillup-templates
|
||||
# install shell script to automate the process of adding your public key to a remote machine
|
||||
install -m 755 contrib/ssh-copy-id %{buildroot}%{_bindir}
|
||||
install -m 644 contrib/ssh-copy-id.1 %{buildroot}%{_mandir}/man1
|
||||
sed -e "s,@LIBEXEC@,%{_libexecdir},g" < %{S:8} > %{buildroot}%{_libexecdir}/ssh/ssh-askpass
|
||||
( cd converter; make install DESTDIR=%{buildroot} )
|
||||
rm -f %{buildroot}%{_datadir}/Ssh.bin
|
||||
sed -i -e s@/usr/libexec@%{_libexecdir}@g %{buildroot}%{_sysconfdir}/ssh/sshd_config
|
||||
|
||||
%if %{has_fw_dir}
|
||||
#install firewall definitions format is described here:
|
||||
#%{_datadir}/SuSEfirewall2/services/TEMPLATE
|
||||
mkdir -p %{buildroot}%{_fwdefdir}
|
||||
install -m 644 %{S:9} %{buildroot}%{_fwdefdir}/sshd
|
||||
%if 0%{?has_systemd}
|
||||
install -D -m 0755 %{SOURCE11} %{buildroot}%{_sbindir}/sshd-gen-keys-start
|
||||
install -D -m 0644 %{SOURCE12} %{buildroot}%{_unitdir}/sshd.service
|
||||
install -m 644 %{SOURCE7} %{buildroot}%{_fwdefdir}/sshd
|
||||
%endif
|
||||
|
||||
# askpass wrapper
|
||||
sed -e "s,@LIBEXECDIR@,%{_libexecdir},g" < %{SOURCE6} > %{buildroot}%{_libexecdir}/ssh/ssh-askpass
|
||||
rm -f %{buildroot}%{_datadir}/Ssh.bin
|
||||
# sshd keys generator wrapper
|
||||
install -D -m 0755 %{SOURCE9} %{buildroot}%{_sbindir}/sshd-gen-keys-start
|
||||
|
||||
%pre
|
||||
getent group sshd >/dev/null || %{_sbindir}/groupadd -r sshd
|
||||
getent passwd sshd >/dev/null || %{_sbindir}/useradd -r -g sshd -d /var/lib/sshd -s /bin/false -c "SSH daemon" sshd
|
||||
%if 0%{?has_systemd}
|
||||
%if %{uses_systemd}
|
||||
%service_add_pre sshd.service
|
||||
%endif
|
||||
|
||||
%post
|
||||
%{fillup_and_insserv -n ssh sshd}
|
||||
%if 0%{?has_systemd}
|
||||
%if %{uses_systemd}
|
||||
%{fillup_only -n ssh sshd}
|
||||
%service_add_post sshd.service
|
||||
%else
|
||||
%{fillup_and_insserv -n ssh sshd}
|
||||
%endif
|
||||
|
||||
%preun
|
||||
%stop_on_removal sshd
|
||||
%if 0%{?has_systemd}
|
||||
%if %{uses_systemd}
|
||||
%service_del_preun sshd.service
|
||||
%else
|
||||
%stop_on_removal sshd
|
||||
%endif
|
||||
|
||||
%postun
|
||||
%if %{uses_systemd}
|
||||
%service_del_postun sshd.service
|
||||
%else
|
||||
%restart_on_update sshd
|
||||
%{insserv_cleanup}
|
||||
%if 0%{?has_systemd}
|
||||
%service_del_postun sshd.service
|
||||
%endif
|
||||
|
||||
%files
|
||||
@ -212,40 +341,41 @@ getent passwd sshd >/dev/null || %{_sbindir}/useradd -r -g sshd -d /var/lib/sshd
|
||||
%doc README.SuSE README.kerberos ChangeLog OVERVIEW README TODO LICENCE CREDITS
|
||||
%attr(0755,root,root) %dir %{_sysconfdir}/ssh
|
||||
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config
|
||||
%attr(0640,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config
|
||||
%attr(0644,root,root) %config %{_sysconfdir}/pam.d/sshd
|
||||
%verify(not mode) %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config
|
||||
%verify(not mode) %attr(0640,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/pam.d/sshd
|
||||
%if %{uses_systemd}
|
||||
%doc sshd.init
|
||||
%attr(0644,root,root) %config %{_unitdir}/sshd.service
|
||||
%else
|
||||
%attr(0755,root,root) %config %{_initddir}/sshd
|
||||
%attr(0755,root,root) %{_bindir}/ssh
|
||||
%{_bindir}/scp
|
||||
%{_bindir}/sftp
|
||||
%{_bindir}/slogin
|
||||
%{_bindir}/ssh-*
|
||||
%{_sbindir}/*
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/scp.1.gz
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/ssh-keygen.1.gz
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/ssh-keyconverter.1.gz
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/ssh.1.gz
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/slogin.1.gz
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/ssh-agent.1*
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/ssh-add.1*
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/ssh-keyscan.1*
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/sftp.1*
|
||||
%attr(444,root,root) %doc %{_mandir}/man1/ssh-copy-id.1*
|
||||
%attr(444,root,root) %doc %{_mandir}/man5/*
|
||||
%attr(444,root,root) %doc %{_mandir}/man8/*
|
||||
%doc sshd.service
|
||||
%endif
|
||||
%attr(0755,root,root) %{_bindir}/*
|
||||
%attr(0755,root,root) %{_sbindir}/*
|
||||
%attr(0755,root,root) %dir %{_libexecdir}/ssh
|
||||
%attr(0755,root,root) %{_libexecdir}/ssh/sftp-server
|
||||
%attr(0755,root,root) %{_libexecdir}/ssh/ssh-keysign
|
||||
%attr(0755,root,root) %{_libexecdir}/ssh/ssh-pkcs11-helper
|
||||
%attr(0755,root,root) %{_libexecdir}/ssh/ssh-askpass
|
||||
%exclude %{_libexecdir}/ssh/ssh-ldap*
|
||||
%attr(0755,root,root) %{_libexecdir}/ssh/*
|
||||
%attr(0444,root,root) %doc %{_mandir}/man1/*
|
||||
%attr(0444,root,root) %doc %{_mandir}/man5/*
|
||||
%attr(0444,root,root) %doc %{_mandir}/man8/*
|
||||
%dir %{_sysconfdir}/slp.reg.d
|
||||
%config %{_sysconfdir}/slp.reg.d/ssh.reg
|
||||
/var/adm/fillup-templates/sysconfig.ssh
|
||||
%if %{has_fw_dir}
|
||||
%if %{needs_all_dirs}
|
||||
%dir %{_fwdir}
|
||||
%dir %{_fwdefdir}
|
||||
%endif
|
||||
%config %{_fwdefdir}/sshd
|
||||
%if 0%{?has_systemd}
|
||||
%{_sbindir}/sshd-gen-keys-start
|
||||
%{_unitdir}/sshd.service
|
||||
%endif
|
||||
|
||||
%files helpers
|
||||
%defattr(-,root,root)
|
||||
%attr(0755,root,root) %dir %{_sysconfdir}/ssh
|
||||
%verify(not mode) %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ldap.conf
|
||||
%attr(0755,root,root) %dir %{_libexecdir}/ssh
|
||||
%attr(0755,root,root) %{_libexecdir}/ssh/ssh-ldap*
|
||||
%doc HOWTO.ldap-keys openssh-lpk-openldap.schema openssh-lpk-sun.schema
|
||||
|
||||
%changelog
|
||||
|
@ -24,9 +24,9 @@ if [ -z "$SESSION" ] ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
GNOME_SSH_ASKPASS="@LIBEXEC@/ssh/gnome-ssh-askpass"
|
||||
KDE_SSH_ASKPASS="@LIBEXEC@/ssh/ksshaskpass"
|
||||
X11_SSH_ASKPASS="@LIBEXEC@/ssh/x11-ssh-askpass"
|
||||
GNOME_SSH_ASKPASS="@LIBEXECDIR@/ssh/gnome-ssh-askpass"
|
||||
KDE_SSH_ASKPASS="@LIBEXECDIR@/ssh/ksshaskpass"
|
||||
X11_SSH_ASKPASS="@LIBEXECDIR@/ssh/x11-ssh-askpass"
|
||||
|
||||
case "$SESSION" in
|
||||
gnome)
|
||||
|
@ -1,21 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! grep -q '^[[:space:]]*HostKey[[:space:]]' /etc/ssh/sshd_config; then
|
||||
if ! test -f /etc/ssh/ssh_host_key ; then
|
||||
echo Generating /etc/ssh/ssh_host_key.
|
||||
ssh-keygen -t rsa1 -b 2048 -f /etc/ssh/ssh_host_key -N ''
|
||||
fi
|
||||
if ! test -f /etc/ssh/ssh_host_dsa_key ; then
|
||||
echo Generating /etc/ssh/ssh_host_dsa_key.
|
||||
ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''
|
||||
fi
|
||||
if ! test -f /etc/ssh/ssh_host_rsa_key ; then
|
||||
echo Generating /etc/ssh/ssh_host_rsa_key.
|
||||
ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N ''
|
||||
fi
|
||||
if ! test -f /etc/ssh/ssh_host_ecdsa_key ; then
|
||||
echo Generating /etc/ssh/ssh_host_ecdsa_key.
|
||||
ssh-keygen -t ecdsa -b 256 -f /etc/ssh/ssh_host_ecdsa_key -N ''
|
||||
fi
|
||||
fi
|
||||
|
||||
#!/bin/sh
|
||||
if ! grep -q '^[[:space:]]*HostKey[[:space:]]' /etc/ssh/sshd_config; then
|
||||
echo "Checking for missing server keys in /etc/ssh"
|
||||
ssh-keygen -A
|
||||
fi
|
||||
|
118
sshd.init
118
sshd.init
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# Copyright (c) 1995-2000 SuSE GmbH Nuernberg, Germany.
|
||||
# Copyright (c) 1995-2013 SuSE GmbH Nuernberg, Germany.
|
||||
#
|
||||
# Author: Jiri Smid <feedback@suse.de>
|
||||
#
|
||||
@ -13,10 +13,10 @@
|
||||
# Provides: sshd
|
||||
# Required-Start: $network $remote_fs
|
||||
# Required-Stop: $network $remote_fs
|
||||
# Should-Start: haveged auditd
|
||||
# Default-Start: 3 5
|
||||
# Default-Stop: 0 1 2 6
|
||||
# Description: Start the sshd daemon
|
||||
# Short-Description: Start the sshd daemon
|
||||
### END INIT INFO
|
||||
|
||||
SSHD_BIN=/usr/sbin/sshd
|
||||
@ -39,48 +39,60 @@ SSHD_PIDFILE=/var/run/sshd.init.pid
|
||||
# rc_reset clear local rc status (overall remains)
|
||||
# rc_exit exit appropriate to overall rc status
|
||||
|
||||
function soft_stop () {
|
||||
echo -n "Shutting down the listening SSH daemon"
|
||||
killproc -p $SSHD_PIDFILE -TERM $SSHD_BIN
|
||||
}
|
||||
|
||||
function force_stop () {
|
||||
echo -n "Shutting down SSH daemon *with all active connections*"
|
||||
trap '' TERM
|
||||
killall sshd 2>/dev/null
|
||||
trap - TERM
|
||||
}
|
||||
|
||||
# First reset status of this service
|
||||
rc_reset
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
if ! grep -q '^[[:space:]]*HostKey[[:space:]]' /etc/ssh/sshd_config; then
|
||||
if ! test -f /etc/ssh/ssh_host_key ; then
|
||||
echo Generating /etc/ssh/ssh_host_key.
|
||||
ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N ''
|
||||
fi
|
||||
if ! test -f /etc/ssh/ssh_host_dsa_key ; then
|
||||
echo Generating /etc/ssh/ssh_host_dsa_key.
|
||||
ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''
|
||||
fi
|
||||
if ! test -f /etc/ssh/ssh_host_rsa_key ; then
|
||||
echo Generating /etc/ssh/ssh_host_rsa_key.
|
||||
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''
|
||||
fi
|
||||
if ! test -f /etc/ssh/ssh_host_ecdsa_key ; then
|
||||
echo Generating /etc/ssh/ssh_host_ecdsa_key.
|
||||
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''
|
||||
fi
|
||||
fi
|
||||
echo -n "Starting SSH daemon"
|
||||
## Start daemon with startproc(8). If this fails
|
||||
## the echo return value is set appropriate.
|
||||
/usr/sbin/sshd-gen-keys-start
|
||||
echo -n "Starting SSH daemon"
|
||||
## Start daemon with startproc(8). If this fails
|
||||
## the echo return value is set appropriate.
|
||||
startproc -f -p $SSHD_PIDFILE $SSHD_BIN $SSHD_OPTS -o "PidFile=$SSHD_PIDFILE"
|
||||
|
||||
startproc -f $SSHD_BIN $SSHD_OPTS -o "PidFile=$SSHD_PIDFILE"
|
||||
|
||||
# Remember status and be verbose
|
||||
rc_status -v
|
||||
;;
|
||||
# Remember status and be verbose
|
||||
rc_status -v
|
||||
;;
|
||||
stop)
|
||||
echo -n "Shutting down SSH daemon"
|
||||
## Stop daemon with killproc(8) and if this fails
|
||||
## set echo the echo return value.
|
||||
# If we're shutting down, kill active sshd connections so they're not
|
||||
# left hanging.
|
||||
runlevel=$(set -- $(runlevel); eval "echo \$$#")
|
||||
if [ "x$runlevel" = x0 -o "x$runlevel" = x6 ] ; then
|
||||
force_stop
|
||||
else
|
||||
soft_stop
|
||||
fi
|
||||
|
||||
# Remember status and be verbose
|
||||
rc_status -v
|
||||
;;
|
||||
soft-stop)
|
||||
## Stop the listener daemon process with killproc(8) and if this
|
||||
## fails set echo the echo return value.
|
||||
soft_stop
|
||||
|
||||
killproc -p $SSHD_PIDFILE -TERM $SSHD_BIN
|
||||
# Remember status and be verbose
|
||||
rc_status -v
|
||||
;;
|
||||
force-stop)
|
||||
## stop all running ssh
|
||||
force_stop
|
||||
|
||||
# Remember status and be verbose
|
||||
rc_status -v
|
||||
;;
|
||||
# Remember status and be verbose
|
||||
rc_status -v
|
||||
;;
|
||||
try-restart)
|
||||
## Stop the service and if this succeeds (i.e. the
|
||||
## service was running before), start it again.
|
||||
@ -90,27 +102,27 @@ case "$1" in
|
||||
rc_status
|
||||
;;
|
||||
restart)
|
||||
## Stop the service and regardless of whether it was
|
||||
## running or not, start it again.
|
||||
$0 stop
|
||||
## Stop the service without closing live connections
|
||||
## and start it again regardless of whether it was
|
||||
## running or not
|
||||
$0 soft-stop
|
||||
$0 start
|
||||
|
||||
# Remember status and be quiet
|
||||
rc_status
|
||||
;;
|
||||
force-reload|reload)
|
||||
## Signal the daemon to reload its config. Most daemons
|
||||
## do this on signal 1 (SIGHUP).
|
||||
## Signal the daemon to reload its config. Most daemons
|
||||
## do this on signal 1 (SIGHUP).
|
||||
echo -n "Reload service sshd"
|
||||
|
||||
echo -n "Reload service sshd"
|
||||
|
||||
killproc -p $SSHD_PIDFILE -HUP $SSHD_BIN
|
||||
killproc -p $SSHD_PIDFILE -HUP $SSHD_BIN
|
||||
|
||||
rc_status -v
|
||||
|
||||
;;
|
||||
status)
|
||||
echo -n "Checking for service sshd "
|
||||
echo -n "Checking for service sshd "
|
||||
## Check status with checkproc(8), if process is running
|
||||
## checkproc will return with exit status 0.
|
||||
|
||||
@ -120,19 +132,19 @@ case "$1" in
|
||||
# 2 - service dead, but /var/lock/ lock file exists
|
||||
# 3 - service not running
|
||||
|
||||
checkproc -p $SSHD_PIDFILE $SSHD_BIN
|
||||
checkproc -p $SSHD_PIDFILE $SSHD_BIN
|
||||
|
||||
rc_status -v
|
||||
;;
|
||||
rc_status -v
|
||||
;;
|
||||
probe)
|
||||
## Optional: Probe for the necessity of a reload,
|
||||
## give out the argument which is required for a reload.
|
||||
## Optional: Probe for the necessity of a reload,
|
||||
## give out the argument which is required for a reload.
|
||||
|
||||
test /etc/ssh/sshd_config -nt $SSHD_PIDFILE && echo reload
|
||||
;;
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
|
||||
exit 1
|
||||
;;
|
||||
echo "Usage: $0 {start|stop|soft-stop|force-stop|status|try-restart|restart|force-reload|reload|probe}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
rc_exit
|
||||
|
14
sshd.pamd
14
sshd.pamd
@ -1,9 +1,9 @@
|
||||
#%PAM-1.0
|
||||
auth requisite pam_nologin.so
|
||||
auth include common-auth
|
||||
account requisite pam_nologin.so
|
||||
account include common-account
|
||||
password include common-password
|
||||
session required pam_loginuid.so
|
||||
session include common-session
|
||||
auth requisite pam_nologin.so
|
||||
auth include common-auth
|
||||
account requisite pam_nologin.so
|
||||
account include common-account
|
||||
password include common-password
|
||||
session required pam_loginuid.so
|
||||
session include common-session
|
||||
session optional pam_lastlog.so silent noupdate showfailed
|
||||
|
@ -3,7 +3,7 @@ Description=OpenSSH Daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/etc/sysconfig/ssh
|
||||
EnvironmentFile=-/etc/sysconfig/ssh
|
||||
ExecStartPre=/usr/sbin/sshd-gen-keys-start
|
||||
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
Loading…
Reference in New Issue
Block a user