![basebuilder@powerel.org](/assets/img/avatar_default.png)
119 changed files with 33888 additions and 0 deletions
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-7.4p1/contrib/gnome-ssh-askpass2.c |
||||
--- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info 2016-12-23 13:31:22.645213115 +0100 |
||||
+++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:40.997216691 +0100 |
||||
@@ -65,9 +65,12 @@ report_failed_grab (GtkWidget *parent_wi |
||||
err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, |
||||
GTK_MESSAGE_ERROR, |
||||
GTK_BUTTONS_CLOSE, |
||||
- "Could not grab %s. " |
||||
- "A malicious client may be eavesdropping " |
||||
- "on your session.", what); |
||||
+ "SSH password dialog could not grab the %s input.\n" |
||||
+ "This might be caused by application such as screensaver, " |
||||
+ "however it could also mean that someone may be eavesdropping " |
||||
+ "on your session.\n" |
||||
+ "Either close the application which grabs the %s or " |
||||
+ "log out and log in again to prevent this from happening.", what, what); |
||||
gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); |
||||
|
||||
gtk_dialog_run(GTK_DIALOG(err)); |
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contrib/gnome-ssh-askpass2.c |
||||
--- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c 2016-12-23 13:31:16.545211926 +0100 |
||||
@@ -53,6 +53,7 @@ |
||||
#include <string.h> |
||||
#include <unistd.h> |
||||
#include <X11/Xlib.h> |
||||
+#include <glib.h> |
||||
#include <gtk/gtk.h> |
||||
#include <gdk/gdkx.h> |
||||
|
||||
@@ -81,13 +82,24 @@ ok_dialog(GtkWidget *entry, gpointer dia |
||||
gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); |
||||
} |
||||
|
||||
+static void |
||||
+move_progress(GtkWidget *entry, gpointer progress) |
||||
+{ |
||||
+ gdouble step; |
||||
+ g_return_if_fail(GTK_IS_PROGRESS_BAR(progress)); |
||||
+ |
||||
+ step = g_random_double_range(0.03, 0.1); |
||||
+ gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress), step); |
||||
+ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress)); |
||||
+} |
||||
+ |
||||
static int |
||||
passphrase_dialog(char *message) |
||||
{ |
||||
const char *failed; |
||||
char *passphrase, *local; |
||||
int result, grab_tries, grab_server, grab_pointer; |
||||
- GtkWidget *parent_window, *dialog, *entry; |
||||
+ GtkWidget *parent_window, *dialog, *entry, *progress, *hbox; |
||||
GdkGrabStatus status; |
||||
|
||||
grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); |
||||
@@ -104,14 +116,32 @@ passphrase_dialog(char *message) |
||||
"%s", |
||||
message); |
||||
|
||||
+ hbox = gtk_hbox_new(FALSE, 0); |
||||
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, |
||||
+ FALSE, 0); |
||||
+ gtk_widget_show(hbox); |
||||
+ |
||||
entry = gtk_entry_new(); |
||||
gtk_box_pack_start( |
||||
- GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry, |
||||
- FALSE, FALSE, 0); |
||||
+ GTK_BOX(hbox), entry, |
||||
+ TRUE, FALSE, 0); |
||||
+ gtk_entry_set_width_chars(GTK_ENTRY(entry), 2); |
||||
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); |
||||
gtk_widget_grab_focus(entry); |
||||
gtk_widget_show(entry); |
||||
|
||||
+ hbox = gtk_hbox_new(FALSE, 0); |
||||
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, |
||||
+ FALSE, 8); |
||||
+ gtk_widget_show(hbox); |
||||
+ |
||||
+ progress = gtk_progress_bar_new(); |
||||
+ |
||||
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally"); |
||||
+ gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE, |
||||
+ TRUE, 5); |
||||
+ gtk_widget_show(progress); |
||||
+ |
||||
gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); |
||||
gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); |
||||
gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); |
||||
@@ -120,6 +150,8 @@ passphrase_dialog(char *message) |
||||
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); |
||||
g_signal_connect(G_OBJECT(entry), "activate", |
||||
G_CALLBACK(ok_dialog), dialog); |
||||
+ g_signal_connect(G_OBJECT(entry), "changed", |
||||
+ G_CALLBACK(move_progress), progress); |
||||
|
||||
gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); |
||||
|
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
diff -up openssh-5.1p1/scp.1.manpage openssh-5.1p1/scp.1 |
||||
--- openssh-5.1p1/scp.1.manpage 2008-07-12 09:12:49.000000000 +0200 |
||||
+++ openssh-5.1p1/scp.1 2008-07-23 19:18:15.000000000 +0200 |
||||
@@ -66,6 +66,14 @@ treating file names containing |
||||
as host specifiers. |
||||
Copies between two remote hosts are also permitted. |
||||
.Pp |
||||
+When copying a source file to a target file which already exists, |
||||
+.Nm |
||||
+will replace the contents of the target file (keeping the inode). |
||||
+.Pp |
||||
+If the target file does not yet exist, an empty file with the target |
||||
+file name is created, then filled with the source file contents. |
||||
+No attempt is made at "near-atomic" transfer using temporary files. |
||||
+.Pp |
||||
The options are as follows: |
||||
.Bl -tag -width Ds |
||||
.It Fl 1 |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c |
||||
--- openssh-5.3p1/channels.c.bz595935 2010-08-12 14:19:28.000000000 +0200 |
||||
+++ openssh-5.3p1/channels.c 2010-08-12 14:33:51.000000000 +0200 |
||||
@@ -3990,21 +3990,24 @@ x11_create_display_inet(int x11_display_ |
||||
} |
||||
|
||||
static int |
||||
-connect_local_xsocket_path(const char *pathname) |
||||
+connect_local_xsocket_path(const char *pathname, int len) |
||||
{ |
||||
int sock; |
||||
struct sockaddr_un addr; |
||||
|
||||
+ if (len <= 0) |
||||
+ return -1; |
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0); |
||||
if (sock < 0) |
||||
error("socket: %.100s", strerror(errno)); |
||||
memset(&addr, 0, sizeof(addr)); |
||||
addr.sun_family = AF_UNIX; |
||||
- strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); |
||||
- if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) |
||||
+ if (len > sizeof addr.sun_path) |
||||
+ len = sizeof addr.sun_path; |
||||
+ memcpy(addr.sun_path, pathname, len); |
||||
+ if (connect(sock, (struct sockaddr *)&addr, sizeof addr - (sizeof addr.sun_path - len) ) == 0) |
||||
return sock; |
||||
close(sock); |
||||
- error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); |
||||
return -1; |
||||
} |
||||
|
||||
@@ -3207,8 +3210,18 @@ static int |
||||
connect_local_xsocket(u_int dnr) |
||||
{ |
||||
char buf[1024]; |
||||
- snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr); |
||||
- return connect_local_xsocket_path(buf); |
||||
+ int len, ret; |
||||
+ len = snprintf(buf + 1, sizeof (buf) - 1, _PATH_UNIX_X, dnr); |
||||
+#ifdef linux |
||||
+ /* try abstract socket first */ |
||||
+ buf[0] = '\0'; |
||||
+ if ((ret = connect_local_xsocket_path(buf, len + 1)) >= 0) |
||||
+ return ret; |
||||
+#endif |
||||
+ if ((ret = connect_local_xsocket_path(buf + 1, len)) >= 0) |
||||
+ return ret; |
||||
+ error("connect %.100s: %.100s", buf + 1, strerror(errno)); |
||||
+ return -1; |
||||
} |
||||
|
||||
int |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
diff -up openssh-5.6p1/channels.c.getaddrinfo openssh-5.6p1/channels.c |
||||
--- openssh-5.6p1/channels.c.getaddrinfo 2012-02-14 16:12:54.427852524 +0100 |
||||
+++ openssh-5.6p1/channels.c 2012-02-14 16:13:22.818928690 +0100 |
||||
@@ -3275,6 +3275,9 @@ x11_create_display_inet(int x11_display_ |
||||
memset(&hints, 0, sizeof(hints)); |
||||
hints.ai_family = IPv4or6; |
||||
hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; |
||||
+#ifdef AI_ADDRCONFIG |
||||
+ hints.ai_flags |= AI_ADDRCONFIG; |
||||
+#endif |
||||
hints.ai_socktype = SOCK_STREAM; |
||||
snprintf(strport, sizeof strport, "%d", port); |
||||
if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { |
||||
diff -up openssh-5.6p1/sshconnect.c.getaddrinfo openssh-5.6p1/sshconnect.c |
||||
--- openssh-5.6p1/sshconnect.c.getaddrinfo 2012-02-14 16:09:25.057964291 +0100 |
||||
+++ openssh-5.6p1/sshconnect.c 2012-02-14 16:09:25.106047007 +0100 |
||||
@@ -343,6 +343,7 @@ ssh_connect(const char *host, struct soc |
||||
memset(&hints, 0, sizeof(hints)); |
||||
hints.ai_family = family; |
||||
hints.ai_socktype = SOCK_STREAM; |
||||
+ hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; |
||||
snprintf(strport, sizeof strport, "%u", port); |
||||
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) |
||||
fatal("%s: Could not resolve hostname %.100s: %s", __progname, |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
diff -up openssh-5.8p1/sftp-glob.c.glob openssh-5.8p1/sftp-glob.c |
||||
--- openssh-5.8p1/sftp-glob.c.glob 2011-03-07 20:17:34.000000000 +0100 |
||||
+++ openssh-5.8p1/sftp-glob.c 2011-03-07 20:18:47.000000000 +0100 |
||||
@@ -145,5 +145,5 @@ remote_glob(struct sftp_conn *conn, cons |
||||
memset(&cur, 0, sizeof(cur)); |
||||
cur.conn = conn; |
||||
|
||||
- return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)); |
||||
+ return(glob(pattern, flags | GLOB_LIMIT | GLOB_ALTDIRFUNC, errfunc, pglob)); |
||||
} |
||||
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c |
||||
index 742b4b9..acae399 100644 |
||||
--- a/openbsd-compat/glob.c |
||||
+++ b/openbsd-compat/glob.c |
||||
@@ -130,8 +130,8 @@ typedef char Char; |
||||
#define M_CLASS META(':') |
||||
#define ismeta(c) (((c)&M_QUOTE) != 0) |
||||
|
||||
-#define GLOB_LIMIT_MALLOC 65536 |
||||
-#define GLOB_LIMIT_STAT 128 |
||||
+#define GLOB_LIMIT_MALLOC 65536*64 |
||||
+#define GLOB_LIMIT_STAT 128*64 |
||||
#define GLOB_LIMIT_READDIR 16384 |
||||
|
||||
/* Limit of recursion during matching attempts. */ |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff -up openssh-5.8p1/packet.c.packet openssh-5.8p1/packet.c |
||||
--- openssh-5.8p1/packet.c.packet 2011-04-05 13:29:06.998648899 +0200 |
||||
+++ openssh-5.8p1/packet.c 2011-04-05 13:30:32.967648596 +0200 |
||||
@@ -294,6 +294,8 @@ packet_connection_is_on_socket(void) |
||||
struct sockaddr_storage from, to; |
||||
socklen_t fromlen, tolen; |
||||
|
||||
+ if (!state) |
||||
+ return 0; |
||||
if (state->connection_in == -1 || state->connection_out == -1) |
||||
return 0; |
||||
|
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c |
||||
--- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200 |
||||
+++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200 |
||||
@@ -715,6 +715,8 @@ main(int argc, char **argv) |
||||
fdlim_set(maxfd); |
||||
fdcon = xcalloc(maxfd, sizeof(con)); |
||||
|
||||
+ signal(SIGPIPE, SIG_IGN); |
||||
+ |
||||
read_wait_nfdset = howmany(maxfd, NFDBITS); |
||||
read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); |
||||
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1 |
||||
--- openssh-5.9p0/ssh.1.ipv6man 2011-08-05 22:17:32.000000000 +0200 |
||||
+++ openssh-5.9p0/ssh.1 2011-08-31 13:08:34.880024485 +0200 |
||||
@@ -1400,6 +1400,8 @@ manual page for more information. |
||||
.Nm |
||||
exits with the exit status of the remote command or with 255 |
||||
if an error occurred. |
||||
+.Sh IPV6 |
||||
+IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. |
||||
.Sh SEE ALSO |
||||
.Xr scp 1 , |
||||
.Xr sftp 1 , |
||||
diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8 |
||||
--- openssh-5.9p0/sshd.8.ipv6man 2011-08-05 22:17:32.000000000 +0200 |
||||
+++ openssh-5.9p0/sshd.8 2011-08-31 13:10:34.129039094 +0200 |
||||
@@ -940,6 +940,8 @@ concurrently for different ports, this c |
||||
started last). |
||||
The content of this file is not sensitive; it can be world-readable. |
||||
.El |
||||
+.Sh IPV6 |
||||
+IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. |
||||
.Sh SEE ALSO |
||||
.Xr scp 1 , |
||||
.Xr sftp 1 , |
@ -0,0 +1,78 @@
@@ -0,0 +1,78 @@
|
||||
diff -up openssh-5.9p1/Makefile.in.wIm openssh-5.9p1/Makefile.in |
||||
--- openssh-5.9p1/Makefile.in.wIm 2011-08-05 22:15:18.000000000 +0200 |
||||
+++ openssh-5.9p1/Makefile.in 2011-09-12 16:24:18.643674014 +0200 |
||||
@@ -66,7 +66,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o b |
||||
cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ |
||||
compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ |
||||
log.o match.o md-sha256.o moduli.o nchan.o packet.o \ |
||||
- readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ |
||||
+ readpass.o rsa.o ttymodes.o whereIam.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 \ |
||||
diff -up openssh-5.9p1/log.h.wIm openssh-5.9p1/log.h |
||||
--- openssh-5.9p1/log.h.wIm 2011-06-20 06:42:23.000000000 +0200 |
||||
+++ openssh-5.9p1/log.h 2011-09-12 16:34:52.984674326 +0200 |
||||
@@ -65,6 +65,8 @@ void verbose(const char *, ...) __at |
||||
void debug(const char *, ...) __attribute__((format(printf, 1, 2))); |
||||
void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); |
||||
void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); |
||||
+void _debug_wIm_body(const char *, int, const char *, const char *, int); |
||||
+#define debug_wIm(a,b) _debug_wIm_body(a,b,__func__,__FILE__,__LINE__) |
||||
|
||||
|
||||
void set_log_handler(log_handler_fn *, void *); |
||||
diff -up openssh-5.9p1/sshd.c.wIm openssh-5.9p1/sshd.c |
||||
--- openssh-5.9p1/sshd.c.wIm 2011-06-23 11:45:51.000000000 +0200 |
||||
+++ openssh-5.9p1/sshd.c 2011-09-12 16:38:35.787816490 +0200 |
||||
@@ -140,6 +140,9 @@ int deny_severity; |
||||
|
||||
extern char *__progname; |
||||
|
||||
+/* trace of fork processes */ |
||||
+extern int whereIam; |
||||
+ |
||||
/* Server configuration options. */ |
||||
ServerOptions options; |
||||
|
||||
@@ -666,6 +669,7 @@ privsep_preauth(Authctxt *authctxt) |
||||
return 1; |
||||
} else { |
||||
/* child */ |
||||
+ whereIam = 1; |
||||
close(pmonitor->m_sendfd); |
||||
close(pmonitor->m_log_recvfd); |
||||
|
||||
@@ -715,6 +719,7 @@ privsep_postauth(Authctxt *authctxt) |
||||
|
||||
/* child */ |
||||
|
||||
+ whereIam = 2; |
||||
close(pmonitor->m_sendfd); |
||||
pmonitor->m_sendfd = -1; |
||||
|
||||
@@ -1325,6 +1330,8 @@ main(int ac, char **av) |
||||
Key *key; |
||||
Authctxt *authctxt; |
||||
|
||||
+ whereIam = 0; |
||||
+ |
||||
#ifdef HAVE_SECUREWARE |
||||
(void)set_auth_parameters(ac, av); |
||||
#endif |
||||
diff -up openssh-5.9p1/whereIam.c.wIm openssh-5.9p1/whereIam.c |
||||
--- openssh-5.9p1/whereIam.c.wIm 2011-09-12 16:24:18.722674167 +0200 |
||||
+++ openssh-5.9p1/whereIam.c 2011-09-12 16:24:18.724674418 +0200 |
||||
@@ -0,0 +1,12 @@ |
||||
+ |
||||
+int whereIam = -1; |
||||
+ |
||||
+void _debug_wIm_body(const char *txt, int val, const char *func, const char *file, int line) |
||||
+{ |
||||
+ if (txt) |
||||
+ debug("%s=%d, %s(%s:%d) wIm = %d, uid=%d, euid=%d", txt, val, func, file, line, whereIam, getuid(), geteuid()); |
||||
+ else |
||||
+ debug("%s(%s:%d) wIm = %d, uid=%d, euid=%d", func, file, line, whereIam, getuid(), geteuid()); |
||||
+} |
||||
+ |
||||
+ |
@ -0,0 +1,177 @@
@@ -0,0 +1,177 @@
|
||||
From 5618210618256bbf5f4f71b2887ff186fd451736 Mon Sep 17 00:00:00 2001 |
||||
From: Damien Miller <djm@mindrot.org> |
||||
Date: Sun, 20 Apr 2014 13:44:47 +1000 |
||||
Subject: [PATCH] - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c |
||||
version.h] OpenSSH 6.5 and 6.6 sometimes encode a value used in the |
||||
curve25519 key exchange incorrectly, causing connection failures about |
||||
0.2% of the time when this method is used against a peer that implements |
||||
the method properly. |
||||
|
||||
Fix the problem and disable the curve25519 KEX when speaking to |
||||
OpenSSH 6.5 or 6.6. This version will identify itself as 6.6.1 |
||||
to enable the compatability code. |
||||
--- |
||||
ChangeLog | 11 +++++++++++ |
||||
bufaux.c | 5 ++++- |
||||
compat.c | 17 ++++++++++++++++- |
||||
compat.h | 2 ++ |
||||
sshconnect2.c | 2 ++ |
||||
sshd.c | 3 +++ |
||||
version.h | 2 +- |
||||
7 files changed, 39 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/ChangeLog b/ChangeLog |
||||
index 1603a07..928999d 100644 |
||||
--- a/ChangeLog |
||||
+++ b/ChangeLog |
||||
@@ -1,13 +1,23 @@ |
||||
20140420 |
||||
- - djm@cvs.openbsd.org 2014/04/01 03:34:10 |
||||
- [sshconnect.c] |
||||
- When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any |
||||
- certificate keys to plain keys and attempt SSHFP resolution. |
||||
- |
||||
- Prevents a server from skipping SSHFP lookup and forcing a new-hostkey |
||||
- dialog by offering only certificate keys. |
||||
- |
||||
- Reported by mcv21 AT cam.ac.uk |
||||
+ - (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c version.h] |
||||
+ OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 |
||||
+ key exchange incorrectly, causing connection failures about 0.2% of |
||||
+ the time when this method is used against a peer that implements |
||||
+ the method properly. |
||||
+ |
||||
+ Fix the problem and disable the curve25519 KEX when speaking to |
||||
+ OpenSSH 6.5 or 6.6. This version will identify itself as 6.6.1 |
||||
+ to enable the compatability code. |
||||
+ |
||||
+ - djm@cvs.openbsd.org 2014/04/01 03:34:10 |
||||
+ [sshconnect.c] |
||||
+ When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any |
||||
+ certificate keys to plain keys and attempt SSHFP resolution. |
||||
+ |
||||
+ Prevents a server from skipping SSHFP lookup and forcing a new-hostkey |
||||
+ dialog by offering only certificate keys. |
||||
+ |
||||
+ Reported by mcv21 AT cam.ac.uk |
||||
|
||||
20140313 |
||||
- (djm) Release OpenSSH 6.6 |
||||
diff --git a/bufaux.c b/bufaux.c |
||||
index e24b5fc..f6a6f2a 100644 |
||||
--- a/bufaux.c |
||||
+++ b/bufaux.c |
||||
@@ -1,4 +1,4 @@ |
||||
-/* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 djm Exp $ */ |
||||
+/* $OpenBSD: bufaux.c,v 1.57 2014/04/16 23:22:45 djm Exp $ */ |
||||
/* |
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi> |
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
||||
@@ -372,6 +372,9 @@ buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) |
||||
|
||||
if (l > 8 * 1024) |
||||
fatal("%s: length %u too long", __func__, l); |
||||
+ /* Skip leading zero bytes */ |
||||
+ for (; l > 0 && *s == 0; l--, s++) |
||||
+ ; |
||||
p = buf = xmalloc(l + 1); |
||||
/* |
||||
* If most significant bit is set then prepend a zero byte to |
||||
diff --git a/compat.c b/compat.c |
||||
index 9d9fabe..2709dc5 100644 |
||||
--- a/compat.c |
||||
+++ b/compat.c |
||||
@@ -95,6 +95,9 @@ compat_datafellows(const char *version) |
||||
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, |
||||
{ "OpenSSH_4*", 0 }, |
||||
{ "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT}, |
||||
+ { "OpenSSH_6.6.1*", SSH_NEW_OPENSSH}, |
||||
+ { "OpenSSH_6.5*," |
||||
+ "OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD}, |
||||
{ "OpenSSH*", SSH_NEW_OPENSSH }, |
||||
{ "*MindTerm*", 0 }, |
||||
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| |
||||
@@ -251,7 +254,6 @@ compat_cipher_proposal(char *cipher_prop) |
||||
return cipher_prop; |
||||
} |
||||
|
||||
- |
||||
char * |
||||
compat_pkalg_proposal(char *pkalg_prop) |
||||
{ |
||||
@@ -265,3 +267,16 @@ compat_pkalg_proposal(char *pkalg_prop) |
||||
return pkalg_prop; |
||||
} |
||||
|
||||
+char * |
||||
+compat_kex_proposal(char *kex_prop) |
||||
+{ |
||||
+ if (!(datafellows & SSH_BUG_CURVE25519PAD)) |
||||
+ return kex_prop; |
||||
+ debug2("%s: original KEX proposal: %s", __func__, kex_prop); |
||||
+ kex_prop = filter_proposal(kex_prop, "curve25519-sha256@libssh.org"); |
||||
+ debug2("%s: compat KEX proposal: %s", __func__, kex_prop); |
||||
+ if (*kex_prop == '\0') |
||||
+ fatal("No supported key exchange algorithms found"); |
||||
+ return kex_prop; |
||||
+} |
||||
+ |
||||
diff --git a/compat.h b/compat.h |
||||
index b174fa1..a6c3f3d 100644 |
||||
--- a/compat.h |
||||
+++ b/compat.h |
||||
@@ -59,6 +59,7 @@ |
||||
#define SSH_BUG_RFWD_ADDR 0x02000000 |
||||
#define SSH_NEW_OPENSSH 0x04000000 |
||||
#define SSH_BUG_DYNAMIC_RPORT 0x08000000 |
||||
+#define SSH_BUG_CURVE25519PAD 0x10000000 |
||||
|
||||
void enable_compat13(void); |
||||
void enable_compat20(void); |
||||
@@ -66,6 +67,7 @@ void compat_datafellows(const char *); |
||||
int proto_spec(const char *); |
||||
char *compat_cipher_proposal(char *); |
||||
char *compat_pkalg_proposal(char *); |
||||
+char *compat_kex_proposal(char *); |
||||
|
||||
extern int compat13; |
||||
extern int compat20; |
||||
diff --git a/sshconnect2.c b/sshconnect2.c |
||||
index bb9292f..b00658b 100644 |
||||
--- a/sshconnect2.c |
||||
+++ b/sshconnect2.c |
||||
@@ -220,6 +220,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) |
||||
} |
||||
if (options.kex_algorithms != NULL) |
||||
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; |
||||
+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( |
||||
+ myproposal[PROPOSAL_KEX_ALGS]); |
||||
|
||||
#ifdef GSSAPI |
||||
/* If we've got GSSAPI algorithms, then we also support the |
||||
diff --git a/sshd.c b/sshd.c |
||||
index e4e406e..512c7ed 100644 |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -2488,6 +2488,9 @@ do_ssh2_kex(void) |
||||
if (options.kex_algorithms != NULL) |
||||
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; |
||||
|
||||
+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( |
||||
+ myproposal[PROPOSAL_KEX_ALGS]); |
||||
+ |
||||
if (options.rekey_limit || options.rekey_interval) |
||||
packet_set_rekey_limits((u_int32_t)options.rekey_limit, |
||||
(time_t)options.rekey_interval); |
||||
diff --git a/version.h b/version.h |
||||
index a1579ac..a33e77c 100644 |
||||
--- a/version.h |
||||
+++ b/version.h |
||||
@@ -1,6 +1,6 @@ |
||||
/* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */ |
||||
|
||||
-#define SSH_VERSION "OpenSSH_6.6" |
||||
+#define SSH_VERSION "OpenSSH_6.6.1" |
||||
|
||||
#define SSH_PORTABLE "p1" |
||||
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
diff -up openssh-6.1p1/contrib/Makefile.askpass-ld openssh-6.1p1/contrib/Makefile |
||||
--- openssh-6.1p1/contrib/Makefile.askpass-ld 2012-05-19 07:24:37.000000000 +0200 |
||||
+++ openssh-6.1p1/contrib/Makefile 2012-09-14 20:35:47.565704718 +0200 |
||||
@@ -4,12 +4,12 @@ all: |
||||
@echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" |
||||
|
||||
gnome-ssh-askpass1: gnome-ssh-askpass1.c |
||||
- $(CC) `gnome-config --cflags gnome gnomeui` \ |
||||
+ $(CC) ${CFLAGS} `gnome-config --cflags gnome gnomeui` \ |
||||
gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \ |
||||
`gnome-config --libs gnome gnomeui` |
||||
|
||||
gnome-ssh-askpass2: gnome-ssh-askpass2.c |
||||
- $(CC) `$(PKG_CONFIG) --cflags gtk+-2.0` \ |
||||
+ $(CC) ${CFLAGS} `$(PKG_CONFIG) --cflags gtk+-2.0` \ |
||||
gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ |
||||
`$(PKG_CONFIG) --libs gtk+-2.0 x11` |
||||
|
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c |
||||
--- openssh-6.1p1/sshconnect2.c.canohost 2012-10-30 10:52:59.593301692 +0100 |
||||
+++ openssh-6.1p1/sshconnect2.c 2012-10-30 11:01:12.870301632 +0100 |
||||
@@ -699,12 +699,15 @@ userauth_gssapi(Authctxt *authctxt) |
||||
static u_int mech = 0; |
||||
OM_uint32 min; |
||||
int ok = 0; |
||||
- const char *gss_host; |
||||
+ const char *gss_host = NULL; |
||||
|
||||
if (options.gss_server_identity) |
||||
gss_host = options.gss_server_identity; |
||||
- else if (options.gss_trust_dns) |
||||
+ else if (options.gss_trust_dns) { |
||||
gss_host = get_canonical_hostname(active_state, 1); |
||||
+ if ( strcmp( gss_host, "UNKNOWN" ) == 0 ) |
||||
+ gss_host = authctxt->host; |
||||
+ } |
||||
else |
||||
gss_host = authctxt->host; |
||||
|
@ -0,0 +1,143 @@
@@ -0,0 +1,143 @@
|
||||
diff -up openssh-7.4p1/configure.ac.vendor openssh-7.4p1/configure.ac |
||||
--- openssh-7.4p1/configure.ac.vendor 2017-02-10 10:45:54.977836854 +0100 |
||||
+++ openssh-7.4p1/configure.ac 2017-02-10 10:45:54.995836725 +0100 |
||||
@@ -4930,6 +4930,12 @@ AC_ARG_WITH([lastlog], |
||||
fi |
||||
] |
||||
) |
||||
+AC_ARG_ENABLE(vendor-patchlevel, |
||||
+ [ --enable-vendor-patchlevel=TAG specify a vendor patch level], |
||||
+ [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.]) |
||||
+ SSH_VENDOR_PATCHLEVEL="$enableval"], |
||||
+ [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.]) |
||||
+ SSH_VENDOR_PATCHLEVEL=none]) |
||||
|
||||
dnl lastlog, [uw]tmpx? detection |
||||
dnl NOTE: set the paths in the platform section to avoid the |
||||
@@ -5194,6 +5200,7 @@ echo " Translate v4 in v6 hack |
||||
echo " BSD Auth support: $BSD_AUTH_MSG" |
||||
echo " Random number source: $RAND_MSG" |
||||
echo " Privsep sandbox style: $SANDBOX_STYLE" |
||||
+echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL" |
||||
|
||||
echo "" |
||||
|
||||
diff -up openssh-7.4p1/servconf.c.vendor openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.vendor 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-10 10:45:54.995836725 +0100 |
||||
@@ -143,6 +143,7 @@ initialize_server_options(ServerOptions |
||||
options->max_authtries = -1; |
||||
options->max_sessions = -1; |
||||
options->banner = NULL; |
||||
+ options->show_patchlevel = -1; |
||||
options->use_dns = -1; |
||||
options->client_alive_interval = -1; |
||||
options->client_alive_count_max = -1; |
||||
@@ -325,6 +326,8 @@ fill_default_server_options(ServerOption |
||||
options->ip_qos_bulk = IPTOS_THROUGHPUT; |
||||
if (options->version_addendum == NULL) |
||||
options->version_addendum = xstrdup(""); |
||||
+ if (options->show_patchlevel == -1) |
||||
+ options->show_patchlevel = 0; |
||||
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) |
||||
options->fwd_opts.streamlocal_bind_mask = 0177; |
||||
if (options->fwd_opts.streamlocal_bind_unlink == -1) |
||||
@@ -402,7 +405,7 @@ typedef enum { |
||||
sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, |
||||
sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, |
||||
sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, |
||||
- sBanner, sUseDNS, sHostbasedAuthentication, |
||||
+ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, |
||||
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, |
||||
sHostKeyAlgorithms, |
||||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |
||||
@@ -528,6 +531,7 @@ static struct { |
||||
{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, |
||||
{ "maxsessions", sMaxSessions, SSHCFG_ALL }, |
||||
{ "banner", sBanner, SSHCFG_ALL }, |
||||
+ { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL }, |
||||
{ "usedns", sUseDNS, SSHCFG_GLOBAL }, |
||||
{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, |
||||
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, |
||||
@@ -1369,6 +1373,10 @@ process_server_config_line(ServerOptions |
||||
multistate_ptr = multistate_privsep; |
||||
goto parse_multistate; |
||||
|
||||
+ case sShowPatchLevel: |
||||
+ intptr = &options->show_patchlevel; |
||||
+ goto parse_flag; |
||||
+ |
||||
case sAllowUsers: |
||||
while ((arg = strdelim(&cp)) && *arg != '\0') { |
||||
if (options->num_allow_users >= MAX_ALLOW_USERS) |
||||
@@ -2269,6 +2277,7 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); |
||||
dump_cfg_fmtint(sCompression, o->compression); |
||||
dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); |
||||
+ dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel); |
||||
dump_cfg_fmtint(sUseDNS, o->use_dns); |
||||
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); |
||||
dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); |
||||
diff -up openssh-7.4p1/servconf.h.vendor openssh-7.4p1/servconf.h |
||||
--- openssh-7.4p1/servconf.h.vendor 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/servconf.h 2017-02-10 10:45:54.995836725 +0100 |
||||
@@ -149,6 +149,7 @@ typedef struct { |
||||
int max_authtries; |
||||
int max_sessions; |
||||
char *banner; /* SSH-2 banner message */ |
||||
+ int show_patchlevel; /* Show vendor patch level to clients */ |
||||
int use_dns; |
||||
int client_alive_interval; /* |
||||
* poke the client this often to |
||||
diff -up openssh-7.4p1/sshd_config.5.vendor openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.vendor 2017-02-10 10:45:54.990836761 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2017-02-10 10:45:54.996836718 +0100 |
||||
@@ -1334,6 +1334,14 @@ an OpenSSH Key Revocation List (KRL) as |
||||
.Xr ssh-keygen 1 . |
||||
For more information on KRLs, see the KEY REVOCATION LISTS section in |
||||
.Xr ssh-keygen 1 . |
||||
+.It Cm ShowPatchLevel |
||||
+Specifies whether |
||||
+.Nm sshd |
||||
+will display the patch level of the binary in the identification string. |
||||
+The patch level is set at compile-time. |
||||
+The default is |
||||
+.Dq no . |
||||
+This option applies to protocol version 1 only. |
||||
.It Cm StreamLocalBindMask |
||||
Sets the octal file creation mode mask |
||||
.Pq umask |
||||
diff -up openssh-7.4p1/sshd_config.vendor openssh-7.4p1/sshd_config |
||||
--- openssh-7.4p1/sshd_config.vendor 2017-02-10 10:45:54.990836761 +0100 |
||||
+++ openssh-7.4p1/sshd_config 2017-02-10 10:45:54.996836718 +0100 |
||||
@@ -105,6 +105,7 @@ X11Forwarding yes |
||||
#Compression delayed |
||||
#ClientAliveInterval 0 |
||||
#ClientAliveCountMax 3 |
||||
+#ShowPatchLevel no |
||||
#UseDNS no |
||||
#PidFile /var/run/sshd.pid |
||||
#MaxStartups 10:30:100 |
||||
diff -up openssh-7.4p1/sshd.c.vendor openssh-7.4p1/sshd.c |
||||
--- openssh-7.4p1/sshd.c.vendor 2017-02-10 10:45:54.996836718 +0100 |
||||
+++ openssh-7.4p1/sshd.c 2017-02-10 10:48:41.633648667 +0100 |
||||
@@ -367,7 +367,8 @@ sshd_exchange_identification(struct ssh |
||||
char remote_version[256]; /* Must be at least as big as buf. */ |
||||
|
||||
xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", |
||||
- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, |
||||
+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, |
||||
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, |
||||
*options.version_addendum == '\0' ? "" : " ", |
||||
options.version_addendum, newline); |
||||
|
||||
@@ -1654,7 +1655,8 @@ main(int ac, char **av) |
||||
exit(1); |
||||
} |
||||
|
||||
- debug("sshd version %s, %s", SSH_VERSION, |
||||
+ debug("sshd version %s, %s", |
||||
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, |
||||
#ifdef WITH_OPENSSL |
||||
SSLeay_version(SSLEAY_VERSION) |
||||
#else |
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
diff -up openssh-5.9p1/cipher-ctr.c.ctr-evp openssh-5.9p1/cipher-ctr.c |
||||
--- openssh-5.9p1/cipher-ctr.c.ctr-evp 2012-01-11 09:24:06.000000000 +0100 |
||||
+++ openssh-5.9p1/cipher-ctr.c 2012-01-11 15:54:04.675956600 +0100 |
||||
@@ -38,7 +38,7 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, in |
||||
|
||||
struct ssh_aes_ctr_ctx |
||||
{ |
||||
- AES_KEY aes_ctx; |
||||
+ EVP_CIPHER_CTX ecbctx; |
||||
u_char aes_counter[AES_BLOCK_SIZE]; |
||||
}; |
||||
|
||||
@@ -63,21 +63,42 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char |
||||
{ |
||||
struct ssh_aes_ctr_ctx *c; |
||||
size_t n = 0; |
||||
- u_char buf[AES_BLOCK_SIZE]; |
||||
+ u_char ctrbuf[AES_BLOCK_SIZE*256]; |
||||
+ u_char buf[AES_BLOCK_SIZE*256]; |
||||
|
||||
if (len == 0) |
||||
return (1); |
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) |
||||
return (0); |
||||
|
||||
- while ((len--) > 0) { |
||||
+ for (; len > 0; len -= sizeof(u_int)) { |
||||
+ u_int r,a,b; |
||||
+ |
||||
if (n == 0) { |
||||
- AES_encrypt(c->aes_counter, buf, &c->aes_ctx); |
||||
- ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); |
||||
+ int outl, i, buflen; |
||||
+ |
||||
+ buflen = MIN(len, sizeof(ctrbuf)); |
||||
+ |
||||
+ for(i = 0; i < buflen; i += AES_BLOCK_SIZE) { |
||||
+ memcpy(&ctrbuf[i], c->aes_counter, AES_BLOCK_SIZE); |
||||
+ ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); |
||||
+ } |
||||
+ |
||||
+ EVP_EncryptUpdate(&c->ecbctx, buf, &outl, |
||||
+ ctrbuf, buflen); |
||||
} |
||||
- *(dest++) = *(src++) ^ buf[n]; |
||||
- n = (n + 1) % AES_BLOCK_SIZE; |
||||
+ |
||||
+ memcpy(&a, src, sizeof(a)); |
||||
+ memcpy(&b, &buf[n], sizeof(b)); |
||||
+ r = a ^ b; |
||||
+ memcpy(dest, &r, sizeof(r)); |
||||
+ src += sizeof(a); |
||||
+ dest += sizeof(r); |
||||
+ |
||||
+ n = (n + sizeof(b)) % sizeof(buf); |
||||
} |
||||
+ memset(ctrbuf, '\0', sizeof(ctrbuf)); |
||||
+ memset(buf, '\0', sizeof(buf)); |
||||
return (1); |
||||
} |
||||
|
||||
@@ -91,9 +112,28 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co |
||||
c = xmalloc(sizeof(*c)); |
||||
EVP_CIPHER_CTX_set_app_data(ctx, c); |
||||
} |
||||
- if (key != NULL) |
||||
- AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, |
||||
- &c->aes_ctx); |
||||
+ |
||||
+ EVP_CIPHER_CTX_init(&c->ecbctx); |
||||
+ |
||||
+ if (key != NULL) { |
||||
+ const EVP_CIPHER *cipher; |
||||
+ switch(EVP_CIPHER_CTX_key_length(ctx)*8) { |
||||
+ case 128: |
||||
+ cipher = EVP_aes_128_ecb(); |
||||
+ break; |
||||
+ case 192: |
||||
+ cipher = EVP_aes_192_ecb(); |
||||
+ break; |
||||
+ case 256: |
||||
+ cipher = EVP_aes_256_ecb(); |
||||
+ break; |
||||
+ default: |
||||
+ fatal("ssh_aes_ctr_init: wrong aes key length"); |
||||
+ } |
||||
+ if(!EVP_EncryptInit_ex(&c->ecbctx, cipher, NULL, key, NULL)) |
||||
+ fatal("ssh_aes_ctr_init: cannot initialize aes encryption"); |
||||
+ EVP_CIPHER_CTX_set_padding(&c->ecbctx, 0); |
||||
+ } |
||||
if (iv != NULL) |
||||
memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); |
||||
return (1); |
||||
@@ -105,6 +145,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) |
||||
struct ssh_aes_ctr_ctx *c; |
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { |
||||
+ EVP_CIPHER_CTX_cleanup(&c->ecbctx); |
||||
memset(c, 0, sizeof(*c)); |
||||
free(c); |
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
@ -0,0 +1,247 @@
@@ -0,0 +1,247 @@
|
||||
diff -up openssh-6.3p1/auth-krb5.c.ccache_name openssh-6.3p1/auth-krb5.c |
||||
--- openssh-6.3p1/auth-krb5.c.ccache_name 2013-10-23 22:03:52.322950759 +0200 |
||||
+++ openssh-6.3p1/auth-krb5.c 2013-10-23 22:04:24.295799873 +0200 |
||||
@@ -50,7 +50,9 @@ |
||||
#include <errno.h> |
||||
#include <unistd.h> |
||||
#include <string.h> |
||||
+#include <sys/stat.h> |
||||
#include <krb5.h> |
||||
+#include <profile.h> |
||||
|
||||
extern ServerOptions options; |
||||
|
||||
@@ -91,6 +93,7 @@ auth_krb5_password(Authctxt *authctxt, c |
||||
#endif |
||||
krb5_error_code problem; |
||||
krb5_ccache ccache = NULL; |
||||
+ const char *ccache_type; |
||||
int len; |
||||
char *client, *platform_client; |
||||
const char *errmsg; |
||||
@@ -191,12 +194,30 @@ auth_krb5_password(Authctxt *authctxt, c |
||||
goto out; |
||||
#endif |
||||
|
||||
+ ccache_type = krb5_cc_get_type(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); |
||||
authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); |
||||
|
||||
- len = strlen(authctxt->krb5_ticket_file) + 6; |
||||
+ if (authctxt->krb5_ticket_file[0] == ':') |
||||
+ authctxt->krb5_ticket_file++; |
||||
+ |
||||
+ len = strlen(authctxt->krb5_ticket_file) + strlen(ccache_type) + 2; |
||||
authctxt->krb5_ccname = xmalloc(len); |
||||
- snprintf(authctxt->krb5_ccname, len, "FILE:%s", |
||||
+ |
||||
+#ifdef USE_CCAPI |
||||
+ snprintf(authctxt->krb5_ccname, len, "API:%s", |
||||
authctxt->krb5_ticket_file); |
||||
+#else |
||||
+ snprintf(authctxt->krb5_ccname, len, "%s:%s", |
||||
+ ccache_type, authctxt->krb5_ticket_file); |
||||
+#endif |
||||
+ |
||||
+ if (strcmp(ccache_type, "DIR") == 0) { |
||||
+ char *p; |
||||
+ p = strrchr(authctxt->krb5_ccname, '/'); |
||||
+ if (p) |
||||
+ *p = '\0'; |
||||
+ } |
||||
+ |
||||
|
||||
#ifdef USE_PAM |
||||
if (options.use_pam) |
||||
@@ -235,10 +256,34 @@ auth_krb5_password(Authctxt *authctxt, c |
||||
void |
||||
krb5_cleanup_proc(Authctxt *authctxt) |
||||
{ |
||||
+ struct stat krb5_ccname_stat; |
||||
+ char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end; |
||||
+ |
||||
debug("krb5_cleanup_proc called"); |
||||
if (authctxt->krb5_fwd_ccache) { |
||||
krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); |
||||
authctxt->krb5_fwd_ccache = NULL; |
||||
+ |
||||
+ strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10); |
||||
+ krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1; |
||||
+ *krb5_ccname_dir_start++ = '\0'; |
||||
+ if (strcmp(krb5_ccname, "DIR") == 0) { |
||||
+ |
||||
+ strcat(krb5_ccname_dir_start, "/primary"); |
||||
+ |
||||
+ if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) { |
||||
+ if (unlink(krb5_ccname_dir_start) == 0) { |
||||
+ krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/'); |
||||
+ *krb5_ccname_dir_end = '\0'; |
||||
+ if (rmdir(krb5_ccname_dir_start) == -1) |
||||
+ debug("cache dir '%s' remove failed: %s", krb5_ccname_dir_start, strerror(errno)); |
||||
+ } |
||||
+ else |
||||
+ debug("cache primary file '%s', remove failed: %s", |
||||
+ krb5_ccname_dir_start, strerror(errno) |
||||
+ ); |
||||
+ } |
||||
+ } |
||||
} |
||||
if (authctxt->krb5_user) { |
||||
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); |
||||
@@ -250,34 +295,139 @@ krb5_cleanup_proc(Authctxt *authctxt) |
||||
} |
||||
} |
||||
|
||||
+int |
||||
+ssh_asprintf_append(char **dsc, const char *fmt, ...) { |
||||
+ char *src, *old; |
||||
+ va_list ap; |
||||
+ int i; |
||||
+ |
||||
+ va_start(ap, fmt); |
||||
+ i = vasprintf(&src, fmt, ap); |
||||
+ va_end(ap); |
||||
+ |
||||
+ if (i == -1 || src == NULL) |
||||
+ return -1; |
||||
+ |
||||
+ old = *dsc; |
||||
+ |
||||
+ i = asprintf(dsc, "%s%s", *dsc, src); |
||||
+ if (i == -1 || src == NULL) { |
||||
+ free(src); |
||||
+ return -1; |
||||
+ } |
||||
+ |
||||
+ free(old); |
||||
+ free(src); |
||||
+ |
||||
+ return i; |
||||
+} |
||||
+ |
||||
+int |
||||
+ssh_krb5_expand_template(char **result, const char *template) { |
||||
+ char *p_n, *p_o, *r, *tmp_template; |
||||
+ |
||||
+ if (template == NULL) |
||||
+ return -1; |
||||
+ |
||||
+ tmp_template = p_n = p_o = xstrdup(template); |
||||
+ r = xstrdup(""); |
||||
+ |
||||
+ while ((p_n = strstr(p_o, "%{")) != NULL) { |
||||
+ |
||||
+ *p_n++ = '\0'; |
||||
+ if (ssh_asprintf_append(&r, "%s", p_o) == -1) |
||||
+ goto cleanup; |
||||
+ |
||||
+ if (strncmp(p_n, "{uid}", 5) == 0 || strncmp(p_n, "{euid}", 6) == 0 || |
||||
+ strncmp(p_n, "{USERID}", 8) == 0) { |
||||
+ p_o = strchr(p_n, '}') + 1; |
||||
+ if (ssh_asprintf_append(&r, "%d", geteuid()) == -1) |
||||
+ goto cleanup; |
||||
+ continue; |
||||
+ } |
||||
+ else if (strncmp(p_n, "{TEMP}", 6) == 0) { |
||||
+ p_o = strchr(p_n, '}') + 1; |
||||
+ if (ssh_asprintf_append(&r, "/tmp") == -1) |
||||
+ goto cleanup; |
||||
+ continue; |
||||
+ } else { |
||||
+ p_o = strchr(p_n, '}') + 1; |
||||
+ p_o = '\0'; |
||||
+ debug("%s: unsupported token %s in %s", __func__, p_n, template); |
||||
+ /* unknown token, fallback to the default */ |
||||
+ goto cleanup; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (ssh_asprintf_append(&r, "%s", p_o) == -1) |
||||
+ goto cleanup; |
||||
+ |
||||
+ *result = r; |
||||
+ free(tmp_template); |
||||
+ return 0; |
||||
+ |
||||
+cleanup: |
||||
+ free(r); |
||||
+ free(tmp_template); |
||||
+ return -1; |
||||
+} |
||||
+ |
||||
+krb5_error_code |
||||
+ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { |
||||
+ profile_t p; |
||||
+ int ret = 0; |
||||
+ char *value = NULL; |
||||
+ |
||||
+ ret = krb5_get_profile(ctx, &p); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
+ ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
+ ret = ssh_krb5_expand_template(ccname, value); |
||||
+ |
||||
+ return ret; |
||||
+} |
||||
+ |
||||
#ifndef HEIMDAL |
||||
krb5_error_code |
||||
ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { |
||||
int tmpfd, ret, oerrno; |
||||
- char ccname[40]; |
||||
+ char *ccname; |
||||
+#ifdef USE_CCAPI |
||||
+ char cctemplate[] = "API:krb5cc_%d"; |
||||
+#else |
||||
mode_t old_umask; |
||||
+ char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX"; |
||||
|
||||
- ret = snprintf(ccname, sizeof(ccname), |
||||
- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); |
||||
- if (ret < 0 || (size_t)ret >= sizeof(ccname)) |
||||
- return ENOMEM; |
||||
- |
||||
- old_umask = umask(0177); |
||||
- tmpfd = mkstemp(ccname + strlen("FILE:")); |
||||
- oerrno = errno; |
||||
- umask(old_umask); |
||||
- if (tmpfd == -1) { |
||||
- logit("mkstemp(): %.100s", strerror(oerrno)); |
||||
- return oerrno; |
||||
- } |
||||
+#endif |
||||
+ |
||||
+ ret = ssh_krb5_get_cctemplate(ctx, &ccname); |
||||
|
||||
- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { |
||||
+ if (ret) { |
||||
+ ret = asprintf(&ccname, cctemplate, geteuid()); |
||||
+ if (ret == -1) |
||||
+ return ENOMEM; |
||||
+ old_umask = umask(0177); |
||||
+ tmpfd = mkstemp(ccname + strlen("FILE:")); |
||||
oerrno = errno; |
||||
- logit("fchmod(): %.100s", strerror(oerrno)); |
||||
+ umask(old_umask); |
||||
+ if (tmpfd == -1) { |
||||
+ logit("mkstemp(): %.100s", strerror(oerrno)); |
||||
+ return oerrno; |
||||
+ } |
||||
+ |
||||
+ if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { |
||||
+ oerrno = errno; |
||||
+ logit("fchmod(): %.100s", strerror(oerrno)); |
||||
+ close(tmpfd); |
||||
+ return oerrno; |
||||
+ } |
||||
close(tmpfd); |
||||
- return oerrno; |
||||
} |
||||
- close(tmpfd); |
||||
+ debug("%s: Setting ccname to %s", __func__, ccname); |
||||
|
||||
return (krb5_cc_resolve(ctx, ccname, ccache)); |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
--- a/misc.c |
||||
+++ b/misc.c |
||||
@@ -865,17 +865,24 @@ ms_to_timeval(struct timeval *tv, int ms |
||||
time_t |
||||
monotime(void) |
||||
{ |
||||
-#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) |
||||
+#if defined(HAVE_CLOCK_GETTIME) && \ |
||||
+ (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) |
||||
struct timespec ts; |
||||
static int gettime_failed = 0; |
||||
|
||||
if (!gettime_failed) { |
||||
+#if defined(CLOCK_BOOTTIME) |
||||
+ if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) |
||||
+ return (ts.tv_sec); |
||||
+#endif |
||||
+#if defined(CLOCK_MONOTONIC) |
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) |
||||
return (ts.tv_sec); |
||||
+#endif |
||||
debug3("clock_gettime: %s", strerror(errno)); |
||||
gettime_failed = 1; |
||||
} |
||||
-#endif |
||||
+#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ |
||||
|
||||
return time(NULL); |
||||
} |
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
diff --git a/scp.c b/scp.c |
||||
index d98fa67..25d347b 100644 |
||||
--- a/scp.c |
||||
+++ b/scp.c |
||||
@@ -638,7 +638,10 @@ toremote(char *targ, int argc, char **argv) |
||||
addargs(&alist, "%s", ssh_program); |
||||
addargs(&alist, "-x"); |
||||
addargs(&alist, "-oClearAllForwardings=yes"); |
||||
- addargs(&alist, "-n"); |
||||
+ if (isatty(fileno(stdin))) |
||||
+ addargs(&alist, "-t"); |
||||
+ else |
||||
+ addargs(&alist, "-n"); |
||||
for (j = 0; j < remote_remote_args.num; j++) { |
||||
addargs(&alist, "%s", |
||||
remote_remote_args.list[j]); |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
diff -up openssh-6.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id openssh-6.4p1/contrib/ssh-copy-id.1 |
||||
--- openssh-6.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id 2013-03-22 00:17:37.000000000 +0100 |
||||
+++ openssh-6.4p1/contrib/ssh-copy-id.1 2014-01-28 17:12:49.197542425 +0100 |
||||
@@ -180,6 +180,19 @@ should prove enlightening (N.B. the mode |
||||
.Fl W |
||||
option, rather than |
||||
.Xr nc 1 ) . |
||||
+.Sh ENVIRONMENT |
||||
+.Bl -tag -width Ds |
||||
+.Pp |
||||
+.It Pa SSH_COPY_ID_LEGACY |
||||
+If the |
||||
+.Cm SSH_COPY_ID_LEGACY |
||||
+environment variable is set, the |
||||
+.Nm |
||||
+is run in a legacy mode. In this mode, the |
||||
+.Nm |
||||
+doesn't check an existence of a private key and doesn't do remote checks |
||||
+of the remote server versions or if public keys are already installed. |
||||
+.El |
||||
.Sh "SEE ALSO" |
||||
.Xr ssh 1 , |
||||
.Xr ssh-agent 1 , |
||||
diff -up openssh-6.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id openssh-6.4p1/contrib/ssh-copy-id |
||||
--- openssh-6.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id 2013-06-05 14:48:45.000000000 +0200 |
||||
+++ openssh-6.4p1/contrib/ssh-copy-id 2014-01-28 17:11:51.538833032 +0100 |
||||
@@ -77,7 +77,7 @@ use_id_file() { |
||||
PUB_ID_FILE="$L_ID_FILE.pub" |
||||
fi |
||||
|
||||
- PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) |
||||
+ [ "x$SSH_COPY_ID_LEGACY" != "x" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) |
||||
|
||||
# check that the files are readable |
||||
for f in $PUB_ID_FILE $PRIV_ID_FILE ; do |
||||
@@ -243,7 +243,7 @@ populate_new_ids() { |
||||
printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 |
||||
} |
||||
|
||||
-REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | |
||||
+[ "x$SSH_COPY_ID_LEGACY" != "x" ] || REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | |
||||
sed -ne 's/.*remote software version //p') |
||||
|
||||
case "$REMOTE_VERSION" in |
||||
@@ -268,7 +268,11 @@ case "$REMOTE_VERSION" in |
||||
;; |
||||
*) |
||||
# Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect |
||||
- populate_new_ids 0 |
||||
+ if [ "x$SSH_COPY_ID_LEGACY" != "x" ]; then |
||||
+ NEW_IDS=`eval "$GET_ID"` |
||||
+ else |
||||
+ populate_new_ids 0 |
||||
+ fi |
||||
[ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " |
||||
umask 077 ; |
||||
mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
diff --git a/ChangeLog b/ChangeLog |
||||
index 928999d..3887495 100644 |
||||
--- a/ChangeLog |
||||
+++ b/ChangeLog |
||||
@@ -1,3 +1,10 @@ |
||||
+20140703 |
||||
+ - OpenBSD CVS Sync |
||||
+ - djm@cvs.openbsd.org 2014/07/03 03:34:09 |
||||
+ [gss-serv.c session.c ssh-keygen.c] |
||||
+ standardise on NI_MAXHOST for gethostname() string lengths; about |
||||
+ 1/2 the cases were using it already. Fixes bz#2239 en passant |
||||
+ |
||||
20140420 |
||||
- (djm) [bufaux.c compat.c compat.h sshconnect2.c sshd.c version.h] |
||||
OpenSSH 6.5 and 6.6 sometimes encode a value used in the curve25519 |
||||
diff --git a/gss-serv.c b/gss-serv.c |
||||
index 14f540e..29916d3 100644 |
||||
--- a/gss-serv.c |
||||
+++ b/gss-serv.c |
||||
@@ -1,4 +1,4 @@ |
||||
-/* $OpenBSD: gss-serv.c,v 1.26 2014/02/26 20:28:44 djm Exp $ */ |
||||
+/* $OpenBSD: gss-serv.c,v 1.27 2014/07/03 03:34:09 djm Exp $ */ |
||||
|
||||
/* |
||||
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. |
||||
@@ -102,14 +102,14 @@ static OM_uint32 |
||||
ssh_gssapi_acquire_cred(Gssctxt *ctx) |
||||
{ |
||||
OM_uint32 status; |
||||
- char lname[MAXHOSTNAMELEN]; |
||||
+ char lname[NI_MAXHOST]; |
||||
gss_OID_set oidset; |
||||
|
||||
if (options.gss_strict_acceptor) { |
||||
gss_create_empty_oid_set(&status, &oidset); |
||||
gss_add_oid_set_member(&status, ctx->oid, &oidset); |
||||
|
||||
- if (gethostname(lname, MAXHOSTNAMELEN)) { |
||||
+ if (gethostname(lname, sizeof(lname))) { |
||||
gss_release_oid_set(&status, &oidset); |
||||
return (-1); |
||||
} |
||||
diff --git a/session.c b/session.c |
||||
index ba4589b..e4add93 100644 |
||||
--- a/session.c |
||||
+++ b/session.c |
||||
@@ -49,6 +49,7 @@ |
||||
#include <errno.h> |
||||
#include <fcntl.h> |
||||
#include <grp.h> |
||||
+#include <netdb.h> |
||||
#ifdef HAVE_PATHS_H |
||||
#include <paths.h> |
||||
#endif |
||||
@@ -2669,7 +2670,7 @@ session_setup_x11fwd(Session *s) |
||||
{ |
||||
struct stat st; |
||||
char display[512], auth_display[512]; |
||||
- char hostname[MAXHOSTNAMELEN]; |
||||
+ char hostname[NI_MAXHOST]; |
||||
u_int i; |
||||
|
||||
if (no_x11_forwarding_flag) { |
||||
diff --git a/ssh-keygen.c b/ssh-keygen.c |
||||
index 482dc1c..66198e6 100644 |
||||
--- a/ssh-keygen.c |
||||
+++ b/ssh-keygen.c |
||||
@@ -165,7 +165,7 @@ int rounds = 0; |
||||
/* argv0 */ |
||||
extern char *__progname; |
||||
|
||||
-char hostname[MAXHOSTNAMELEN]; |
||||
+char hostname[NI_MAXHOST]; |
||||
|
||||
/* moduli.c */ |
||||
int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); |
@ -0,0 +1,212 @@
@@ -0,0 +1,212 @@
|
||||
diff --git a/audit-bsm.c b/audit-bsm.c |
||||
index 5160869..c7a1b47 100644 |
||||
--- a/audit-bsm.c |
||||
+++ b/audit-bsm.c |
||||
@@ -481,7 +481,7 @@ audit_unsupported_body(int what) |
||||
} |
||||
|
||||
void |
||||
-audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, uid_t uid) |
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) |
||||
{ |
||||
/* not implemented */ |
||||
} |
||||
diff --git a/audit-linux.c b/audit-linux.c |
||||
index 6954fc1..6686f6a 100644 |
||||
--- a/audit-linux.c |
||||
+++ b/audit-linux.c |
||||
@@ -297,7 +297,7 @@ audit_unsupported_body(int what) |
||||
const static char *direction[] = { "from-server", "from-client", "both" }; |
||||
|
||||
void |
||||
-audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, |
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, |
||||
uid_t uid) |
||||
{ |
||||
#ifdef AUDIT_CRYPTO_SESSION |
||||
@@ -306,8 +306,8 @@ audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, |
||||
Cipher *cipher = cipher_by_name(enc); |
||||
char *s; |
||||
|
||||
- snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", |
||||
- direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, |
||||
+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", |
||||
+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, |
||||
(intmax_t)pid, (intmax_t)uid, |
||||
get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port()); |
||||
free(s); |
||||
diff --git a/audit.c b/audit.c |
||||
index 13c6849..5b49434 100644 |
||||
--- a/audit.c |
||||
+++ b/audit.c |
||||
@@ -135,9 +135,9 @@ audit_unsupported(int what) |
||||
} |
||||
|
||||
void |
||||
-audit_kex(int ctos, char *enc, char *mac, char *comp) |
||||
+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) |
||||
{ |
||||
- PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid())); |
||||
+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); |
||||
} |
||||
|
||||
void |
||||
@@ -270,11 +270,11 @@ audit_unsupported_body(int what) |
||||
* This will be called on succesfull protocol negotiation. |
||||
*/ |
||||
void |
||||
-audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, |
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, 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, |
||||
+ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", |
||||
+ (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, |
||||
(unsigned)uid); |
||||
} |
||||
|
||||
diff --git a/audit.h b/audit.h |
||||
index a2dc3ff..903df66 100644 |
||||
--- a/audit.h |
||||
+++ b/audit.h |
||||
@@ -61,9 +61,9 @@ 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_kex(int, char *, char *, char *, char *); |
||||
void audit_unsupported_body(int); |
||||
-void audit_kex_body(int, char *, char *, char *, pid_t, uid_t); |
||||
+void audit_kex_body(int, char *, 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); |
||||
diff --git a/auditstub.c b/auditstub.c |
||||
index 45817e0..116f460 100644 |
||||
--- a/auditstub.c |
||||
+++ b/auditstub.c |
||||
@@ -35,7 +35,7 @@ audit_unsupported(int n) |
||||
} |
||||
|
||||
void |
||||
-audit_kex(int ctos, char *enc, char *mac, char *comp) |
||||
+audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) |
||||
{ |
||||
} |
||||
|
||||
diff --git a/kex.c b/kex.c |
||||
index ede7b67..eb5f333 100644 |
||||
--- a/kex.c |
||||
+++ b/kex.c |
||||
@@ -553,13 +553,12 @@ kex_choose_conf(Kex *kex) |
||||
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]; |
||||
@@ -571,11 +570,16 @@ kex_choose_conf(Kex *kex) |
||||
dh_need = MAX(dh_need, newkeys->enc.block_size); |
||||
dh_need = MAX(dh_need, newkeys->enc.iv_len); |
||||
dh_need = MAX(dh_need, newkeys->mac.key_len); |
||||
+ debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need); |
||||
+#ifdef SSH_AUDIT_EVENTS |
||||
+ audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); |
||||
+#endif |
||||
} |
||||
/* XXX need runden? */ |
||||
kex->we_need = need; |
||||
kex->dh_need = dh_need; |
||||
|
||||
+ |
||||
/* ignore the next message if the proposals do not match */ |
||||
if (first_kex_follows && !proposals_match(my, peer) && |
||||
!(datafellows & SSH_BUG_FIRSTKEX)) { |
||||
diff --git a/monitor.c b/monitor.c |
||||
index 70b9b4c..81bc9c1 100644 |
||||
--- a/monitor.c |
||||
+++ b/monitor.c |
||||
@@ -2396,7 +2396,7 @@ int |
||||
mm_answer_audit_kex_body(int sock, Buffer *m) |
||||
{ |
||||
int ctos, len; |
||||
- char *cipher, *mac, *compress; |
||||
+ char *cipher, *mac, *compress, *pfs; |
||||
pid_t pid; |
||||
uid_t uid; |
||||
|
||||
@@ -2404,14 +2404,16 @@ mm_answer_audit_kex_body(int sock, Buffer *m) |
||||
cipher = buffer_get_string(m, &len); |
||||
mac = buffer_get_string(m, &len); |
||||
compress = buffer_get_string(m, &len); |
||||
+ pfs = buffer_get_string(m, &len); |
||||
pid = buffer_get_int64(m); |
||||
uid = buffer_get_int64(m); |
||||
|
||||
- audit_kex_body(ctos, cipher, mac, compress, pid, uid); |
||||
+ audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); |
||||
|
||||
free(cipher); |
||||
free(mac); |
||||
free(compress); |
||||
+ free(pfs); |
||||
buffer_clear(m); |
||||
|
||||
mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); |
||||
diff --git a/monitor_wrap.c b/monitor_wrap.c |
||||
index 93f6535..69b29d8 100644 |
||||
--- a/monitor_wrap.c |
||||
+++ b/monitor_wrap.c |
||||
@@ -1408,7 +1408,7 @@ mm_audit_unsupported_body(int what) |
||||
} |
||||
|
||||
void |
||||
-mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, |
||||
+mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, |
||||
uid_t uid) |
||||
{ |
||||
Buffer m; |
||||
@@ -1418,6 +1418,7 @@ mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, |
||||
buffer_put_cstring(&m, cipher); |
||||
buffer_put_cstring(&m, (mac ? mac : "")); |
||||
buffer_put_cstring(&m, compress); |
||||
+ buffer_put_cstring(&m, fps); |
||||
buffer_put_int64(&m, pid); |
||||
buffer_put_int64(&m, uid); |
||||
|
||||
diff --git a/monitor_wrap.h b/monitor_wrap.h |
||||
index 4cf0c78..e43109f 100644 |
||||
--- a/monitor_wrap.h |
||||
+++ b/monitor_wrap.h |
||||
@@ -83,7 +83,7 @@ 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_kex_body(int, char *, 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 |
||||
diff --git a/sshd.c b/sshd.c |
||||
index ee94825..41a94a7 100644 |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -2430,7 +2430,7 @@ do_ssh1_kex(void) |
||||
packet_disconnect("IP Spoofing check bytes do not match."); |
||||
|
||||
#ifdef SSH_AUDIT_EVENTS |
||||
- audit_kex(2, cipher_name(cipher_type), "crc", "none"); |
||||
+ audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); |
||||
#endif |
||||
|
||||
debug("Encryption type: %.200s", cipher_name(cipher_type)); |
@ -0,0 +1,844 @@
@@ -0,0 +1,844 @@
|
||||
diff --git a/auth-pam.c b/auth-pam.c |
||||
index cd1a775..690711e 100644 |
||||
--- a/auth-pam.c |
||||
+++ b/auth-pam.c |
||||
@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void **value) |
||||
if (sshpam_thread_status != -1) |
||||
return (sshpam_thread_status); |
||||
signal(SIGCHLD, sshpam_oldsig); |
||||
- waitpid(thread, &status, 0); |
||||
+ while (waitpid(thread, &status, 0) < 0) { |
||||
+ if (errno == EINTR) |
||||
+ continue; |
||||
+ fatal("%s: waitpid: %s", __func__, |
||||
+ strerror(errno)); |
||||
+ } |
||||
return (status); |
||||
} |
||||
#endif |
||||
diff --git a/channels.c b/channels.c |
||||
index af3fdc2..39c9f89 100644 |
||||
--- a/channels.c |
||||
+++ b/channels.c |
||||
@@ -233,11 +233,11 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, |
||||
channel_max_fd = MAX(channel_max_fd, wfd); |
||||
channel_max_fd = MAX(channel_max_fd, efd); |
||||
|
||||
- if (rfd != -1) |
||||
+ if (rfd >= 0) |
||||
fcntl(rfd, F_SETFD, FD_CLOEXEC); |
||||
- if (wfd != -1 && wfd != rfd) |
||||
+ if (wfd >= 0 && wfd != rfd) |
||||
fcntl(wfd, F_SETFD, FD_CLOEXEC); |
||||
- if (efd != -1 && efd != rfd && efd != wfd) |
||||
+ if (efd >= 0 && efd != rfd && efd != wfd) |
||||
fcntl(efd, F_SETFD, FD_CLOEXEC); |
||||
|
||||
c->rfd = rfd; |
||||
@@ -255,11 +255,11 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, |
||||
|
||||
/* enable nonblocking mode */ |
||||
if (nonblock) { |
||||
- if (rfd != -1) |
||||
+ if (rfd >= 0) |
||||
set_nonblock(rfd); |
||||
- if (wfd != -1) |
||||
+ if (wfd >= 0) |
||||
set_nonblock(wfd); |
||||
- if (efd != -1) |
||||
+ if (efd >= 0) |
||||
set_nonblock(efd); |
||||
} |
||||
} |
||||
diff --git a/clientloop.c b/clientloop.c |
||||
index 9c60108..d372b53 100644 |
||||
--- a/clientloop.c |
||||
+++ b/clientloop.c |
||||
@@ -2081,14 +2081,15 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) |
||||
char *rtype; |
||||
int want_reply; |
||||
int success = 0; |
||||
+/* success is still 0 the packet is allways SSH2_MSG_REQUEST_FAILURE, isn't it? */ |
||||
|
||||
rtype = packet_get_string(NULL); |
||||
want_reply = packet_get_char(); |
||||
debug("client_input_global_request: rtype %s want_reply %d", |
||||
rtype, want_reply); |
||||
if (want_reply) { |
||||
- packet_start(success ? |
||||
- SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); |
||||
+ packet_start(/*success ? |
||||
+ SSH2_MSG_REQUEST_SUCCESS :*/ SSH2_MSG_REQUEST_FAILURE); |
||||
packet_send(); |
||||
packet_write_wait(); |
||||
} |
||||
diff --git a/key.c b/key.c |
||||
index a2050f6..6487d81 100644 |
||||
--- a/key.c |
||||
+++ b/key.c |
||||
@@ -880,8 +880,10 @@ key_read(Key *ret, char **cpp) |
||||
success = 1; |
||||
/*XXXX*/ |
||||
key_free(k); |
||||
+/*XXXX |
||||
if (success != 1) |
||||
break; |
||||
+XXXX*/ |
||||
/* advance cp: skip whitespace and data */ |
||||
while (*cp == ' ' || *cp == '\t') |
||||
cp++; |
||||
diff --git a/monitor.c b/monitor.c |
||||
index 3ff62b0..70b9b4c 100644 |
||||
--- a/monitor.c |
||||
+++ b/monitor.c |
||||
@@ -472,7 +472,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) |
||||
mm_get_keystate(pmonitor); |
||||
|
||||
/* Drain any buffered messages from the child */ |
||||
- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) |
||||
+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) |
||||
; |
||||
|
||||
close(pmonitor->m_sendfd); |
||||
@@ -1254,6 +1254,10 @@ mm_answer_keyallowed(int sock, Buffer *m) |
||||
break; |
||||
} |
||||
} |
||||
+ |
||||
+ debug3("%s: key %p is %s", |
||||
+ __func__, key, allowed ? "allowed" : "not allowed"); |
||||
+ |
||||
if (key != NULL) |
||||
key_free(key); |
||||
|
||||
@@ -1275,9 +1279,6 @@ mm_answer_keyallowed(int sock, Buffer *m) |
||||
free(chost); |
||||
} |
||||
|
||||
- debug3("%s: key %p is %s", |
||||
- __func__, key, allowed ? "allowed" : "not allowed"); |
||||
- |
||||
buffer_clear(m); |
||||
buffer_put_int(m, allowed); |
||||
buffer_put_int(m, forced_command != NULL); |
||||
diff --git a/monitor_wrap.c b/monitor_wrap.c |
||||
index 6df236a..93f6535 100644 |
||||
--- a/monitor_wrap.c |
||||
+++ b/monitor_wrap.c |
||||
@@ -743,10 +743,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) |
||||
if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || |
||||
(tmp2 = dup(pmonitor->m_recvfd)) == -1) { |
||||
error("%s: cannot allocate fds for pty", __func__); |
||||
- if (tmp1 > 0) |
||||
+ if (tmp1 >= 0) |
||||
close(tmp1); |
||||
- if (tmp2 > 0) |
||||
- close(tmp2); |
||||
+ /*DEAD CODE if (tmp2 >= 0) |
||||
+ close(tmp2);*/ |
||||
return 0; |
||||
} |
||||
close(tmp1); |
||||
diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c |
||||
index c89f214..80115c2 100644 |
||||
--- a/openbsd-compat/bindresvport.c |
||||
+++ b/openbsd-compat/bindresvport.c |
||||
@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) |
||||
struct sockaddr_in6 *in6; |
||||
u_int16_t *portp; |
||||
u_int16_t port; |
||||
- socklen_t salen; |
||||
+ socklen_t salen = sizeof(struct sockaddr_storage); |
||||
int i; |
||||
|
||||
if (sa == NULL) { |
||||
diff --git a/packet.c b/packet.c |
||||
index f5b122b..1305e87 100644 |
||||
--- a/packet.c |
||||
+++ b/packet.c |
||||
@@ -1234,6 +1234,7 @@ packet_read_poll1(void) |
||||
case DEATTACK_DETECTED: |
||||
packet_disconnect("crc32 compensation attack: " |
||||
"network attack detected"); |
||||
+ break; |
||||
case DEATTACK_DOS_DETECTED: |
||||
packet_disconnect("deattack denial of " |
||||
"service detected"); |
||||
diff --git a/progressmeter.c b/progressmeter.c |
||||
index bbbc706..ae6d1aa 100644 |
||||
--- a/progressmeter.c |
||||
+++ b/progressmeter.c |
||||
@@ -65,7 +65,7 @@ static void update_progress_meter(int); |
||||
|
||||
static time_t start; /* start progress */ |
||||
static time_t last_update; /* last progress update */ |
||||
-static char *file; /* name of the file being transferred */ |
||||
+static const char *file; /* name of the file being transferred */ |
||||
static off_t start_pos; /* initial position of transfer */ |
||||
static off_t end_pos; /* ending position of transfer */ |
||||
static off_t cur_pos; /* transfer position as of last refresh */ |
||||
@@ -248,7 +248,7 @@ update_progress_meter(int ignore) |
||||
} |
||||
|
||||
void |
||||
-start_progress_meter(char *f, off_t filesize, off_t *ctr) |
||||
+start_progress_meter(const char *f, off_t filesize, off_t *ctr) |
||||
{ |
||||
start = last_update = monotime(); |
||||
file = f; |
||||
diff --git a/progressmeter.h b/progressmeter.h |
||||
index 10bab99..e9ca8f0 100644 |
||||
--- a/progressmeter.h |
||||
+++ b/progressmeter.h |
||||
@@ -23,5 +23,5 @@ |
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
-void start_progress_meter(char *, off_t, off_t *); |
||||
+void start_progress_meter(const char *, off_t, off_t *); |
||||
void stop_progress_meter(void); |
||||
diff --git a/scp.c b/scp.c |
||||
index 1178a07..d9bc016 100644 |
||||
--- a/scp.c |
||||
+++ b/scp.c |
||||
@@ -155,7 +155,7 @@ killchild(int signo) |
||||
{ |
||||
if (do_cmd_pid > 1) { |
||||
kill(do_cmd_pid, signo ? signo : SIGTERM); |
||||
- waitpid(do_cmd_pid, NULL, 0); |
||||
+ (void) waitpid(do_cmd_pid, NULL, 0); |
||||
} |
||||
|
||||
if (signo) |
||||
diff --git a/servconf.c b/servconf.c |
||||
index 3839928..d482e79 100644 |
||||
--- a/servconf.c |
||||
+++ b/servconf.c |
||||
@@ -1382,7 +1382,7 @@ process_server_config_line(ServerOptions *options, char *line, |
||||
fatal("%s line %d: Missing subsystem name.", |
||||
filename, linenum); |
||||
if (!*activep) { |
||||
- arg = strdelim(&cp); |
||||
+ /*arg =*/ (void) strdelim(&cp); |
||||
break; |
||||
} |
||||
for (i = 0; i < options->num_subsystems; i++) |
||||
@@ -1473,8 +1473,9 @@ process_server_config_line(ServerOptions *options, char *line, |
||||
if (*activep && *charptr == NULL) { |
||||
*charptr = tilde_expand_filename(arg, getuid()); |
||||
/* increase optional counter */ |
||||
- if (intptr != NULL) |
||||
- *intptr = *intptr + 1; |
||||
+ /* DEAD CODE intptr is still NULL ;) |
||||
+ if (intptr != NULL) |
||||
+ *intptr = *intptr + 1; */ |
||||
} |
||||
break; |
||||
|
||||
diff --git a/serverloop.c b/serverloop.c |
||||
index 2f8e3a0..e03bc6c 100644 |
||||
--- a/serverloop.c |
||||
+++ b/serverloop.c |
||||
@@ -147,13 +147,13 @@ notify_setup(void) |
||||
static void |
||||
notify_parent(void) |
||||
{ |
||||
- if (notify_pipe[1] != -1) |
||||
+ if (notify_pipe[1] >= 0) |
||||
(void)write(notify_pipe[1], "", 1); |
||||
} |
||||
static void |
||||
notify_prepare(fd_set *readset) |
||||
{ |
||||
- if (notify_pipe[0] != -1) |
||||
+ if (notify_pipe[0] >= 0) |
||||
FD_SET(notify_pipe[0], readset); |
||||
} |
||||
static void |
||||
@@ -161,8 +161,8 @@ notify_done(fd_set *readset) |
||||
{ |
||||
char c; |
||||
|
||||
- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) |
||||
- while (read(notify_pipe[0], &c, 1) != -1) |
||||
+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) |
||||
+ while (read(notify_pipe[0], &c, 1) >= 0) |
||||
debug2("notify_done: reading"); |
||||
} |
||||
|
||||
@@ -337,7 +337,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, |
||||
* If we have buffered data, try to write some of that data |
||||
* to the program. |
||||
*/ |
||||
- if (fdin != -1 && buffer_len(&stdin_buffer) > 0) |
||||
+ if (fdin >= 0 && buffer_len(&stdin_buffer) > 0) |
||||
FD_SET(fdin, *writesetp); |
||||
} |
||||
notify_prepare(*readsetp); |
||||
@@ -477,7 +477,7 @@ process_output(fd_set *writeset) |
||||
int len; |
||||
|
||||
/* Write buffered data to program stdin. */ |
||||
- if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) { |
||||
+ if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) { |
||||
data = buffer_ptr(&stdin_buffer); |
||||
dlen = buffer_len(&stdin_buffer); |
||||
len = write(fdin, data, dlen); |
||||
@@ -590,7 +590,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) |
||||
set_nonblock(fdin); |
||||
set_nonblock(fdout); |
||||
/* we don't have stderr for interactive terminal sessions, see below */ |
||||
- if (fderr != -1) |
||||
+ if (fderr >= 0) |
||||
set_nonblock(fderr); |
||||
|
||||
if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) |
||||
@@ -614,7 +614,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) |
||||
max_fd = MAX(connection_in, connection_out); |
||||
max_fd = MAX(max_fd, fdin); |
||||
max_fd = MAX(max_fd, fdout); |
||||
- if (fderr != -1) |
||||
+ if (fderr >= 0) |
||||
max_fd = MAX(max_fd, fderr); |
||||
#endif |
||||
|
||||
@@ -644,7 +644,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) |
||||
* If we have received eof, and there is no more pending |
||||
* input data, cause a real eof by closing fdin. |
||||
*/ |
||||
- if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { |
||||
+ if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) { |
||||
if (fdin != fdout) |
||||
close(fdin); |
||||
else |
||||
@@ -740,15 +740,15 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) |
||||
buffer_free(&stderr_buffer); |
||||
|
||||
/* Close the file descriptors. */ |
||||
- if (fdout != -1) |
||||
+ if (fdout >= 0) |
||||
close(fdout); |
||||
fdout = -1; |
||||
fdout_eof = 1; |
||||
- if (fderr != -1) |
||||
+ if (fderr >= 0) |
||||
close(fderr); |
||||
fderr = -1; |
||||
fderr_eof = 1; |
||||
- if (fdin != -1) |
||||
+ if (fdin >= 0) |
||||
close(fdin); |
||||
fdin = -1; |
||||
|
||||
@@ -947,7 +947,7 @@ server_input_window_size(int type, u_int32_t seq, void *ctxt) |
||||
|
||||
debug("Window change received."); |
||||
packet_check_eom(); |
||||
- if (fdin != -1) |
||||
+ if (fdin >= 0) |
||||
pty_change_window_size(fdin, row, col, xpixel, ypixel); |
||||
} |
||||
|
||||
@@ -1007,7 +1007,7 @@ server_request_tun(void) |
||||
} |
||||
|
||||
tun = packet_get_int(); |
||||
- if (forced_tun_device != -1) { |
||||
+ if (forced_tun_device >= 0) { |
||||
if (tun != SSH_TUNID_ANY && forced_tun_device != tun) |
||||
goto done; |
||||
tun = forced_tun_device; |
||||
diff --git a/sftp-client.c b/sftp-client.c |
||||
index 2f5907c..3a2affd 100644 |
||||
--- a/sftp-client.c |
||||
+++ b/sftp-client.c |
||||
@@ -151,7 +151,7 @@ get_msg(struct sftp_conn *conn, Buffer *m) |
||||
} |
||||
|
||||
static void |
||||
-send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, |
||||
+send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s, |
||||
u_int len) |
||||
{ |
||||
Buffer msg; |
||||
@@ -167,7 +167,7 @@ send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, |
||||
|
||||
static void |
||||
send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, |
||||
- char *s, u_int len, Attrib *a) |
||||
+ const char *s, u_int len, Attrib *a) |
||||
{ |
||||
Buffer msg; |
||||
|
||||
@@ -429,7 +429,7 @@ sftp_proto_version(struct sftp_conn *conn) |
||||
} |
||||
|
||||
int |
||||
-do_close(struct sftp_conn *conn, char *handle, u_int handle_len) |
||||
+do_close(struct sftp_conn *conn, const char *handle, u_int handle_len) |
||||
{ |
||||
u_int id, status; |
||||
Buffer msg; |
||||
@@ -454,7 +454,7 @@ do_close(struct sftp_conn *conn, char *handle, u_int handle_len) |
||||
|
||||
|
||||
static int |
||||
-do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, |
||||
+do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag, |
||||
SFTP_DIRENT ***dir) |
||||
{ |
||||
Buffer msg; |
||||
@@ -577,7 +577,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, |
||||
} |
||||
|
||||
int |
||||
-do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir) |
||||
+do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir) |
||||
{ |
||||
return(do_lsreaddir(conn, path, 0, dir)); |
||||
} |
||||
@@ -597,7 +597,7 @@ void free_sftp_dirents(SFTP_DIRENT **s) |
||||
} |
||||
|
||||
int |
||||
-do_rm(struct sftp_conn *conn, char *path) |
||||
+do_rm(struct sftp_conn *conn, const char *path) |
||||
{ |
||||
u_int status, id; |
||||
|
||||
@@ -612,7 +612,7 @@ do_rm(struct sftp_conn *conn, char *path) |
||||
} |
||||
|
||||
int |
||||
-do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) |
||||
+do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag) |
||||
{ |
||||
u_int status, id; |
||||
|
||||
@@ -628,7 +628,7 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) |
||||
} |
||||
|
||||
int |
||||
-do_rmdir(struct sftp_conn *conn, char *path) |
||||
+do_rmdir(struct sftp_conn *conn, const char *path) |
||||
{ |
||||
u_int status, id; |
||||
|
||||
@@ -644,7 +644,7 @@ do_rmdir(struct sftp_conn *conn, char *path) |
||||
} |
||||
|
||||
Attrib * |
||||
-do_stat(struct sftp_conn *conn, char *path, int quiet) |
||||
+do_stat(struct sftp_conn *conn, const char *path, int quiet) |
||||
{ |
||||
u_int id; |
||||
|
||||
@@ -658,7 +658,7 @@ do_stat(struct sftp_conn *conn, char *path, int quiet) |
||||
} |
||||
|
||||
Attrib * |
||||
-do_lstat(struct sftp_conn *conn, char *path, int quiet) |
||||
+do_lstat(struct sftp_conn *conn, const char *path, int quiet) |
||||
{ |
||||
u_int id; |
||||
|
||||
@@ -679,7 +679,7 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet) |
||||
|
||||
#ifdef notyet |
||||
Attrib * |
||||
-do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) |
||||
+do_fstat(struct sftp_conn *conn, const char *handle, u_int handle_len, int quiet) |
||||
{ |
||||
u_int id; |
||||
|
||||
@@ -692,7 +692,7 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) |
||||
#endif |
||||
|
||||
int |
||||
-do_setstat(struct sftp_conn *conn, char *path, Attrib *a) |
||||
+do_setstat(struct sftp_conn *conn, const char *path, Attrib *a) |
||||
{ |
||||
u_int status, id; |
||||
|
||||
@@ -709,7 +709,7 @@ do_setstat(struct sftp_conn *conn, char *path, Attrib *a) |
||||
} |
||||
|
||||
int |
||||
-do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, |
||||
+do_fsetstat(struct sftp_conn *conn, const char *handle, u_int handle_len, |
||||
Attrib *a) |
||||
{ |
||||
u_int status, id; |
||||
@@ -726,7 +726,7 @@ do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, |
||||
} |
||||
|
||||
char * |
||||
-do_realpath(struct sftp_conn *conn, char *path) |
||||
+do_realpath(struct sftp_conn *conn, const char *path) |
||||
{ |
||||
Buffer msg; |
||||
u_int type, expected_id, count, id; |
||||
@@ -775,7 +775,7 @@ do_realpath(struct sftp_conn *conn, char *path) |
||||
} |
||||
|
||||
int |
||||
-do_rename(struct sftp_conn *conn, char *oldpath, char *newpath, |
||||
+do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath, |
||||
int force_legacy) |
||||
{ |
||||
Buffer msg; |
||||
@@ -811,7 +811,7 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath, |
||||
} |
||||
|
||||
int |
||||
-do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) |
||||
+do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) |
||||
{ |
||||
Buffer msg; |
||||
u_int status, id; |
||||
@@ -844,7 +844,7 @@ do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) |
||||
} |
||||
|
||||
int |
||||
-do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) |
||||
+do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) |
||||
{ |
||||
Buffer msg; |
||||
u_int status, id; |
||||
@@ -876,7 +876,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) |
||||
} |
||||
|
||||
int |
||||
-do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) |
||||
+do_fsync(struct sftp_conn *conn, const char *handle, u_int handle_len) |
||||
{ |
||||
Buffer msg; |
||||
u_int status, id; |
||||
@@ -907,7 +907,7 @@ do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) |
||||
|
||||
#ifdef notyet |
||||
char * |
||||
-do_readlink(struct sftp_conn *conn, char *path) |
||||
+do_readlink(struct sftp_conn *conn, const char *path) |
||||
{ |
||||
Buffer msg; |
||||
u_int type, expected_id, count, id; |
||||
@@ -1010,7 +1010,7 @@ do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, |
||||
|
||||
static void |
||||
send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, |
||||
- u_int len, char *handle, u_int handle_len) |
||||
+ u_int len, const char *handle, u_int handle_len) |
||||
{ |
||||
Buffer msg; |
||||
|
||||
@@ -1026,7 +1026,7 @@ send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, |
||||
} |
||||
|
||||
int |
||||
-do_download(struct sftp_conn *conn, char *remote_path, char *local_path, |
||||
+do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path, |
||||
Attrib *a, int preserve_flag, int resume_flag, int fsync_flag) |
||||
{ |
||||
Attrib junk; |
||||
@@ -1308,7 +1308,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, |
||||
} |
||||
|
||||
static int |
||||
-download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
||||
+download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, |
||||
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, |
||||
int fsync_flag) |
||||
{ |
||||
@@ -1400,7 +1400,7 @@ download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
||||
} |
||||
|
||||
int |
||||
-download_dir(struct sftp_conn *conn, char *src, char *dst, |
||||
+download_dir(struct sftp_conn *conn, const char *src, const char *dst, |
||||
Attrib *dirattrib, int preserve_flag, int print_flag, |
||||
int resume_flag, int fsync_flag) |
||||
{ |
||||
@@ -1419,7 +1419,7 @@ download_dir(struct sftp_conn *conn, char *src, char *dst, |
||||
} |
||||
|
||||
int |
||||
-do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
||||
+do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path, |
||||
int preserve_flag, int fsync_flag) |
||||
{ |
||||
int local_fd; |
||||
@@ -1607,7 +1607,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
||||
} |
||||
|
||||
static int |
||||
-upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
||||
+upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, |
||||
int preserve_flag, int print_flag, int fsync_flag) |
||||
{ |
||||
int ret = 0, status; |
||||
@@ -1700,7 +1700,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
||||
} |
||||
|
||||
int |
||||
-upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, |
||||
+upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int preserve_flag, |
||||
int print_flag, int fsync_flag) |
||||
{ |
||||
char *dst_canon; |
||||
@@ -1719,7 +1719,7 @@ upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, |
||||
} |
||||
|
||||
char * |
||||
-path_append(char *p1, char *p2) |
||||
+path_append(const char *p1, const char *p2) |
||||
{ |
||||
char *ret; |
||||
size_t len = strlen(p1) + strlen(p2) + 2; |
||||
diff --git a/sftp-client.h b/sftp-client.h |
||||
index ba92ad0..c085423 100644 |
||||
--- a/sftp-client.h |
||||
+++ b/sftp-client.h |
||||
@@ -56,79 +56,79 @@ struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t); |
||||
u_int sftp_proto_version(struct sftp_conn *); |
||||
|
||||
/* Close file referred to by 'handle' */ |
||||
-int do_close(struct sftp_conn *, char *, u_int); |
||||
+int do_close(struct sftp_conn *, const char *, u_int); |
||||
|
||||
/* Read contents of 'path' to NULL-terminated array 'dir' */ |
||||
-int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***); |
||||
+int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***); |
||||
|
||||
/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */ |
||||
void free_sftp_dirents(SFTP_DIRENT **); |
||||
|
||||
/* Delete file 'path' */ |
||||
-int do_rm(struct sftp_conn *, char *); |
||||
+int do_rm(struct sftp_conn *, const char *); |
||||
|
||||
/* Create directory 'path' */ |
||||
-int do_mkdir(struct sftp_conn *, char *, Attrib *, int); |
||||
+int do_mkdir(struct sftp_conn *, const char *, Attrib *, int); |
||||
|
||||
/* Remove directory 'path' */ |
||||
-int do_rmdir(struct sftp_conn *, char *); |
||||
+int do_rmdir(struct sftp_conn *, const char *); |
||||
|
||||
/* Get file attributes of 'path' (follows symlinks) */ |
||||
-Attrib *do_stat(struct sftp_conn *, char *, int); |
||||
+Attrib *do_stat(struct sftp_conn *, const char *, int); |
||||
|
||||
/* Get file attributes of 'path' (does not follow symlinks) */ |
||||
-Attrib *do_lstat(struct sftp_conn *, char *, int); |
||||
+Attrib *do_lstat(struct sftp_conn *, const char *, int); |
||||
|
||||
/* Set file attributes of 'path' */ |
||||
-int do_setstat(struct sftp_conn *, char *, Attrib *); |
||||
+int do_setstat(struct sftp_conn *, const char *, Attrib *); |
||||
|
||||
/* Set file attributes of open file 'handle' */ |
||||
-int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); |
||||
+int do_fsetstat(struct sftp_conn *, const char *, u_int, Attrib *); |
||||
|
||||
/* Canonicalise 'path' - caller must free result */ |
||||
-char *do_realpath(struct sftp_conn *, char *); |
||||
+char *do_realpath(struct sftp_conn *, const char *); |
||||
|
||||
/* Get statistics for filesystem hosting file at "path" */ |
||||
int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); |
||||
|
||||
/* Rename 'oldpath' to 'newpath' */ |
||||
-int do_rename(struct sftp_conn *, char *, char *m, int force_legacy); |
||||
+int do_rename(struct sftp_conn *, const char *, const char *m, int force_legacy); |
||||
|
||||
/* Link 'oldpath' to 'newpath' */ |
||||
-int do_hardlink(struct sftp_conn *, char *, char *); |
||||
+int do_hardlink(struct sftp_conn *, const char *, const char *); |
||||
|
||||
/* Rename 'oldpath' to 'newpath' */ |
||||
-int do_symlink(struct sftp_conn *, char *, char *); |
||||
+int do_symlink(struct sftp_conn *, const char *, const char *); |
||||
|
||||
/* Call fsync() on open file 'handle' */ |
||||
-int do_fsync(struct sftp_conn *conn, char *, u_int); |
||||
+int do_fsync(struct sftp_conn *conn, const char *, u_int); |
||||
|
||||
/* |
||||
* Download 'remote_path' to 'local_path'. Preserve permissions and times |
||||
* if 'pflag' is set |
||||
*/ |
||||
-int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int, int); |
||||
+int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int, int, int); |
||||
|
||||
/* |
||||
* Recursively download 'remote_directory' to 'local_directory'. Preserve |
||||
* times if 'pflag' is set |
||||
*/ |
||||
-int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, |
||||
+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, |
||||
int, int, int); |
||||
|
||||
/* |
||||
* Upload 'local_path' to 'remote_path'. Preserve permissions and times |
||||
* if 'pflag' is set |
||||
*/ |
||||
-int do_upload(struct sftp_conn *, char *, char *, int, int); |
||||
+int do_upload(struct sftp_conn *, const char *, const char *, int, int); |
||||
|
||||
/* |
||||
* Recursively upload 'local_directory' to 'remote_directory'. Preserve |
||||
* times if 'pflag' is set |
||||
*/ |
||||
-int upload_dir(struct sftp_conn *, char *, char *, int, int, int); |
||||
+int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int); |
||||
|
||||
/* Concatenate paths, taking care of slashes. Caller must free result. */ |
||||
-char *path_append(char *, char *); |
||||
+char *path_append(const char *, const char *); |
||||
|
||||
#endif |
||||
diff --git a/sftp.c b/sftp.c |
||||
index ad1f8c8..3987117 100644 |
||||
--- a/sftp.c |
||||
+++ b/sftp.c |
||||
@@ -218,7 +218,7 @@ killchild(int signo) |
||||
{ |
||||
if (sshpid > 1) { |
||||
kill(sshpid, SIGTERM); |
||||
- waitpid(sshpid, NULL, 0); |
||||
+ (void) waitpid(sshpid, NULL, 0); |
||||
} |
||||
|
||||
_exit(1); |
||||
@@ -329,7 +329,7 @@ local_do_ls(const char *args) |
||||
|
||||
/* Strip one path (usually the pwd) from the start of another */ |
||||
static char * |
||||
-path_strip(char *path, char *strip) |
||||
+path_strip(const char *path, const char *strip) |
||||
{ |
||||
size_t len; |
||||
|
||||
@@ -347,7 +347,7 @@ path_strip(char *path, char *strip) |
||||
} |
||||
|
||||
static char * |
||||
-make_absolute(char *p, char *pwd) |
||||
+make_absolute(char *p, const char *pwd) |
||||
{ |
||||
char *abs_str; |
||||
|
||||
@@ -545,7 +545,7 @@ parse_no_flags(const char *cmd, char **argv, int argc) |
||||
} |
||||
|
||||
static int |
||||
-is_dir(char *path) |
||||
+is_dir(const char *path) |
||||
{ |
||||
struct stat sb; |
||||
|
||||
@@ -557,7 +557,7 @@ is_dir(char *path) |
||||
} |
||||
|
||||
static int |
||||
-remote_is_dir(struct sftp_conn *conn, char *path) |
||||
+remote_is_dir(struct sftp_conn *conn, const char *path) |
||||
{ |
||||
Attrib *a; |
||||
|
||||
@@ -571,7 +571,7 @@ remote_is_dir(struct sftp_conn *conn, char *path) |
||||
|
||||
/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */ |
||||
static int |
||||
-pathname_is_dir(char *pathname) |
||||
+pathname_is_dir(const char *pathname) |
||||
{ |
||||
size_t l = strlen(pathname); |
||||
|
||||
@@ -579,7 +579,7 @@ pathname_is_dir(char *pathname) |
||||
} |
||||
|
||||
static int |
||||
-process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
||||
+process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, |
||||
int pflag, int rflag, int resume, int fflag) |
||||
{ |
||||
char *abs_src = NULL; |
||||
@@ -659,7 +659,7 @@ out: |
||||
} |
||||
|
||||
static int |
||||
-process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, |
||||
+process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd, |
||||
int pflag, int rflag, int fflag) |
||||
{ |
||||
char *tmp_dst = NULL; |
||||
@@ -765,7 +765,7 @@ sdirent_comp(const void *aa, const void *bb) |
||||
|
||||
/* sftp ls.1 replacement for directories */ |
||||
static int |
||||
-do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) |
||||
+do_ls_dir(struct sftp_conn *conn, const char *path, const char *strip_path, int lflag) |
||||
{ |
||||
int n; |
||||
u_int c = 1, colspace = 0, columns = 1; |
||||
@@ -850,7 +850,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) |
||||
|
||||
/* sftp ls.1 replacement which handles path globs */ |
||||
static int |
||||
-do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, |
||||
+do_globbed_ls(struct sftp_conn *conn, const char *path, const char *strip_path, |
||||
int lflag) |
||||
{ |
||||
char *fname, *lname; |
||||
@@ -931,7 +931,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, |
||||
} |
||||
|
||||
static int |
||||
-do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) |
||||
+do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag) |
||||
{ |
||||
struct sftp_statvfs st; |
||||
char s_used[FMT_SCALED_STRSIZE]; |
||||
diff --git a/ssh-agent.c b/ssh-agent.c |
||||
index 117fdde..2b50132 100644 |
||||
--- a/ssh-agent.c |
||||
+++ b/ssh-agent.c |
||||
@@ -1037,8 +1037,8 @@ main(int ac, char **av) |
||||
sanitise_stdfd(); |
||||
|
||||
/* drop */ |
||||
- setegid(getgid()); |
||||
- setgid(getgid()); |
||||
+ (void) setegid(getgid()); |
||||
+ (void) setgid(getgid()); |
||||
|
||||
#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) |
||||
/* Disable ptrace on Linux without sgid bit */ |
||||
diff --git a/sshd.c b/sshd.c |
||||
index 773bb02..1eaa9f7 100644 |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -771,8 +771,10 @@ privsep_preauth(Authctxt *authctxt) |
||||
if (getuid() == 0 || geteuid() == 0) |
||||
privsep_preauth_child(); |
||||
setproctitle("%s", "[net]"); |
||||
- if (box != NULL) |
||||
+ if (box != NULL) { |
||||
ssh_sandbox_child(box); |
||||
+ free(box); |
||||
+ } |
||||
|
||||
return 0; |
||||
} |
||||
@@ -1439,6 +1441,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) |
||||
if (num_listen_socks < 0) |
||||
break; |
||||
} |
||||
+ |
||||
+ if (fdset != NULL) |
||||
+ free(fdset); |
||||
} |
||||
|
||||
|
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
diff --git a/ChangeLog b/ChangeLog |
||||
index 3887495..a4dc72f 100644 |
||||
--- a/ChangeLog |
||||
+++ b/ChangeLog |
||||
@@ -1,3 +1,9 @@ |
||||
+20140823 |
||||
+ - (djm) [sshd.c] Ignore SIGXFSZ in preauth monitor child; can explode on |
||||
+ lastlog writing on platforms with high UIDs; bz#2263 |
||||
+ - (djm) [monitor.c sshd.c] SIGXFSZ needs to be ignored in postauth |
||||
+ monitor, not preauth; bz#2263 |
||||
+ |
||||
20140703 |
||||
- OpenBSD CVS Sync |
||||
- djm@cvs.openbsd.org 2014/07/03 03:34:09 |
||||
diff --git a/monitor.c b/monitor.c |
||||
index bdabe21..5a65114 100644 |
||||
--- a/monitor.c |
||||
+++ b/monitor.c |
||||
@@ -501,6 +501,9 @@ monitor_child_postauth(struct monitor *pmonitor) |
||||
signal(SIGHUP, &monitor_child_handler); |
||||
signal(SIGTERM, &monitor_child_handler); |
||||
signal(SIGINT, &monitor_child_handler); |
||||
+#ifdef SIGXFSZ |
||||
+ signal(SIGXFSZ, SIG_IGN); |
||||
+#endif |
||||
|
||||
if (compat20) { |
||||
mon_dispatch = mon_dispatch_postauth20; |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff --git a/ssh_config b/ssh_config |
||||
index 03a228f..49a4f6c 100644 |
||||
--- a/ssh_config |
||||
+++ b/ssh_config |
||||
@@ -46,3 +46,7 @@ |
||||
# VisualHostKey no |
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com |
||||
# RekeyLimit 1G 1h |
||||
+# |
||||
+# Uncomment this if you want to use .local domain |
||||
+# Host *.local |
||||
+# CheckHostIP no |
@ -0,0 +1,295 @@
@@ -0,0 +1,295 @@
|
||||
diff --git a/log.c b/log.c |
||||
index 32e1d2e..d4caeb5 100644 |
||||
--- a/log.c |
||||
+++ b/log.c |
||||
@@ -241,6 +241,11 @@ debug3(const char *fmt,...) |
||||
void |
||||
log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) |
||||
{ |
||||
+ log_init_handler(av0, level, facility, on_stderr, 1); |
||||
+} |
||||
+ |
||||
+void |
||||
+log_init_handler(char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) { |
||||
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) |
||||
struct syslog_data sdata = SYSLOG_DATA_INIT; |
||||
#endif |
||||
@@ -264,8 +269,10 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) |
||||
exit(1); |
||||
} |
||||
|
||||
- log_handler = NULL; |
||||
- log_handler_ctx = NULL; |
||||
+ if (reset_handler) { |
||||
+ log_handler = NULL; |
||||
+ log_handler_ctx = NULL; |
||||
+ } |
||||
|
||||
log_on_stderr = on_stderr; |
||||
if (on_stderr) |
||||
diff --git a/log.h b/log.h |
||||
index ae7df25..30c3310 100644 |
||||
--- a/log.h |
||||
+++ b/log.h |
||||
@@ -49,6 +49,7 @@ typedef enum { |
||||
typedef void (log_handler_fn)(LogLevel, const char *, void *); |
||||
|
||||
void log_init(char *, LogLevel, SyslogFacility, int); |
||||
+void log_init_handler(char *, LogLevel, SyslogFacility, int, int); |
||||
void log_change_level(LogLevel); |
||||
int log_is_on_stderr(void); |
||||
void log_redirect_stderr_to(const char *); |
||||
diff --git a/monitor.c b/monitor.c |
||||
index 7461fae..da2f766 100644 |
||||
--- a/monitor.c |
||||
+++ b/monitor.c |
||||
@@ -364,6 +364,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) |
||||
close(pmonitor->m_log_sendfd); |
||||
pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; |
||||
|
||||
+ pmonitor->m_state = "preauth"; |
||||
+ |
||||
authctxt = _authctxt; |
||||
memset(authctxt, 0, sizeof(*authctxt)); |
||||
|
||||
@@ -472,6 +474,8 @@ monitor_child_postauth(struct monitor *pmonitor) |
||||
close(pmonitor->m_recvfd); |
||||
pmonitor->m_recvfd = -1; |
||||
|
||||
+ pmonitor->m_state = "postauth"; |
||||
+ |
||||
monitor_set_child_handler(pmonitor->m_pid); |
||||
signal(SIGHUP, &monitor_child_handler); |
||||
signal(SIGTERM, &monitor_child_handler); |
||||
@@ -552,7 +556,7 @@ monitor_read_log(struct monitor *pmonitor) |
||||
if (log_level_name(level) == NULL) |
||||
fatal("%s: invalid log level %u (corrupted message?)", |
||||
__func__, level); |
||||
- do_log2(level, "%s [preauth]", msg); |
||||
+ do_log2(level, "%s [%s]", msg, pmonitor->m_state); |
||||
|
||||
buffer_free(&logmsg); |
||||
free(msg); |
||||
@@ -2083,13 +2087,28 @@ monitor_init(void) |
||||
mm_init_compression(mon->m_zlib); |
||||
} |
||||
|
||||
+ mon->m_state = ""; |
||||
+ |
||||
return mon; |
||||
} |
||||
|
||||
void |
||||
-monitor_reinit(struct monitor *mon) |
||||
+monitor_reinit(struct monitor *mon, const char *chroot_dir) |
||||
{ |
||||
- monitor_openfds(mon, 0); |
||||
+ struct stat dev_log_stat; |
||||
+ char *dev_log_path; |
||||
+ int do_logfds = 0; |
||||
+ |
||||
+ if (chroot_dir != NULL) { |
||||
+ xasprintf(&dev_log_path, "%s/dev/log", chroot_dir); |
||||
+ |
||||
+ if (stat(dev_log_path, &dev_log_stat) != 0) { |
||||
+ debug("%s: /dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", __func__, chroot_dir); |
||||
+ do_logfds = 1; |
||||
+ } |
||||
+ free(dev_log_path); |
||||
+ } |
||||
+ monitor_openfds(mon, do_logfds); |
||||
} |
||||
|
||||
#ifdef GSSAPI |
||||
diff --git a/monitor.h b/monitor.h |
||||
index ff79fbb..00c2028 100644 |
||||
--- a/monitor.h |
||||
+++ b/monitor.h |
||||
@@ -83,10 +83,11 @@ struct monitor { |
||||
struct mm_master *m_zlib; |
||||
struct Kex **m_pkex; |
||||
pid_t m_pid; |
||||
+ char *m_state; |
||||
}; |
||||
|
||||
struct monitor *monitor_init(void); |
||||
-void monitor_reinit(struct monitor *); |
||||
+void monitor_reinit(struct monitor *, const char *); |
||||
void monitor_sync(struct monitor *); |
||||
|
||||
struct Authctxt; |
||||
diff --git a/session.c b/session.c |
||||
index e4add93..bc4a8dd 100644 |
||||
--- a/session.c |
||||
+++ b/session.c |
||||
@@ -160,6 +160,8 @@ login_cap_t *lc; |
||||
|
||||
static int is_child = 0; |
||||
|
||||
+static int have_dev_log = 1; |
||||
+ |
||||
/* Name and directory of socket for authentication agent forwarding. */ |
||||
static char *auth_sock_name = NULL; |
||||
static char *auth_sock_dir = NULL; |
||||
@@ -523,8 +525,8 @@ do_exec_no_pty(Session *s, const char *command) |
||||
is_child = 1; |
||||
|
||||
/* Child. Reinitialize the log since the pid has changed. */ |
||||
- log_init(__progname, options.log_level, |
||||
- options.log_facility, log_stderr); |
||||
+ log_init_handler(__progname, options.log_level, |
||||
+ options.log_facility, log_stderr, have_dev_log); |
||||
|
||||
/* |
||||
* Create a new session and process group since the 4.4BSD |
||||
@@ -692,8 +694,8 @@ do_exec_pty(Session *s, const char *command) |
||||
close(ptymaster); |
||||
|
||||
/* Child. Reinitialize the log because the pid has changed. */ |
||||
- log_init(__progname, options.log_level, |
||||
- options.log_facility, log_stderr); |
||||
+ log_init_handler(__progname, options.log_level, |
||||
+ options.log_facility, log_stderr, have_dev_log); |
||||
/* Close the master side of the pseudo tty. */ |
||||
close(ptyfd); |
||||
|
||||
@@ -797,6 +799,7 @@ do_exec(Session *s, const char *command) |
||||
int ret; |
||||
const char *forced = NULL; |
||||
char session_type[1024], *tty = NULL; |
||||
+ struct stat dev_log_stat; |
||||
|
||||
if (options.adm_forced_command) { |
||||
original_command = command; |
||||
@@ -854,6 +857,10 @@ do_exec(Session *s, const char *command) |
||||
tty += 5; |
||||
} |
||||
|
||||
+ if (lstat("/dev/log", &dev_log_stat) != 0) { |
||||
+ have_dev_log = 0; |
||||
+ } |
||||
+ |
||||
verbose("Starting session: %s%s%s for %s from %.200s port %d", |
||||
session_type, |
||||
tty == NULL ? "" : " on ", |
||||
@@ -1681,14 +1688,6 @@ child_close_fds(void) |
||||
* descriptors left by system functions. They will be closed later. |
||||
*/ |
||||
endpwent(); |
||||
- |
||||
- /* |
||||
- * Close any extra open file descriptors so that we don't have them |
||||
- * hanging around in clients. Note that we want to do this after |
||||
- * initgroups, because at least on Solaris 2.3 it leaves file |
||||
- * descriptors open. |
||||
- */ |
||||
- closefrom(STDERR_FILENO + 1); |
||||
} |
||||
|
||||
/* |
||||
@@ -1834,8 +1833,6 @@ do_child(Session *s, const char *command) |
||||
exit(1); |
||||
} |
||||
|
||||
- closefrom(STDERR_FILENO + 1); |
||||
- |
||||
if (!options.use_login) |
||||
do_rc_files(s, shell); |
||||
|
||||
@@ -1859,9 +1856,17 @@ do_child(Session *s, const char *command) |
||||
argv[i] = NULL; |
||||
optind = optreset = 1; |
||||
__progname = argv[0]; |
||||
- exit(sftp_server_main(i, argv, s->pw)); |
||||
+ exit(sftp_server_main(i, argv, s->pw, have_dev_log)); |
||||
} |
||||
|
||||
+ /* |
||||
+ * Close any extra open file descriptors so that we don't have them |
||||
+ * hanging around in clients. Note that we want to do this after |
||||
+ * initgroups, because at least on Solaris 2.3 it leaves file |
||||
+ * descriptors open. |
||||
+ */ |
||||
+ closefrom(STDERR_FILENO + 1); |
||||
+ |
||||
fflush(NULL); |
||||
|
||||
if (options.use_login) { |
||||
diff --git a/sftp-server-main.c b/sftp-server-main.c |
||||
index 7e644ab..e162b7a 100644 |
||||
--- a/sftp-server-main.c |
||||
+++ b/sftp-server-main.c |
||||
@@ -47,5 +47,5 @@ main(int argc, char **argv) |
||||
return 1; |
||||
} |
||||
|
||||
- return (sftp_server_main(argc, argv, user_pw)); |
||||
+ return (sftp_server_main(argc, argv, user_pw, 0)); |
||||
} |
||||
diff --git a/sftp-server.c b/sftp-server.c |
||||
index b8eb59c..a0e644c 100644 |
||||
--- a/sftp-server.c |
||||
+++ b/sftp-server.c |
||||
@@ -1437,7 +1437,7 @@ sftp_server_usage(void) |
||||
} |
||||
|
||||
int |
||||
-sftp_server_main(int argc, char **argv, struct passwd *user_pw) |
||||
+sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler) |
||||
{ |
||||
fd_set *rset, *wset; |
||||
int i, in, out, max, ch, skipargs = 0, log_stderr = 0; |
||||
@@ -1450,7 +1450,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) |
||||
extern char *__progname; |
||||
|
||||
__progname = ssh_get_progname(argv[0]); |
||||
- log_init(__progname, log_level, log_facility, log_stderr); |
||||
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); |
||||
|
||||
pw = pwcopy(user_pw); |
||||
|
||||
@@ -1521,7 +1521,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) |
||||
} |
||||
} |
||||
|
||||
- log_init(__progname, log_level, log_facility, log_stderr); |
||||
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); |
||||
|
||||
if ((cp = getenv("SSH_CONNECTION")) != NULL) { |
||||
client_addr = xstrdup(cp); |
||||
diff --git a/sftp.h b/sftp.h |
||||
index 2bde8bb..ddf1a39 100644 |
||||
--- a/sftp.h |
||||
+++ b/sftp.h |
||||
@@ -97,5 +97,5 @@ |
||||
|
||||
struct passwd; |
||||
|
||||
-int sftp_server_main(int, char **, struct passwd *); |
||||
+int sftp_server_main(int, char **, struct passwd *, int); |
||||
void sftp_server_cleanup_exit(int) __attribute__((noreturn)); |
||||
diff --git a/sshd.c b/sshd.c |
||||
index 3eee75a..9c00bcb 100644 |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -745,7 +745,7 @@ privsep_postauth(Authctxt *authctxt) |
||||
} |
||||
|
||||
/* New socket pair */ |
||||
- monitor_reinit(pmonitor); |
||||
+ monitor_reinit(pmonitor, options.chroot_directory); |
||||
|
||||
pmonitor->m_pid = fork(); |
||||
if (pmonitor->m_pid == -1) |
||||
@@ -763,6 +763,11 @@ privsep_postauth(Authctxt *authctxt) |
||||
|
||||
close(pmonitor->m_sendfd); |
||||
pmonitor->m_sendfd = -1; |
||||
+ close(pmonitor->m_log_recvfd); |
||||
+ pmonitor->m_log_recvfd = -1; |
||||
+ |
||||
+ if (pmonitor->m_log_sendfd != -1) |
||||
+ set_log_handler(mm_log_handler, pmonitor); |
||||
|
||||
/* Demote the private keys to public keys. */ |
||||
demote_sensitive_data(); |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff --git a/session.c b/session.c |
||||
index 626a642..b186ca1 100644 |
||||
--- a/session.c |
||||
+++ b/session.c |
||||
@@ -1859,6 +1859,7 @@ do_child(Session *s, const char *command) |
||||
|
||||
if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { |
||||
printf("This service allows sftp connections only.\n"); |
||||
+ logit("The session allows sftp connections only"); |
||||
fflush(NULL); |
||||
exit(1); |
||||
} else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c |
||||
index 22ea8ef..2660085 100644 |
||||
--- a/openbsd-compat/port-linux.c |
||||
+++ b/openbsd-compat/port-linux.c |
||||
@@ -116,7 +116,11 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) |
||||
|
||||
debug3("%s: setting TTY context on %s", __func__, tty); |
||||
|
||||
- user_ctx = ssh_selinux_getctxbyname(pwname); |
||||
+ if (getexeccon(&user_ctx) != 0) { |
||||
+ error("%s: getexeccon: %s", __func__, strerror(errno)); |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
|
||||
/* XXX: should these calls fatal() upon failure in enforcing mode? */ |
||||
|
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
diff --git a/auth2.c b/auth2.c |
||||
index d9b440a..ec0bf12 100644 |
||||
--- a/auth2.c |
||||
+++ b/auth2.c |
||||
@@ -355,8 +355,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, |
||||
authctxt->success = 1; |
||||
} else { |
||||
|
||||
- /* Allow initial try of "none" auth without failure penalty */ |
||||
- if (!authctxt->server_caused_failure && |
||||
+ /* Allow initial try of "none" auth without failure penalty |
||||
+ * Partial succes is not failure */ |
||||
+ if (!authctxt->server_caused_failure && !partial && |
||||
(authctxt->attempt > 1 || strcmp(method, "none") != 0)) |
||||
authctxt->failures++; |
||||
if (authctxt->failures >= options.max_authtries) { |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
diff --git a/servconf.c b/servconf.c |
||||
index b7f3294..bc1e909 100644 |
||||
--- a/servconf.c |
||||
+++ b/servconf.c |
||||
@@ -1550,7 +1550,7 @@ process_server_config_line(ServerOptions *options, char *line, |
||||
break; |
||||
|
||||
case sForceCommand: |
||||
- if (cp == NULL) |
||||
+ if (cp == NULL || *cp == '\0') |
||||
fatal("%.200s line %d: Missing argument.", filename, |
||||
linenum); |
||||
len = strspn(cp, WHITESPACE); |
||||
@@ -1595,7 +1595,7 @@ process_server_config_line(ServerOptions *options, char *line, |
||||
break; |
||||
|
||||
case sVersionAddendum: |
||||
- if (cp == NULL) |
||||
+ if (cp == NULL || *cp == '\0') |
||||
fatal("%.200s line %d: Missing argument.", filename, |
||||
linenum); |
||||
len = strspn(cp, WHITESPACE); |
||||
@@ -1630,6 +1630,8 @@ process_server_config_line(ServerOptions *options, char *line, |
||||
break; |
||||
|
||||
case sAuthenticationMethods: |
||||
+ if (cp == NULL || *cp == '\0') |
||||
+ fatal("%.200s line %d: Missing argument.", filename, linenum); |
||||
if (*activep && options->num_auth_methods == 0) { |
||||
while ((arg = strdelim(&cp)) && *arg != '\0') { |
||||
if (options->num_auth_methods >= |
@ -0,0 +1,994 @@
@@ -0,0 +1,994 @@
|
||||
diff --git a/Makefile.in b/Makefile.in |
||||
index 2ad26ff..0f0d39f 100644 |
||||
--- a/Makefile.in |
||||
+++ b/Makefile.in |
||||
@@ -81,7 +81,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ |
||||
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.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-openssl.o hmac.o \ |
||||
+ ssh-ed25519.o digest-openssl.o hmac.o utf8_stringprep.o \ |
||||
sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o |
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ |
||||
diff --git a/misc.h b/misc.h |
||||
index d4df619..d98b83d 100644 |
||||
--- a/misc.h |
||||
+++ b/misc.h |
||||
@@ -106,4 +106,7 @@ char *read_passphrase(const char *, int); |
||||
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); |
||||
int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); |
||||
|
||||
+/* utf8_stringprep.c */ |
||||
+int utf8_stringprep(const char *, char *, size_t); |
||||
+ |
||||
#endif /* _MISC_H */ |
||||
diff --git a/sshconnect2.c b/sshconnect2.c |
||||
index b00658b..08064f4 100644 |
||||
--- a/sshconnect2.c |
||||
+++ b/sshconnect2.c |
||||
@@ -33,6 +33,8 @@ |
||||
|
||||
#include <errno.h> |
||||
#include <fcntl.h> |
||||
+#include <langinfo.h> |
||||
+#include <locale.h> |
||||
#include <netdb.h> |
||||
#include <pwd.h> |
||||
#include <signal.h> |
||||
@@ -519,21 +521,51 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt) |
||||
"type %d", type); |
||||
} |
||||
|
||||
+/* Check whether we can display UTF-8 safely */ |
||||
+static int |
||||
+utf8_ok(void) |
||||
+{ |
||||
+ static int ret = -1; |
||||
+ char *cp; |
||||
+ |
||||
+ if (ret == -1) { |
||||
+ setlocale(LC_CTYPE, ""); |
||||
+ cp = nl_langinfo(CODESET); |
||||
+ ret = strcmp(cp, "UTF-8") == 0; |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+ |
||||
/* ARGSUSED */ |
||||
void |
||||
input_userauth_banner(int type, u_int32_t seq, void *ctxt) |
||||
{ |
||||
char *msg, *raw, *lang; |
||||
- u_int len; |
||||
+ u_int done, len; |
||||
|
||||
debug3("input_userauth_banner"); |
||||
+ |
||||
raw = packet_get_string(&len); |
||||
lang = packet_get_string(NULL); |
||||
if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { |
||||
if (len > 65536) |
||||
len = 65536; |
||||
msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ |
||||
- strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); |
||||
+ done = 0; |
||||
+ if (utf8_ok()) { |
||||
+ if (utf8_stringprep(raw, msg, len * 4 + 1) == 0) |
||||
+ done = 1; |
||||
+ else |
||||
+ debug2("%s: UTF8 stringprep failed", __func__); |
||||
+ } |
||||
+ /* |
||||
+ * Fallback to strnvis if UTF8 display not supported or |
||||
+ * conversion failed. |
||||
+ */ |
||||
+ if (!done) { |
||||
+ strnvis(msg, raw, len * 4 + 1, |
||||
+ VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); |
||||
+ } |
||||
fprintf(stderr, "%s", msg); |
||||
free(msg); |
||||
} |
||||
diff --git a/stringprep-tables.c b/stringprep-tables.c |
||||
new file mode 100644 |
||||
index 0000000..49f4d9d |
||||
--- /dev/null |
||||
+++ b/stringprep-tables.c |
||||
@@ -0,0 +1,661 @@ |
||||
+/* Public domain. */ |
||||
+ |
||||
+/* $OpenBSD$ */ |
||||
+ |
||||
+/* |
||||
+ * Tables for RFC3454 stringprep algorithm, updated with a table of allocated |
||||
+ * characters generated from Unicode.6.2's UnicodeData.txt |
||||
+ * |
||||
+ * Intended to be included directly from utf8_stringprep.c |
||||
+ */ |
||||
+ |
||||
+/* Unassigned characters in Unicode 6.2 */ |
||||
+static const struct u32_range unassigned[] = { |
||||
+ { 0x0378, 0x0379 }, |
||||
+ { 0x037F, 0x0383 }, |
||||
+ { 0x038B, 0x038B }, |
||||
+ { 0x038D, 0x038D }, |
||||
+ { 0x03A2, 0x03A2 }, |
||||
+ { 0x0528, 0x0530 }, |
||||
+ { 0x0557, 0x0558 }, |
||||
+ { 0x0560, 0x0560 }, |
||||
+ { 0x0588, 0x0588 }, |
||||
+ { 0x058B, 0x058E }, |
||||
+ { 0x0590, 0x0590 }, |
||||
+ { 0x05C8, 0x05CF }, |
||||
+ { 0x05EB, 0x05EF }, |
||||
+ { 0x05F5, 0x05FF }, |
||||
+ { 0x0605, 0x0605 }, |
||||
+ { 0x061C, 0x061D }, |
||||
+ { 0x070E, 0x070E }, |
||||
+ { 0x074B, 0x074C }, |
||||
+ { 0x07B2, 0x07BF }, |
||||
+ { 0x07FB, 0x07FF }, |
||||
+ { 0x082E, 0x082F }, |
||||
+ { 0x083F, 0x083F }, |
||||
+ { 0x085C, 0x085D }, |
||||
+ { 0x085F, 0x089F }, |
||||
+ { 0x08A1, 0x08A1 }, |
||||
+ { 0x08AD, 0x08E3 }, |
||||
+ { 0x08FF, 0x08FF }, |
||||
+ { 0x0978, 0x0978 }, |
||||
+ { 0x0980, 0x0980 }, |
||||
+ { 0x0984, 0x0984 }, |
||||
+ { 0x098D, 0x098E }, |
||||
+ { 0x0991, 0x0992 }, |
||||
+ { 0x09A9, 0x09A9 }, |
||||
+ { 0x09B1, 0x09B1 }, |
||||
+ { 0x09B3, 0x09B5 }, |
||||
+ { 0x09BA, 0x09BB }, |
||||
+ { 0x09C5, 0x09C6 }, |
||||
+ { 0x09C9, 0x09CA }, |
||||
+ { 0x09CF, 0x09D6 }, |
||||
+ { 0x09D8, 0x09DB }, |
||||
+ { 0x09DE, 0x09DE }, |
||||
+ { 0x09E4, 0x09E5 }, |
||||
+ { 0x09FC, 0x0A00 }, |
||||
+ { 0x0A04, 0x0A04 }, |
||||
+ { 0x0A0B, 0x0A0E }, |
||||
+ { 0x0A11, 0x0A12 }, |
||||
+ { 0x0A29, 0x0A29 }, |
||||
+ { 0x0A31, 0x0A31 }, |
||||
+ { 0x0A34, 0x0A34 }, |
||||
+ { 0x0A37, 0x0A37 }, |
||||
+ { 0x0A3A, 0x0A3B }, |
||||
+ { 0x0A3D, 0x0A3D }, |
||||
+ { 0x0A43, 0x0A46 }, |
||||
+ { 0x0A49, 0x0A4A }, |
||||
+ { 0x0A4E, 0x0A50 }, |
||||
+ { 0x0A52, 0x0A58 }, |
||||
+ { 0x0A5D, 0x0A5D }, |
||||
+ { 0x0A5F, 0x0A65 }, |
||||
+ { 0x0A76, 0x0A80 }, |
||||
+ { 0x0A84, 0x0A84 }, |
||||
+ { 0x0A8E, 0x0A8E }, |
||||
+ { 0x0A92, 0x0A92 }, |
||||
+ { 0x0AA9, 0x0AA9 }, |
||||
+ { 0x0AB1, 0x0AB1 }, |
||||
+ { 0x0AB4, 0x0AB4 }, |
||||
+ { 0x0ABA, 0x0ABB }, |
||||
+ { 0x0AC6, 0x0AC6 }, |
||||
+ { 0x0ACA, 0x0ACA }, |
||||
+ { 0x0ACE, 0x0ACF }, |
||||
+ { 0x0AD1, 0x0ADF }, |
||||
+ { 0x0AE4, 0x0AE5 }, |
||||
+ { 0x0AF2, 0x0B00 }, |
||||
+ { 0x0B04, 0x0B04 }, |
||||
+ { 0x0B0D, 0x0B0E }, |
||||
+ { 0x0B11, 0x0B12 }, |
||||
+ { 0x0B29, 0x0B29 }, |
||||
+ { 0x0B31, 0x0B31 }, |
||||
+ { 0x0B34, 0x0B34 }, |
||||
+ { 0x0B3A, 0x0B3B }, |
||||
+ { 0x0B45, 0x0B46 }, |
||||
+ { 0x0B49, 0x0B4A }, |
||||
+ { 0x0B4E, 0x0B55 }, |
||||
+ { 0x0B58, 0x0B5B }, |
||||
+ { 0x0B5E, 0x0B5E }, |
||||
+ { 0x0B64, 0x0B65 }, |
||||
+ { 0x0B78, 0x0B81 }, |
||||
+ { 0x0B84, 0x0B84 }, |
||||
+ { 0x0B8B, 0x0B8D }, |
||||
+ { 0x0B91, 0x0B91 }, |
||||
+ { 0x0B96, 0x0B98 }, |
||||
+ { 0x0B9B, 0x0B9B }, |
||||
+ { 0x0B9D, 0x0B9D }, |
||||
+ { 0x0BA0, 0x0BA2 }, |
||||
+ { 0x0BA5, 0x0BA7 }, |
||||
+ { 0x0BAB, 0x0BAD }, |
||||
+ { 0x0BBA, 0x0BBD }, |
||||
+ { 0x0BC3, 0x0BC5 }, |
||||
+ { 0x0BC9, 0x0BC9 }, |
||||
+ { 0x0BCE, 0x0BCF }, |
||||
+ { 0x0BD1, 0x0BD6 }, |
||||
+ { 0x0BD8, 0x0BE5 }, |
||||
+ { 0x0BFB, 0x0C00 }, |
||||
+ { 0x0C04, 0x0C04 }, |
||||
+ { 0x0C0D, 0x0C0D }, |
||||
+ { 0x0C11, 0x0C11 }, |
||||
+ { 0x0C29, 0x0C29 }, |
||||
+ { 0x0C34, 0x0C34 }, |
||||
+ { 0x0C3A, 0x0C3C }, |
||||
+ { 0x0C45, 0x0C45 }, |
||||
+ { 0x0C49, 0x0C49 }, |
||||
+ { 0x0C4E, 0x0C54 }, |
||||
+ { 0x0C57, 0x0C57 }, |
||||
+ { 0x0C5A, 0x0C5F }, |
||||
+ { 0x0C64, 0x0C65 }, |
||||
+ { 0x0C70, 0x0C77 }, |
||||
+ { 0x0C80, 0x0C81 }, |
||||
+ { 0x0C84, 0x0C84 }, |
||||
+ { 0x0C8D, 0x0C8D }, |
||||
+ { 0x0C91, 0x0C91 }, |
||||
+ { 0x0CA9, 0x0CA9 }, |
||||
+ { 0x0CB4, 0x0CB4 }, |
||||
+ { 0x0CBA, 0x0CBB }, |
||||
+ { 0x0CC5, 0x0CC5 }, |
||||
+ { 0x0CC9, 0x0CC9 }, |
||||
+ { 0x0CCE, 0x0CD4 }, |
||||
+ { 0x0CD7, 0x0CDD }, |
||||
+ { 0x0CDF, 0x0CDF }, |
||||
+ { 0x0CE4, 0x0CE5 }, |
||||
+ { 0x0CF0, 0x0CF0 }, |
||||
+ { 0x0CF3, 0x0D01 }, |
||||
+ { 0x0D04, 0x0D04 }, |
||||
+ { 0x0D0D, 0x0D0D }, |
||||
+ { 0x0D11, 0x0D11 }, |
||||
+ { 0x0D3B, 0x0D3C }, |
||||
+ { 0x0D45, 0x0D45 }, |
||||
+ { 0x0D49, 0x0D49 }, |
||||
+ { 0x0D4F, 0x0D56 }, |
||||
+ { 0x0D58, 0x0D5F }, |
||||
+ { 0x0D64, 0x0D65 }, |
||||
+ { 0x0D76, 0x0D78 }, |
||||
+ { 0x0D80, 0x0D81 }, |
||||
+ { 0x0D84, 0x0D84 }, |
||||
+ { 0x0D97, 0x0D99 }, |
||||
+ { 0x0DB2, 0x0DB2 }, |
||||
+ { 0x0DBC, 0x0DBC }, |
||||
+ { 0x0DBE, 0x0DBF }, |
||||
+ { 0x0DC7, 0x0DC9 }, |
||||
+ { 0x0DCB, 0x0DCE }, |
||||
+ { 0x0DD5, 0x0DD5 }, |
||||
+ { 0x0DD7, 0x0DD7 }, |
||||
+ { 0x0DE0, 0x0DF1 }, |
||||
+ { 0x0DF5, 0x0E00 }, |
||||
+ { 0x0E3B, 0x0E3E }, |
||||
+ { 0x0E5C, 0x0E80 }, |
||||
+ { 0x0E83, 0x0E83 }, |
||||
+ { 0x0E85, 0x0E86 }, |
||||
+ { 0x0E89, 0x0E89 }, |
||||
+ { 0x0E8B, 0x0E8C }, |
||||
+ { 0x0E8E, 0x0E93 }, |
||||
+ { 0x0E98, 0x0E98 }, |
||||
+ { 0x0EA0, 0x0EA0 }, |
||||
+ { 0x0EA4, 0x0EA4 }, |
||||
+ { 0x0EA6, 0x0EA6 }, |
||||
+ { 0x0EA8, 0x0EA9 }, |
||||
+ { 0x0EAC, 0x0EAC }, |
||||
+ { 0x0EBA, 0x0EBA }, |
||||
+ { 0x0EBE, 0x0EBF }, |
||||
+ { 0x0EC5, 0x0EC5 }, |
||||
+ { 0x0EC7, 0x0EC7 }, |
||||
+ { 0x0ECE, 0x0ECF }, |
||||
+ { 0x0EDA, 0x0EDB }, |
||||
+ { 0x0EE0, 0x0EFF }, |
||||
+ { 0x0F48, 0x0F48 }, |
||||
+ { 0x0F6D, 0x0F70 }, |
||||
+ { 0x0F98, 0x0F98 }, |
||||
+ { 0x0FBD, 0x0FBD }, |
||||
+ { 0x0FCD, 0x0FCD }, |
||||
+ { 0x0FDB, 0x0FFF }, |
||||
+ { 0x10C6, 0x10C6 }, |
||||
+ { 0x10C8, 0x10CC }, |
||||
+ { 0x10CE, 0x10CF }, |
||||
+ { 0x1249, 0x1249 }, |
||||
+ { 0x124E, 0x124F }, |
||||
+ { 0x1257, 0x1257 }, |
||||
+ { 0x1259, 0x1259 }, |
||||
+ { 0x125E, 0x125F }, |
||||
+ { 0x1289, 0x1289 }, |
||||
+ { 0x128E, 0x128F }, |
||||
+ { 0x12B1, 0x12B1 }, |
||||
+ { 0x12B6, 0x12B7 }, |
||||
+ { 0x12BF, 0x12BF }, |
||||
+ { 0x12C1, 0x12C1 }, |
||||
+ { 0x12C6, 0x12C7 }, |
||||
+ { 0x12D7, 0x12D7 }, |
||||
+ { 0x1311, 0x1311 }, |
||||
+ { 0x1316, 0x1317 }, |
||||
+ { 0x135B, 0x135C }, |
||||
+ { 0x137D, 0x137F }, |
||||
+ { 0x139A, 0x139F }, |
||||
+ { 0x13F5, 0x13FF }, |
||||
+ { 0x169D, 0x169F }, |
||||
+ { 0x16F1, 0x16FF }, |
||||
+ { 0x170D, 0x170D }, |
||||
+ { 0x1715, 0x171F }, |
||||
+ { 0x1737, 0x173F }, |
||||
+ { 0x1754, 0x175F }, |
||||
+ { 0x176D, 0x176D }, |
||||
+ { 0x1771, 0x1771 }, |
||||
+ { 0x1774, 0x177F }, |
||||
+ { 0x17DE, 0x17DF }, |
||||
+ { 0x17EA, 0x17EF }, |
||||
+ { 0x17FA, 0x17FF }, |
||||
+ { 0x180F, 0x180F }, |
||||
+ { 0x181A, 0x181F }, |
||||
+ { 0x1878, 0x187F }, |
||||
+ { 0x18AB, 0x18AF }, |
||||
+ { 0x18F6, 0x18FF }, |
||||
+ { 0x191D, 0x191F }, |
||||
+ { 0x192C, 0x192F }, |
||||
+ { 0x193C, 0x193F }, |
||||
+ { 0x1941, 0x1943 }, |
||||
+ { 0x196E, 0x196F }, |
||||
+ { 0x1975, 0x197F }, |
||||
+ { 0x19AC, 0x19AF }, |
||||
+ { 0x19CA, 0x19CF }, |
||||
+ { 0x19DB, 0x19DD }, |
||||
+ { 0x1A1C, 0x1A1D }, |
||||
+ { 0x1A5F, 0x1A5F }, |
||||
+ { 0x1A7D, 0x1A7E }, |
||||
+ { 0x1A8A, 0x1A8F }, |
||||
+ { 0x1A9A, 0x1A9F }, |
||||
+ { 0x1AAE, 0x1AFF }, |
||||
+ { 0x1B4C, 0x1B4F }, |
||||
+ { 0x1B7D, 0x1B7F }, |
||||
+ { 0x1BF4, 0x1BFB }, |
||||
+ { 0x1C38, 0x1C3A }, |
||||
+ { 0x1C4A, 0x1C4C }, |
||||
+ { 0x1C80, 0x1CBF }, |
||||
+ { 0x1CC8, 0x1CCF }, |
||||
+ { 0x1CF7, 0x1CFF }, |
||||
+ { 0x1DE7, 0x1DFB }, |
||||
+ { 0x1F16, 0x1F17 }, |
||||
+ { 0x1F1E, 0x1F1F }, |
||||
+ { 0x1F46, 0x1F47 }, |
||||
+ { 0x1F4E, 0x1F4F }, |
||||
+ { 0x1F58, 0x1F58 }, |
||||
+ { 0x1F5A, 0x1F5A }, |
||||
+ { 0x1F5C, 0x1F5C }, |
||||
+ { 0x1F5E, 0x1F5E }, |
||||
+ { 0x1F7E, 0x1F7F }, |
||||
+ { 0x1FB5, 0x1FB5 }, |
||||
+ { 0x1FC5, 0x1FC5 }, |
||||
+ { 0x1FD4, 0x1FD5 }, |
||||
+ { 0x1FDC, 0x1FDC }, |
||||
+ { 0x1FF0, 0x1FF1 }, |
||||
+ { 0x1FF5, 0x1FF5 }, |
||||
+ { 0x1FFF, 0x1FFF }, |
||||
+ { 0x2065, 0x2069 }, |
||||
+ { 0x2072, 0x2073 }, |
||||
+ { 0x208F, 0x208F }, |
||||
+ { 0x209D, 0x209F }, |
||||
+ { 0x20BB, 0x20CF }, |
||||
+ { 0x20F1, 0x20FF }, |
||||
+ { 0x218A, 0x218F }, |
||||
+ { 0x23F4, 0x23FF }, |
||||
+ { 0x2427, 0x243F }, |
||||
+ { 0x244B, 0x245F }, |
||||
+ { 0x2700, 0x2700 }, |
||||
+ { 0x2B4D, 0x2B4F }, |
||||
+ { 0x2B5A, 0x2BFF }, |
||||
+ { 0x2C2F, 0x2C2F }, |
||||
+ { 0x2C5F, 0x2C5F }, |
||||
+ { 0x2CF4, 0x2CF8 }, |
||||
+ { 0x2D26, 0x2D26 }, |
||||
+ { 0x2D28, 0x2D2C }, |
||||
+ { 0x2D2E, 0x2D2F }, |
||||
+ { 0x2D68, 0x2D6E }, |
||||
+ { 0x2D71, 0x2D7E }, |
||||
+ { 0x2D97, 0x2D9F }, |
||||
+ { 0x2DA7, 0x2DA7 }, |
||||
+ { 0x2DAF, 0x2DAF }, |
||||
+ { 0x2DB7, 0x2DB7 }, |
||||
+ { 0x2DBF, 0x2DBF }, |
||||
+ { 0x2DC7, 0x2DC7 }, |
||||
+ { 0x2DCF, 0x2DCF }, |
||||
+ { 0x2DD7, 0x2DD7 }, |
||||
+ { 0x2DDF, 0x2DDF }, |
||||
+ { 0x2E3C, 0x2E7F }, |
||||
+ { 0x2E9A, 0x2E9A }, |
||||
+ { 0x2EF4, 0x2EFF }, |
||||
+ { 0x2FD6, 0x2FEF }, |
||||
+ { 0x2FFC, 0x2FFF }, |
||||
+ { 0x3040, 0x3040 }, |
||||
+ { 0x3097, 0x3098 }, |
||||
+ { 0x3100, 0x3104 }, |
||||
+ { 0x312E, 0x3130 }, |
||||
+ { 0x318F, 0x318F }, |
||||
+ { 0x31BB, 0x31BF }, |
||||
+ { 0x31E4, 0x31EF }, |
||||
+ { 0x321F, 0x321F }, |
||||
+ { 0x32FF, 0x32FF }, |
||||
+ { 0x4DB6, 0x4DBF }, |
||||
+ { 0x9FA6, 0x9FCB }, |
||||
+ { 0x9FCD, 0x9FFF }, |
||||
+ { 0xA48D, 0xA48F }, |
||||
+ { 0xA4C7, 0xA4CF }, |
||||
+ { 0xA62C, 0xA63F }, |
||||
+ { 0xA698, 0xA69E }, |
||||
+ { 0xA6F8, 0xA6FF }, |
||||
+ { 0xA78F, 0xA78F }, |
||||
+ { 0xA794, 0xA79F }, |
||||
+ { 0xA7AB, 0xA7F7 }, |
||||
+ { 0xA82C, 0xA82F }, |
||||
+ { 0xA83A, 0xA83F }, |
||||
+ { 0xA878, 0xA87F }, |
||||
+ { 0xA8C5, 0xA8CD }, |
||||
+ { 0xA8DA, 0xA8DF }, |
||||
+ { 0xA8FC, 0xA8FF }, |
||||
+ { 0xA954, 0xA95E }, |
||||
+ { 0xA97D, 0xA97F }, |
||||
+ { 0xA9CE, 0xA9CE }, |
||||
+ { 0xA9DA, 0xA9DD }, |
||||
+ { 0xA9E0, 0xA9FF }, |
||||
+ { 0xAA37, 0xAA3F }, |
||||
+ { 0xAA4E, 0xAA4F }, |
||||
+ { 0xAA5A, 0xAA5B }, |
||||
+ { 0xAA7C, 0xAA7F }, |
||||
+ { 0xAAC3, 0xAADA }, |
||||
+ { 0xAAF7, 0xAB00 }, |
||||
+ { 0xAB07, 0xAB08 }, |
||||
+ { 0xAB0F, 0xAB10 }, |
||||
+ { 0xAB17, 0xAB1F }, |
||||
+ { 0xAB27, 0xAB27 }, |
||||
+ { 0xAB2F, 0xABBF }, |
||||
+ { 0xABEE, 0xABEF }, |
||||
+ { 0xABFA, 0xABFF }, |
||||
+ { 0xD7A4, 0xD7AF }, |
||||
+ { 0xD7C7, 0xD7CA }, |
||||
+ { 0xD7FC, 0xD7FF }, |
||||
+ { 0xFA6E, 0xFA6F }, |
||||
+ { 0xFADA, 0xFAFF }, |
||||
+ { 0xFB07, 0xFB12 }, |
||||
+ { 0xFB18, 0xFB1C }, |
||||
+ { 0xFB37, 0xFB37 }, |
||||
+ { 0xFB3D, 0xFB3D }, |
||||
+ { 0xFB3F, 0xFB3F }, |
||||
+ { 0xFB42, 0xFB42 }, |
||||
+ { 0xFB45, 0xFB45 }, |
||||
+ { 0xFBC2, 0xFBD2 }, |
||||
+ { 0xFD40, 0xFD4F }, |
||||
+ { 0xFD90, 0xFD91 }, |
||||
+ { 0xFDC8, 0xFDCF }, |
||||
+ { 0xFDFE, 0xFDFF }, |
||||
+ { 0xFE1A, 0xFE1F }, |
||||
+ { 0xFE27, 0xFE2F }, |
||||
+ { 0xFE53, 0xFE53 }, |
||||
+ { 0xFE67, 0xFE67 }, |
||||
+ { 0xFE6C, 0xFE6F }, |
||||
+ { 0xFE75, 0xFE75 }, |
||||
+ { 0xFEFD, 0xFEFE }, |
||||
+ { 0xFF00, 0xFF00 }, |
||||
+ { 0xFFBF, 0xFFC1 }, |
||||
+ { 0xFFC8, 0xFFC9 }, |
||||
+ { 0xFFD0, 0xFFD1 }, |
||||
+ { 0xFFD8, 0xFFD9 }, |
||||
+ { 0xFFDD, 0xFFDF }, |
||||
+ { 0xFFE7, 0xFFE7 }, |
||||
+ { 0xFFEF, 0xFFF8 }, |
||||
+ { 0x1000C, 0x1000C }, |
||||
+ { 0x10027, 0x10027 }, |
||||
+ { 0x1003B, 0x1003B }, |
||||
+ { 0x1003E, 0x1003E }, |
||||
+ { 0x1004E, 0x1004F }, |
||||
+ { 0x1005E, 0x1007F }, |
||||
+ { 0x100FB, 0x100FF }, |
||||
+ { 0x10103, 0x10106 }, |
||||
+ { 0x10134, 0x10136 }, |
||||
+ { 0x1018B, 0x1018F }, |
||||
+ { 0x1019C, 0x101CF }, |
||||
+ { 0x101FE, 0x1027F }, |
||||
+ { 0x1029D, 0x1029F }, |
||||
+ { 0x102D1, 0x102FF }, |
||||
+ { 0x1031F, 0x1031F }, |
||||
+ { 0x10324, 0x1032F }, |
||||
+ { 0x1034B, 0x1037F }, |
||||
+ { 0x1039E, 0x1039E }, |
||||
+ { 0x103C4, 0x103C7 }, |
||||
+ { 0x103D6, 0x103FF }, |
||||
+ { 0x1049E, 0x1049F }, |
||||
+ { 0x104AA, 0x107FF }, |
||||
+ { 0x10806, 0x10807 }, |
||||
+ { 0x10809, 0x10809 }, |
||||
+ { 0x10836, 0x10836 }, |
||||
+ { 0x10839, 0x1083B }, |
||||
+ { 0x1083D, 0x1083E }, |
||||
+ { 0x10856, 0x10856 }, |
||||
+ { 0x10860, 0x108FF }, |
||||
+ { 0x1091C, 0x1091E }, |
||||
+ { 0x1093A, 0x1093E }, |
||||
+ { 0x10940, 0x1097F }, |
||||
+ { 0x109B8, 0x109BD }, |
||||
+ { 0x109C0, 0x109FF }, |
||||
+ { 0x10A04, 0x10A04 }, |
||||
+ { 0x10A07, 0x10A0B }, |
||||
+ { 0x10A14, 0x10A14 }, |
||||
+ { 0x10A18, 0x10A18 }, |
||||
+ { 0x10A34, 0x10A37 }, |
||||
+ { 0x10A3B, 0x10A3E }, |
||||
+ { 0x10A48, 0x10A4F }, |
||||
+ { 0x10A59, 0x10A5F }, |
||||
+ { 0x10A80, 0x10AFF }, |
||||
+ { 0x10B36, 0x10B38 }, |
||||
+ { 0x10B56, 0x10B57 }, |
||||
+ { 0x10B73, 0x10B77 }, |
||||
+ { 0x10B80, 0x10BFF }, |
||||
+ { 0x10C49, 0x10E5F }, |
||||
+ { 0x10E7F, 0x10FFF }, |
||||
+ { 0x1104E, 0x11051 }, |
||||
+ { 0x11070, 0x1107F }, |
||||
+ { 0x110C2, 0x110CF }, |
||||
+ { 0x110E9, 0x110EF }, |
||||
+ { 0x110FA, 0x110FF }, |
||||
+ { 0x11135, 0x11135 }, |
||||
+ { 0x11144, 0x1117F }, |
||||
+ { 0x111C9, 0x111CF }, |
||||
+ { 0x111DA, 0x1167F }, |
||||
+ { 0x116B8, 0x116BF }, |
||||
+ { 0x116CA, 0x11FFF }, |
||||
+ { 0x1236F, 0x123FF }, |
||||
+ { 0x12463, 0x1246F }, |
||||
+ { 0x12474, 0x12FFF }, |
||||
+ { 0x1342F, 0x167FF }, |
||||
+ { 0x16A39, 0x16EFF }, |
||||
+ { 0x16F45, 0x16F4F }, |
||||
+ { 0x16F7F, 0x16F8E }, |
||||
+ { 0x16FA0, 0x1AFFF }, |
||||
+ { 0x1B002, 0x1CFFF }, |
||||
+ { 0x1D0F6, 0x1D0FF }, |
||||
+ { 0x1D127, 0x1D128 }, |
||||
+ { 0x1D1DE, 0x1D1FF }, |
||||
+ { 0x1D246, 0x1D2FF }, |
||||
+ { 0x1D357, 0x1D35F }, |
||||
+ { 0x1D372, 0x1D3FF }, |
||||
+ { 0x1D455, 0x1D455 }, |
||||
+ { 0x1D49D, 0x1D49D }, |
||||
+ { 0x1D4A0, 0x1D4A1 }, |
||||
+ { 0x1D4A3, 0x1D4A4 }, |
||||
+ { 0x1D4A7, 0x1D4A8 }, |
||||
+ { 0x1D4AD, 0x1D4AD }, |
||||
+ { 0x1D4BA, 0x1D4BA }, |
||||
+ { 0x1D4BC, 0x1D4BC }, |
||||
+ { 0x1D4C4, 0x1D4C4 }, |
||||
+ { 0x1D506, 0x1D506 }, |
||||
+ { 0x1D50B, 0x1D50C }, |
||||
+ { 0x1D515, 0x1D515 }, |
||||
+ { 0x1D51D, 0x1D51D }, |
||||
+ { 0x1D53A, 0x1D53A }, |
||||
+ { 0x1D53F, 0x1D53F }, |
||||
+ { 0x1D545, 0x1D545 }, |
||||
+ { 0x1D547, 0x1D549 }, |
||||
+ { 0x1D551, 0x1D551 }, |
||||
+ { 0x1D6A6, 0x1D6A7 }, |
||||
+ { 0x1D7CC, 0x1D7CD }, |
||||
+ { 0x1D800, 0x1EDFF }, |
||||
+ { 0x1EE04, 0x1EE04 }, |
||||
+ { 0x1EE20, 0x1EE20 }, |
||||
+ { 0x1EE23, 0x1EE23 }, |
||||
+ { 0x1EE25, 0x1EE26 }, |
||||
+ { 0x1EE28, 0x1EE28 }, |
||||
+ { 0x1EE33, 0x1EE33 }, |
||||
+ { 0x1EE38, 0x1EE38 }, |
||||
+ { 0x1EE3A, 0x1EE3A }, |
||||
+ { 0x1EE3C, 0x1EE41 }, |
||||
+ { 0x1EE43, 0x1EE46 }, |
||||
+ { 0x1EE48, 0x1EE48 }, |
||||
+ { 0x1EE4A, 0x1EE4A }, |
||||
+ { 0x1EE4C, 0x1EE4C }, |
||||
+ { 0x1EE50, 0x1EE50 }, |
||||
+ { 0x1EE53, 0x1EE53 }, |
||||
+ { 0x1EE55, 0x1EE56 }, |
||||
+ { 0x1EE58, 0x1EE58 }, |
||||
+ { 0x1EE5A, 0x1EE5A }, |
||||
+ { 0x1EE5C, 0x1EE5C }, |
||||
+ { 0x1EE5E, 0x1EE5E }, |
||||
+ { 0x1EE60, 0x1EE60 }, |
||||
+ { 0x1EE63, 0x1EE63 }, |
||||
+ { 0x1EE65, 0x1EE66 }, |
||||
+ { 0x1EE6B, 0x1EE6B }, |
||||
+ { 0x1EE73, 0x1EE73 }, |
||||
+ { 0x1EE78, 0x1EE78 }, |
||||
+ { 0x1EE7D, 0x1EE7D }, |
||||
+ { 0x1EE7F, 0x1EE7F }, |
||||
+ { 0x1EE8A, 0x1EE8A }, |
||||
+ { 0x1EE9C, 0x1EEA0 }, |
||||
+ { 0x1EEA4, 0x1EEA4 }, |
||||
+ { 0x1EEAA, 0x1EEAA }, |
||||
+ { 0x1EEBC, 0x1EEEF }, |
||||
+ { 0x1EEF2, 0x1EFFF }, |
||||
+ { 0x1F02C, 0x1F02F }, |
||||
+ { 0x1F094, 0x1F09F }, |
||||
+ { 0x1F0AF, 0x1F0B0 }, |
||||
+ { 0x1F0BF, 0x1F0C0 }, |
||||
+ { 0x1F0D0, 0x1F0D0 }, |
||||
+ { 0x1F0E0, 0x1F0FF }, |
||||
+ { 0x1F10B, 0x1F10F }, |
||||
+ { 0x1F12F, 0x1F12F }, |
||||
+ { 0x1F16C, 0x1F16F }, |
||||
+ { 0x1F19B, 0x1F1E5 }, |
||||
+ { 0x1F203, 0x1F20F }, |
||||
+ { 0x1F23B, 0x1F23F }, |
||||
+ { 0x1F249, 0x1F24F }, |
||||
+ { 0x1F252, 0x1F2FF }, |
||||
+ { 0x1F321, 0x1F32F }, |
||||
+ { 0x1F336, 0x1F336 }, |
||||
+ { 0x1F37D, 0x1F37F }, |
||||
+ { 0x1F394, 0x1F39F }, |
||||
+ { 0x1F3C5, 0x1F3C5 }, |
||||
+ { 0x1F3CB, 0x1F3DF }, |
||||
+ { 0x1F3F1, 0x1F3FF }, |
||||
+ { 0x1F43F, 0x1F43F }, |
||||
+ { 0x1F441, 0x1F441 }, |
||||
+ { 0x1F4F8, 0x1F4F8 }, |
||||
+ { 0x1F4FD, 0x1F4FF }, |
||||
+ { 0x1F53E, 0x1F53F }, |
||||
+ { 0x1F544, 0x1F54F }, |
||||
+ { 0x1F568, 0x1F5FA }, |
||||
+ { 0x1F641, 0x1F644 }, |
||||
+ { 0x1F650, 0x1F67F }, |
||||
+ { 0x1F6C6, 0x1F6FF }, |
||||
+ { 0x1F774, 0x1FFFD }, |
||||
+ { 0x2A6D7, 0x2A6FF }, |
||||
+ { 0x2A701, 0x2B733 }, |
||||
+ { 0x2B735, 0x2B73F }, |
||||
+ { 0x2B741, 0x2B81C }, |
||||
+ { 0x2B81E, 0x2F7FF }, |
||||
+ { 0x2FA1E, 0x2FFFD }, |
||||
+ { 0x30000, 0x3FFFD }, |
||||
+ { 0x40000, 0x4FFFD }, |
||||
+ { 0x50000, 0x5FFFD }, |
||||
+ { 0x60000, 0x6FFFD }, |
||||
+ { 0x70000, 0x7FFFD }, |
||||
+ { 0x80000, 0x8FFFD }, |
||||
+ { 0x90000, 0x9FFFD }, |
||||
+ { 0xA0000, 0xAFFFD }, |
||||
+ { 0xB0000, 0xBFFFD }, |
||||
+ { 0xC0000, 0xCFFFD }, |
||||
+ { 0xD0000, 0xDFFFD }, |
||||
+ { 0xE0000, 0xE0000 }, |
||||
+ { 0xE0002, 0xE001F }, |
||||
+ { 0xE0080, 0xE00FF }, |
||||
+ { 0xE01F0, 0xEFFFD }, |
||||
+}; |
||||
+ |
||||
+/* RFC3454 Table B.1 */ |
||||
+static const struct u32_range map_to_nothing[] = { |
||||
+ { 0x00AD, 0x00AD }, |
||||
+ { 0x034F, 0x034F }, |
||||
+ { 0x1806, 0x1806 }, |
||||
+ { 0x180B, 0x180D }, |
||||
+ { 0x200B, 0x200D }, |
||||
+ { 0x2060, 0x2060 }, |
||||
+ { 0xFE00, 0xFE0F }, |
||||
+ { 0xFEFF, 0xFEFF }, |
||||
+}; |
||||
+ |
||||
+/* Local: allow tab, CR and LF */ |
||||
+static const struct u32_range whitelist[] = { |
||||
+ { 0x09, 0x09 }, |
||||
+ { 0x0a, 0x0a }, |
||||
+ { 0x0d, 0x0d }, |
||||
+}; |
||||
+ |
||||
+/* RFC3454 Tables in appendix C */ |
||||
+static const struct u32_range prohibited[] = { |
||||
+ /* C.2.1 ASCII control characters */ |
||||
+ { 0x0000, 0x001F }, |
||||
+ { 0x007F, 0x007F }, |
||||
+ /* C.2.2 Non-ASCII control characters */ |
||||
+ { 0x0080, 0x009F }, |
||||
+ { 0x06DD, 0x06DD }, |
||||
+ { 0x070F, 0x070F }, |
||||
+ { 0x180E, 0x180E }, |
||||
+ { 0x200C, 0x200C }, |
||||
+ { 0x200D, 0x200D }, |
||||
+ { 0x2028, 0x2028 }, |
||||
+ { 0x2029, 0x2029 }, |
||||
+ { 0x2060, 0x2060 }, |
||||
+ { 0x2061, 0x2061 }, |
||||
+ { 0x2062, 0x2062 }, |
||||
+ { 0x2063, 0x2063 }, |
||||
+ { 0x206A, 0x206F }, |
||||
+ { 0xFEFF, 0xFEFF }, |
||||
+ { 0xFFF9, 0xFFFC }, |
||||
+ { 0x1D173, 0x1D17A }, |
||||
+ /* C.3 Private use */ |
||||
+ { 0xE000, 0xF8FF }, |
||||
+ { 0xF0000, 0xFFFFD }, |
||||
+ { 0x100000, 0x10FFFD }, |
||||
+ /* C.4 Non-character code points */ |
||||
+ { 0xFDD0, 0xFDEF }, |
||||
+ { 0xFFFE, 0xFFFF }, |
||||
+ { 0x1FFFE, 0x1FFFF }, |
||||
+ { 0x2FFFE, 0x2FFFF }, |
||||
+ { 0x3FFFE, 0x3FFFF }, |
||||
+ { 0x4FFFE, 0x4FFFF }, |
||||
+ { 0x5FFFE, 0x5FFFF }, |
||||
+ { 0x6FFFE, 0x6FFFF }, |
||||
+ { 0x7FFFE, 0x7FFFF }, |
||||
+ { 0x8FFFE, 0x8FFFF }, |
||||
+ { 0x9FFFE, 0x9FFFF }, |
||||
+ { 0xAFFFE, 0xAFFFF }, |
||||
+ { 0xBFFFE, 0xBFFFF }, |
||||
+ { 0xCFFFE, 0xCFFFF }, |
||||
+ { 0xDFFFE, 0xDFFFF }, |
||||
+ { 0xEFFFE, 0xEFFFF }, |
||||
+ { 0xFFFFE, 0xFFFFF }, |
||||
+ { 0x10FFFE, 0x10FFFF }, |
||||
+ /* C.5 Surrogate codes */ |
||||
+ { 0xD800, 0xDFFF }, |
||||
+ /* C.6 Inappropriate for plain text */ |
||||
+ { 0xFFF9, 0xFFF9 }, |
||||
+ { 0xFFFA, 0xFFFA }, |
||||
+ { 0xFFFB, 0xFFFB }, |
||||
+ { 0xFFFC, 0xFFFC }, |
||||
+ { 0xFFFD, 0xFFFD }, |
||||
+ /* C.7 Inappropriate for canonical representation */ |
||||
+ { 0x2FF0, 0x2FFB }, |
||||
+ /* C.8 Change display properties or are deprecated */ |
||||
+ { 0x0340, 0x0340 }, |
||||
+ { 0x0341, 0x0341 }, |
||||
+ { 0x200E, 0x200E }, |
||||
+ { 0x200F, 0x200F }, |
||||
+ { 0x202A, 0x202A }, |
||||
+ { 0x202B, 0x202B }, |
||||
+ { 0x202C, 0x202C }, |
||||
+ { 0x202D, 0x202D }, |
||||
+ { 0x202E, 0x202E }, |
||||
+ { 0x206A, 0x206A }, |
||||
+ { 0x206B, 0x206B }, |
||||
+ { 0x206C, 0x206C }, |
||||
+ { 0x206D, 0x206D }, |
||||
+ { 0x206E, 0x206E }, |
||||
+ { 0x206F, 0x206F }, |
||||
+ /* C.9 Tagging characters */ |
||||
+ { 0xE0001, 0xE0001 }, |
||||
+ { 0xE0020, 0xE007F }, |
||||
+}; |
||||
+ |
||||
diff --git a/utf8_stringprep.c b/utf8_stringprep.c |
||||
new file mode 100644 |
||||
index 0000000..bcafae7 |
||||
--- /dev/null |
||||
+++ b/utf8_stringprep.c |
||||
@@ -0,0 +1,229 @@ |
||||
+/* |
||||
+ * Copyright (c) 2013 Damien Miller <djm@mindrot.org> |
||||
+ * |
||||
+ * Permission to use, copy, modify, and distribute this software for any |
||||
+ * purpose with or without fee is hereby granted, provided that the above |
||||
+ * copyright notice and this permission notice appear in all copies. |
||||
+ * |
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
+ */ |
||||
+ |
||||
+/* |
||||
+ * This is a simple RFC3454 stringprep profile to sanitise UTF-8 strings |
||||
+ * from untrusted sources. |
||||
+ * |
||||
+ * It is intended to be used prior to display of untrusted strings only. |
||||
+ * It should not be used for logging because of bi-di ambiguity. It |
||||
+ * should also not be used in any case where lack of normalisation may |
||||
+ * cause problems. |
||||
+ * |
||||
+ * This profile uses the prohibition and mapping tables from RFC3454 |
||||
+ * (listed below) but the unassigned character table has been updated to |
||||
+ * Unicode 6.2. It uses a local whitelist of whitespace characters (\n, |
||||
+ * \a and \t). Unicode normalisation and bi-di testing are not used. |
||||
+ * |
||||
+ * XXX: implement bi-di handling (needed for logs) |
||||
+ * XXX: implement KC normalisation (needed for passing to libs/syscalls) |
||||
+ */ |
||||
+ |
||||
+#include <sys/types.h> |
||||
+#include <stdio.h> |
||||
+#include <stdlib.h> |
||||
+#include <string.h> |
||||
+#include <limits.h> |
||||
+#include <ctype.h> |
||||
+ |
||||
+#include "misc.h" |
||||
+ |
||||
+struct u32_range { |
||||
+ u_int32_t lo, hi; /* Inclusive */ |
||||
+}; |
||||
+ |
||||
+#include "stringprep-tables.c" |
||||
+ |
||||
+/* Returns 1 if code 'c' appears in the table or 0 otherwise */ |
||||
+static int |
||||
+code_in_table(u_int32_t c, const struct u32_range *table, size_t tlen) |
||||
+{ |
||||
+ const struct u32_range *e, *end = (void *)(tlen + (char *)table); |
||||
+ |
||||
+ for (e = table; e < end; e++) { |
||||
+ if (c >= e->lo && c <= e->hi) |
||||
+ return 1; |
||||
+ } |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+/* |
||||
+ * Decode the next valid UCS character from a UTF-8 string, skipping past bad |
||||
+ * codes. Returns the decoded character or 0 for end-of-string and updates |
||||
+ * nextc to point to the start of the next character (if any). |
||||
+ * had_error is set if an invalid code was encountered. |
||||
+ */ |
||||
+static u_int32_t |
||||
+decode_utf8(const char *in, const char **nextc, int *had_error) |
||||
+{ |
||||
+ int state = 0; |
||||
+ size_t i; |
||||
+ u_int32_t c, e; |
||||
+ |
||||
+ e = c = 0; |
||||
+ for (i = 0; in[i] != '\0'; i++) { |
||||
+ e = (u_char)in[i]; |
||||
+ /* Invalid code point state */ |
||||
+ if (state == -1) { |
||||
+ /* |
||||
+ * Continue eating continuation characters until |
||||
+ * a new start character comes along. |
||||
+ */ |
||||
+ if ((e & 0xc0) == 0x80) |
||||
+ continue; |
||||
+ state = 0; |
||||
+ } |
||||
+ |
||||
+ /* New code point state */ |
||||
+ if (state == 0) { |
||||
+ if ((e & 0x80) == 0) { /* 7 bit code */ |
||||
+ c = e & 0x7f; |
||||
+ goto have_code; |
||||
+ } else if ((e & 0xe0) == 0xc0) { /* 11 bit code point */ |
||||
+ state = 1; |
||||
+ c = (e & 0x1f) << 6; |
||||
+ } else if ((e & 0xf0) == 0xe0) { /* 16 bit code point */ |
||||
+ state = 2; |
||||
+ c = (e & 0xf) << 12; |
||||
+ } else if ((e & 0xf8) == 0xf0) { /* 21 bit code point */ |
||||
+ state = 3; |
||||
+ c = (e & 0x7) << 18; |
||||
+ } else { |
||||
+ /* A five or six byte header, or 0xff */ |
||||
+ goto bad_encoding; |
||||
+ } |
||||
+ /* |
||||
+ * Check that the header byte has some non-zero data |
||||
+ * after masking off the length marker. If not it is |
||||
+ * an invalid encoding. |
||||
+ */ |
||||
+ if (c == 0) { |
||||
+ bad_encoding: |
||||
+ c = 0; |
||||
+ state = -1; |
||||
+ if (had_error != NULL) |
||||
+ *had_error = 1; |
||||
+ } |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
+ /* Sanity check: should never happen */ |
||||
+ if (state < 1 || state > 5) { |
||||
+ *nextc = NULL; |
||||
+ if (had_error != NULL) |
||||
+ *had_error = 1; |
||||
+ return 0; |
||||
+ } |
||||
+ /* Multibyte code point state */ |
||||
+ state--; |
||||
+ c |= (e & 0x3f) << (state * 6); |
||||
+ if (state > 0) |
||||
+ continue; |
||||
+ |
||||
+ /* RFC3629 bans codepoints > U+10FFFF */ |
||||
+ if (c > 0x10FFFF) { |
||||
+ if (had_error != NULL) |
||||
+ *had_error = 1; |
||||
+ continue; |
||||
+ } |
||||
+ have_code: |
||||
+ *nextc = in + i + 1; |
||||
+ return c; |
||||
+ } |
||||
+ if (state != 0 && had_error != NULL) |
||||
+ *had_error = 1; |
||||
+ *nextc = in + i; |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+/* |
||||
+ * Attempt to encode a UCS character as a UTF-8 sequence. Returns the number |
||||
+ * of characters used or -1 on error (insufficient space or bad code). |
||||
+ */ |
||||
+static int |
||||
+encode_utf8(u_int32_t c, char *s, size_t slen) |
||||
+{ |
||||
+ size_t i, need; |
||||
+ u_char h; |
||||
+ |
||||
+ if (c < 0x80) { |
||||
+ if (slen >= 1) { |
||||
+ s[0] = (char)c; |
||||
+ } |
||||
+ return 1; |
||||
+ } else if (c < 0x800) { |
||||
+ need = 2; |
||||
+ h = 0xc0; |
||||
+ } else if (c < 0x10000) { |
||||
+ need = 3; |
||||
+ h = 0xe0; |
||||
+ } else if (c < 0x200000) { |
||||
+ need = 4; |
||||
+ h = 0xf0; |
||||
+ } else { |
||||
+ /* Invalid code point > U+10FFFF */ |
||||
+ return -1; |
||||
+ } |
||||
+ if (need > slen) |
||||
+ return -1; |
||||
+ for (i = 0; i < need; i++) { |
||||
+ s[i] = (i == 0 ? h : 0x80); |
||||
+ s[i] |= (c >> (need - i - 1) * 6) & 0x3f; |
||||
+ } |
||||
+ return need; |
||||
+} |
||||
+ |
||||
+ |
||||
+/* |
||||
+ * Normalise a UTF-8 string using the RFC3454 stringprep algorithm. |
||||
+ * Returns 0 on success or -1 on failure (prohibited code or insufficient |
||||
+ * length in the output string. |
||||
+ * Requires an output buffer at most the same length as the input. |
||||
+ */ |
||||
+int |
||||
+utf8_stringprep(const char *in, char *out, size_t olen) |
||||
+{ |
||||
+ int r; |
||||
+ size_t o; |
||||
+ u_int32_t c; |
||||
+ |
||||
+ if (olen < 1) |
||||
+ return -1; |
||||
+ |
||||
+ for (o = 0; (c = decode_utf8(in, &in, NULL)) != 0;) { |
||||
+ /* Mapping */ |
||||
+ if (code_in_table(c, map_to_nothing, sizeof(map_to_nothing))) |
||||
+ continue; |
||||
+ |
||||
+ /* Prohibitied output */ |
||||
+ if (code_in_table(c, prohibited, sizeof(prohibited)) && |
||||
+ !code_in_table(c, whitelist, sizeof(whitelist))) |
||||
+ return -1; |
||||
+ |
||||
+ /* Map unassigned code points to U+FFFD */ |
||||
+ if (code_in_table(c, unassigned, sizeof(unassigned))) |
||||
+ c = 0xFFFD; |
||||
+ |
||||
+ /* Encode the character */ |
||||
+ r = encode_utf8(c, out + o, olen - o - 1); |
||||
+ if (r < 0) |
||||
+ return -1; |
||||
+ o += r; |
||||
+ } |
||||
+ out[o] = '\0'; |
||||
+ return 0; |
||||
+} |
||||
+ |
@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
|
||||
diff --git a/ChangeLog b/ChangeLog |
||||
index 38de846..1603a07 100644 |
||||
--- a/ChangeLog |
||||
+++ b/ChangeLog |
||||
@@ -1,3 +1,14 @@ |
||||
+20140420 |
||||
+ - djm@cvs.openbsd.org 2014/04/01 03:34:10 |
||||
+ [sshconnect.c] |
||||
+ When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any |
||||
+ certificate keys to plain keys and attempt SSHFP resolution. |
||||
+ |
||||
+ Prevents a server from skipping SSHFP lookup and forcing a new-hostkey |
||||
+ dialog by offering only certificate keys. |
||||
+ |
||||
+ Reported by mcv21 AT cam.ac.uk |
||||
+ |
||||
20140313 |
||||
- (djm) Release OpenSSH 6.6 |
||||
|
||||
diff --git a/sshconnect.c b/sshconnect.c |
||||
index 394cca8..e636f33 100644 |
||||
--- a/sshconnect.c |
||||
+++ b/sshconnect.c |
||||
@@ -1219,30 +1219,40 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) |
||||
{ |
||||
int flags = 0; |
||||
char *fp; |
||||
+ Key *plain = NULL; |
||||
|
||||
fp = key_selected_fingerprint(host_key, SSH_FP_HEX); |
||||
debug("Server host key: %s %s%s", key_type(host_key), |
||||
key_fingerprint_prefix(), 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) { |
||||
- |
||||
- if (options.verify_host_key_dns == 1 && |
||||
- flags & DNS_VERIFY_MATCH && |
||||
- flags & DNS_VERIFY_SECURE) |
||||
- return 0; |
||||
- |
||||
- if (flags & DNS_VERIFY_MATCH) { |
||||
- matching_host_key_dns = 1; |
||||
- } else { |
||||
- warn_changed_key(host_key); |
||||
- error("Update the SSHFP RR in DNS with the new " |
||||
- "host key to get rid of this message."); |
||||
+ if (options.verify_host_key_dns) { |
||||
+ /* |
||||
+ * XXX certs are not yet supported for DNS, so downgrade |
||||
+ * them and try the plain key. |
||||
+ */ |
||||
+ plain = key_from_private(host_key); |
||||
+ if (key_is_cert(plain)) |
||||
+ key_drop_cert(plain); |
||||
+ if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { |
||||
+ if (flags & DNS_VERIFY_FOUND) { |
||||
+ if (options.verify_host_key_dns == 1 && |
||||
+ flags & DNS_VERIFY_MATCH && |
||||
+ flags & DNS_VERIFY_SECURE) { |
||||
+ key_free(plain); |
||||
+ return 0; |
||||
+ } |
||||
+ if (flags & DNS_VERIFY_MATCH) { |
||||
+ matching_host_key_dns = 1; |
||||
+ } else { |
||||
+ warn_changed_key(plain); |
||||
+ error("Update the SSHFP RR in DNS " |
||||
+ "with the new host key to get rid " |
||||
+ "of this message."); |
||||
+ } |
||||
} |
||||
} |
||||
+ key_free(plain); |
||||
} |
||||
|
||||
return check_host_key(host, hostaddr, options.port, host_key, RDRW, |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
diff --git a/session.c b/session.c |
||||
index 9a75c62..4859245 100644 |
||||
--- a/session.c |
||||
+++ b/session.c |
||||
@@ -46,6 +46,7 @@ |
||||
|
||||
#include <arpa/inet.h> |
||||
|
||||
+#include <ctype.h> |
||||
#include <errno.h> |
||||
#include <fcntl.h> |
||||
#include <grp.h> |
||||
@@ -292,6 +293,21 @@ do_authenticated(Authctxt *authctxt) |
||||
do_cleanup(authctxt); |
||||
} |
||||
|
||||
+/* Check untrusted xauth strings for metacharacters */ |
||||
+static int |
||||
+xauth_valid_string(const char *s) |
||||
+{ |
||||
+ size_t i; |
||||
+ |
||||
+ for (i = 0; s[i] != '\0'; i++) { |
||||
+ if (!isalnum((u_char)s[i]) && |
||||
+ s[i] != '.' && s[i] != ':' && s[i] != '/' && |
||||
+ s[i] != '-' && s[i] != '_') |
||||
+ return 0; |
||||
+ } |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
/* |
||||
* Prepares for an interactive session. This is called after the user has |
||||
* been successfully authenticated. During this message exchange, pseudo |
||||
@@ -365,7 +381,13 @@ do_authenticated1(Authctxt *authctxt) |
||||
s->screen = 0; |
||||
} |
||||
packet_check_eom(); |
||||
- success = session_setup_x11fwd(s); |
||||
+ if (xauth_valid_string(s->auth_proto) && |
||||
+ xauth_valid_string(s->auth_data)) |
||||
+ success = session_setup_x11fwd(s); |
||||
+ else { |
||||
+ success = 0; |
||||
+ error("Invalid X11 forwarding data"); |
||||
+ } |
||||
if (!success) { |
||||
free(s->auth_proto); |
||||
free(s->auth_data); |
||||
@@ -2219,7 +2241,13 @@ session_x11_req(Session *s) |
||||
s->screen = packet_get_int(); |
||||
packet_check_eom(); |
||||
|
||||
- success = session_setup_x11fwd(s); |
||||
+ if (xauth_valid_string(s->auth_proto) && |
||||
+ xauth_valid_string(s->auth_data)) |
||||
+ success = session_setup_x11fwd(s); |
||||
+ else { |
||||
+ success = 0; |
||||
+ error("Invalid X11 forwarding data"); |
||||
+ } |
||||
if (!success) { |
||||
free(s->auth_proto); |
||||
free(s->auth_data); |
@ -0,0 +1,131 @@
@@ -0,0 +1,131 @@
|
||||
diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-serv-krb5.c |
||||
--- openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users 2017-02-09 10:10:47.403859893 +0100 |
||||
+++ openssh-7.4p1/gss-serv-krb5.c 2017-02-09 10:10:47.414859882 +0100 |
||||
@@ -260,7 +260,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri |
||||
FILE *fp; |
||||
char file[MAXPATHLEN]; |
||||
char line[BUFSIZ]; |
||||
- char kuser[65]; /* match krb5_kuserok() */ |
||||
struct stat st; |
||||
struct passwd *pw = the_authctxt->pw; |
||||
int found_principal = 0; |
||||
@@ -269,7 +268,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri |
||||
|
||||
snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); |
||||
/* If both .k5login and .k5users DNE, self-login is ok. */ |
||||
- if (!k5login_exists && (access(file, F_OK) == -1)) { |
||||
+ if ( !options.enable_k5users || (!k5login_exists && (access(file, F_OK) == -1))) { |
||||
return ssh_krb5_kuserok(krb_context, principal, luser, |
||||
k5login_exists); |
||||
} |
||||
diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.GSSAPIEnablek5users 2017-02-09 10:10:47.404859892 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-09 10:18:45.800385543 +0100 |
||||
@@ -166,6 +166,7 @@ initialize_server_options(ServerOptions |
||||
options->ip_qos_bulk = -1; |
||||
options->version_addendum = NULL; |
||||
options->use_kuserok = -1; |
||||
+ options->enable_k5users = -1; |
||||
options->fingerprint_hash = -1; |
||||
options->disable_forwarding = -1; |
||||
} |
||||
@@ -337,6 +338,8 @@ fill_default_server_options(ServerOption |
||||
options->show_patchlevel = 0; |
||||
if (options->use_kuserok == -1) |
||||
options->use_kuserok = 1; |
||||
+ if (options->enable_k5users == -1) |
||||
+ options->enable_k5users = 0; |
||||
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) |
||||
options->fwd_opts.streamlocal_bind_mask = 0177; |
||||
if (options->fwd_opts.streamlocal_bind_unlink == -1) |
||||
@@ -418,7 +421,7 @@ typedef enum { |
||||
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, |
||||
sHostKeyAlgorithms, |
||||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |
||||
- sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, |
||||
+ sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, |
||||
sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, |
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
||||
sUsePrivilegeSeparation, sAllowAgentForwarding, |
||||
@@ -497,12 +500,14 @@ static struct { |
||||
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, |
||||
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, |
||||
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, |
||||
+ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, |
||||
#else |
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL }, |
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, |
||||
+ { "gssapienablek5users", sUnsupported, SSHCFG_ALL }, |
||||
#endif |
||||
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, |
||||
@@ -1653,6 +1658,10 @@ process_server_config_line(ServerOptions |
||||
intptr = &options->use_kuserok; |
||||
goto parse_flag; |
||||
|
||||
+ case sGssEnablek5users: |
||||
+ intptr = &options->enable_k5users; |
||||
+ goto parse_flag; |
||||
+ |
||||
case sPermitOpen: |
||||
arg = strdelim(&cp); |
||||
if (!arg || *arg == '\0') |
||||
@@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d |
||||
M_CP_INTOPT(ip_qos_interactive); |
||||
M_CP_INTOPT(ip_qos_bulk); |
||||
M_CP_INTOPT(use_kuserok); |
||||
+ M_CP_INTOPT(enable_k5users); |
||||
M_CP_INTOPT(rekey_limit); |
||||
M_CP_INTOPT(rekey_interval); |
||||
|
||||
@@ -2319,6 +2329,7 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); |
||||
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); |
||||
dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); |
||||
+ dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); |
||||
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); |
||||
|
||||
/* string arguments */ |
||||
diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h |
||||
--- openssh-7.4p1/servconf.h.GSSAPIEnablek5users 2017-02-09 10:10:47.404859892 +0100 |
||||
+++ openssh-7.4p1/servconf.h 2017-02-09 10:10:47.415859881 +0100 |
||||
@@ -174,7 +174,8 @@ typedef struct { |
||||
|
||||
int num_permitted_opens; |
||||
|
||||
- int use_kuserok; |
||||
+ int use_kuserok; |
||||
+ int enable_k5users; |
||||
char *chroot_directory; |
||||
char *revoked_keys_file; |
||||
char *trusted_user_ca_keys; |
||||
diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users 2017-02-09 10:10:47.415859881 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2017-02-09 10:19:29.420336796 +0100 |
||||
@@ -633,6 +633,12 @@ Specifies whether key exchange based on |
||||
doesn't rely on ssh keys to verify host identity. |
||||
The default is |
||||
.Dq no . |
||||
+.It Cm GSSAPIEnablek5users |
||||
+Specifies whether to look at .k5users file for GSSAPI authentication |
||||
+access control. Further details are described in |
||||
+.Xr ksu 1 . |
||||
+The default is |
||||
+.Cm no . |
||||
.It Cm GSSAPIStrictAcceptorCheck |
||||
Determines whether to be strict about the identity of the GSSAPI acceptor |
||||
a client authenticates against. |
||||
diff -up openssh-7.4p1/sshd_config.GSSAPIEnablek5users openssh-7.4p1/sshd_config |
||||
--- openssh-7.4p1/sshd_config.GSSAPIEnablek5users 2017-02-09 10:10:47.404859892 +0100 |
||||
+++ openssh-7.4p1/sshd_config 2017-02-09 10:10:47.415859881 +0100 |
||||
@@ -80,6 +80,7 @@ GSSAPIAuthentication yes |
||||
GSSAPICleanupCredentials no |
||||
#GSSAPIStrictAcceptorCheck yes |
||||
#GSSAPIKeyExchange no |
||||
+#GSSAPIEnablek5users no |
||||
|
||||
# Set this to 'yes' to enable PAM authentication, account processing, |
||||
# and session processing. If this is enabled, PAM authentication will |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
diff -up openssh/sshd.c.ip-opts openssh/sshd.c |
||||
--- openssh/sshd.c.ip-opts 2016-07-25 13:58:48.998507834 +0200 |
||||
+++ openssh/sshd.c 2016-07-25 14:01:28.346469878 +0200 |
||||
@@ -1507,12 +1507,29 @@ check_ip_options(struct ssh *ssh) |
||||
|
||||
if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, |
||||
&option_size) >= 0 && option_size != 0) { |
||||
- text[0] = '\0'; |
||||
- for (i = 0; i < option_size; i++) |
||||
- snprintf(text + i*3, sizeof(text) - i*3, |
||||
- " %2.2x", opts[i]); |
||||
- fatal("Connection from %.100s port %d with IP opts: %.800s", |
||||
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); |
||||
+ i = 0; |
||||
+ do { |
||||
+ switch (opts[i]) { |
||||
+ case 0: |
||||
+ case 1: |
||||
+ ++i; |
||||
+ break; |
||||
+ case 130: |
||||
+ case 133: |
||||
+ case 134: |
||||
+ i += opts[i + 1]; |
||||
+ break; |
||||
+ default: |
||||
+ /* Fail, fatally, if we detect either loose or strict |
||||
+ * source routing options. */ |
||||
+ text[0] = '\0'; |
||||
+ for (i = 0; i < option_size; i++) |
||||
+ snprintf(text + i*3, sizeof(text) - i*3, |
||||
+ " %2.2x", opts[i]); |
||||
+ fatal("Connection from %.100s port %d with IP options:%.800s", |
||||
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); |
||||
+ } |
||||
+ } while (i < option_size); |
||||
} |
||||
return; |
||||
#endif /* IP_OPTIONS */ |
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
diff --git a/sshd_config.5 b/sshd_config.5 |
||||
index 2320128..6244e68 100644 |
||||
--- a/sshd_config.5 |
||||
+++ b/sshd_config.5 |
||||
@@ -120,6 +120,8 @@ The allow/deny directives are processed in the following order: |
||||
.Cm DenyGroups , |
||||
and finally |
||||
.Cm AllowGroups . |
||||
+All of the specified user and group tests must succeed, before user |
||||
+is allowed to log in. |
||||
.Pp |
||||
See PATTERNS in |
||||
.Xr ssh_config 5 |
||||
@@ -160,6 +162,8 @@ The allow/deny directives are processed in the following order: |
||||
.Cm DenyGroups , |
||||
and finally |
||||
.Cm AllowGroups . |
||||
+All of the specified user and group tests must succeed, before user |
||||
+is allowed to log in. |
||||
.Pp |
||||
See PATTERNS in |
||||
.Xr ssh_config 5 |
||||
@@ -430,6 +434,8 @@ The allow/deny directives are processed in the following order: |
||||
.Cm DenyGroups , |
||||
and finally |
||||
.Cm AllowGroups . |
||||
+All of the specified user and group tests must succeed, before user |
||||
+is allowed to log in. |
||||
.Pp |
||||
See PATTERNS in |
||||
.Xr ssh_config 5 |
||||
@@ -449,6 +455,8 @@ The allow/deny directives are processed in the following order: |
||||
.Cm DenyGroups , |
||||
and finally |
||||
.Cm AllowGroups . |
||||
+All of the specified user and group tests must succeed, before user |
||||
+is allowed to log in. |
||||
.Pp |
||||
See PATTERNS in |
||||
.Xr ssh_config 5 |
@ -0,0 +1,183 @@
@@ -0,0 +1,183 @@
|
||||
diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c |
||||
--- openssh-7.4p1/monitor_wrap.c.audit-race 2017-02-09 14:07:56.870994116 +0100 |
||||
+++ openssh-7.4p1/monitor_wrap.c 2017-02-09 14:07:56.874994112 +0100 |
||||
@@ -1107,4 +1107,48 @@ mm_audit_destroy_sensitive_data(const ch |
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); |
||||
buffer_free(&m); |
||||
} |
||||
+ |
||||
+int mm_forward_audit_messages(int fdin) |
||||
+{ |
||||
+ u_char buf[4]; |
||||
+ u_int blen, msg_len; |
||||
+ Buffer m; |
||||
+ int ret = 0; |
||||
+ |
||||
+ debug3("%s: entering", __func__); |
||||
+ buffer_init(&m); |
||||
+ do { |
||||
+ blen = atomicio(read, fdin, buf, sizeof(buf)); |
||||
+ if (blen == 0) /* closed pipe */ |
||||
+ break; |
||||
+ if (blen != sizeof(buf)) { |
||||
+ error("%s: Failed to read the buffer from child", __func__); |
||||
+ ret = -1; |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ msg_len = get_u32(buf); |
||||
+ if (msg_len > 256 * 1024) |
||||
+ fatal("%s: read: bad msg_len %d", __func__, msg_len); |
||||
+ buffer_clear(&m); |
||||
+ buffer_append_space(&m, msg_len); |
||||
+ if (atomicio(read, fdin, buffer_ptr(&m), msg_len) != msg_len) { |
||||
+ error("%s: Failed to read the the buffer content from the child", __func__); |
||||
+ ret = -1; |
||||
+ break; |
||||
+ } |
||||
+ if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen || |
||||
+ atomicio(vwrite, pmonitor->m_recvfd, buffer_ptr(&m), msg_len) != msg_len) { |
||||
+ error("%s: Failed to write the message to the monitor", __func__); |
||||
+ ret = -1; |
||||
+ break; |
||||
+ } |
||||
+ } while (1); |
||||
+ buffer_free(&m); |
||||
+ return ret; |
||||
+} |
||||
+void mm_set_monitor_pipe(int fd) |
||||
+{ |
||||
+ pmonitor->m_recvfd = fd; |
||||
+} |
||||
#endif /* SSH_AUDIT_EVENTS */ |
||||
diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h |
||||
--- openssh-7.4p1/monitor_wrap.h.audit-race 2017-02-09 14:07:56.870994116 +0100 |
||||
+++ openssh-7.4p1/monitor_wrap.h 2017-02-09 14:07:56.874994112 +0100 |
||||
@@ -80,6 +80,8 @@ void mm_audit_unsupported_body(int); |
||||
void mm_audit_kex_body(int, char *, 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); |
||||
+int mm_forward_audit_messages(int); |
||||
+void mm_set_monitor_pipe(int); |
||||
#endif |
||||
|
||||
struct Session; |
||||
diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c |
||||
--- openssh-7.4p1/session.c.audit-race 2017-02-09 14:07:56.871994115 +0100 |
||||
+++ openssh-7.4p1/session.c 2017-02-09 14:09:44.710893783 +0100 |
||||
@@ -162,6 +162,10 @@ static Session *sessions = NULL; |
||||
login_cap_t *lc; |
||||
#endif |
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS |
||||
+int paudit[2]; |
||||
+#endif |
||||
+ |
||||
static int is_child = 0; |
||||
static int in_chroot = 0; |
||||
static int have_dev_log = 1; |
||||
@@ -289,6 +293,8 @@ xauth_valid_string(const char *s) |
||||
return 1; |
||||
} |
||||
|
||||
+void child_destory_sensitive_data(); |
||||
+ |
||||
#define USE_PIPES 1 |
||||
/* |
||||
* This is called to fork and execute a command when we have no tty. This |
||||
@@ -424,6 +430,8 @@ do_exec_no_pty(Session *s, const char *c |
||||
cray_init_job(s->pw); /* set up cray jid and tmpdir */ |
||||
#endif |
||||
|
||||
+ child_destory_sensitive_data(); |
||||
+ |
||||
/* Do processing for the child (exec command etc). */ |
||||
do_child(s, command); |
||||
/* NOTREACHED */ |
||||
@@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm |
||||
/* Close the extra descriptor for the pseudo tty. */ |
||||
close(ttyfd); |
||||
|
||||
+ /* Do this early, so we will not block large MOTDs */ |
||||
+ child_destory_sensitive_data(); |
||||
+ |
||||
/* record login, etc. similar to login(1) */ |
||||
#ifdef _UNICOS |
||||
cray_init_job(s->pw); /* set up cray jid and tmpdir */ |
||||
@@ -717,6 +728,8 @@ do_exec(Session *s, const char *command) |
||||
} |
||||
if (s->command != NULL && s->ptyfd == -1) |
||||
s->command_handle = PRIVSEP(audit_run_command(s->command)); |
||||
+ if (pipe(paudit) < 0) |
||||
+ fatal("pipe: %s", strerror(errno)); |
||||
#endif |
||||
if (s->ttyfd != -1) |
||||
ret = do_exec_pty(s, command); |
||||
@@ -732,6 +745,20 @@ do_exec(Session *s, const char *command) |
||||
*/ |
||||
buffer_clear(&loginmsg); |
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS |
||||
+ close(paudit[1]); |
||||
+ if (use_privsep && ret == 0) { |
||||
+ /* |
||||
+ * Read the audit messages from forked child and send them |
||||
+ * back to monitor. We don't want to communicate directly, |
||||
+ * because the messages might get mixed up. |
||||
+ * Continue after the pipe gets closed (all messages sent). |
||||
+ */ |
||||
+ ret = mm_forward_audit_messages(paudit[0]); |
||||
+ } |
||||
+ close(paudit[0]); |
||||
+#endif /* SSH_AUDIT_EVENTS */ |
||||
+ |
||||
return ret; |
||||
} |
||||
|
||||
@@ -1542,6 +1569,33 @@ child_close_fds(void) |
||||
endpwent(); |
||||
} |
||||
|
||||
+void |
||||
+child_destory_sensitive_data() |
||||
+{ |
||||
+#ifdef SSH_AUDIT_EVENTS |
||||
+ int pparent = paudit[1]; |
||||
+ close(paudit[0]); |
||||
+ /* Hack the monitor pipe to avoid race condition with parent */ |
||||
+ if (use_privsep) |
||||
+ mm_set_monitor_pipe(pparent); |
||||
+#endif |
||||
+ |
||||
+ /* remove hostkey from the child's memory */ |
||||
+ destroy_sensitive_data(use_privsep); |
||||
+ /* |
||||
+ * We can audit this, because we hacked the pipe to direct the |
||||
+ * messages over postauth child. But this message requires answer |
||||
+ * which we can't do using one-way pipe. |
||||
+ */ |
||||
+ packet_destroy_all(0, 1); |
||||
+ |
||||
+#ifdef SSH_AUDIT_EVENTS |
||||
+ /* Notify parent that we are done */ |
||||
+ close(pparent); |
||||
+#endif |
||||
+ |
||||
+} |
||||
+ |
||||
/* |
||||
* Performs common processing for the child, such as setting up the |
||||
* environment, closing extra file descriptors, setting the user and group |
||||
@@ -1558,12 +1612,6 @@ do_child(Session *s, const char *command |
||||
struct passwd *pw = s->pw; |
||||
int r = 0; |
||||
|
||||
- /* remove hostkey from the child's memory */ |
||||
- 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); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
From 5b64f85bb811246c59ebab70aed331f26ba37b18 Mon Sep 17 00:00:00 2001 |
||||
From: "djm@openbsd.org" <djm@openbsd.org> |
||||
Date: Sat, 18 Jul 2015 07:57:14 +0000 |
||||
Subject: upstream commit |
||||
|
||||
only query each keyboard-interactive device once per |
||||
authentication request regardless of how many times it is listed; ok markus@ |
||||
|
||||
Upstream-ID: d73fafba6e86030436ff673656ec1f33d9ffeda1 |
||||
--- |
||||
auth2-chall.c | 11 ++++++++--- |
||||
1 file changed, 8 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/auth2-chall.c b/auth2-chall.c |
||||
index ddabe1a..4aff09d 100644 |
||||
--- a/auth2-chall.c |
||||
+++ b/auth2-chall.c |
||||
@@ -83,6 +83,7 @@ struct KbdintAuthctxt |
||||
void *ctxt; |
||||
KbdintDevice *device; |
||||
u_int nreq; |
||||
+ u_int devices_done; |
||||
}; |
||||
|
||||
#ifdef USE_PAM |
||||
@@ -169,11 +170,15 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt) |
||||
if (len == 0) |
||||
break; |
||||
for (i = 0; devices[i]; i++) { |
||||
- if (!auth2_method_allowed(authctxt, |
||||
+ if ((kbdintctxt->devices_done & (1 << i)) != 0 || |
||||
+ !auth2_method_allowed(authctxt, |
||||
"keyboard-interactive", devices[i]->name)) |
||||
continue; |
||||
- if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) |
||||
+ if (strncmp(kbdintctxt->devices, devices[i]->name, |
||||
+ len) == 0) { |
||||
kbdintctxt->device = devices[i]; |
||||
+ kbdintctxt->devices_done |= 1 << i; |
||||
+ } |
||||
} |
||||
t = kbdintctxt->devices; |
||||
kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; |
||||
-- |
||||
cgit v0.11.2 |
||||
|
||||
|
@ -0,0 +1,253 @@
@@ -0,0 +1,253 @@
|
||||
diff --git a/Makefile.in b/Makefile.in |
||||
index 4ab6717..581b121 100644 |
||||
--- a/Makefile.in |
||||
+++ b/Makefile.in |
||||
@@ -28,6 +28,7 @@ SSH_KEYSIGN=$(libexecdir)/ssh-keysign |
||||
SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper |
||||
SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper |
||||
SSH_KEYCAT=$(libexecdir)/ssh-keycat |
||||
+CTR_CAVSTEST=$(libexecdir)/ctr-cavstest |
||||
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper |
||||
PRIVSEP_PATH=@PRIVSEP_PATH@ |
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ |
||||
@@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@ |
||||
MANFMT=@MANFMT@ |
||||
INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ |
||||
|
||||
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) |
||||
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) |
||||
|
||||
LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ |
||||
canohost.o channels.o cipher.o cipher-aes.o \ |
||||
@@ -180,6 +181,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o |
||||
ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o |
||||
$(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(SSHLIBS) |
||||
|
||||
+ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o |
||||
+ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) |
||||
+ |
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o |
||||
$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) |
||||
|
||||
@@ -288,6 +292,7 @@ install-files: |
||||
$(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ |
||||
fi |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) |
||||
+ $(INSTALL) -m 0755 $(STRIP_OPT) ctr-cavstest$(EXEEXT) $(DESTDIR)$(libexecdir)/ctr-cavstest$(EXEEXT) |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) |
||||
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 |
||||
diff --git a/ctr-cavstest.c b/ctr-cavstest.c |
||||
new file mode 100644 |
||||
index 0000000..bbcbe8a |
||||
--- /dev/null |
||||
+++ b/ctr-cavstest.c |
||||
@@ -0,0 +1,208 @@ |
||||
+/* |
||||
+ * |
||||
+ * invocation (all of the following are equal): |
||||
+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 |
||||
+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 --iv 00000000000000000000000000000000 |
||||
+ * echo -n a6deca405eef2e8e4609abf3c3ccf4a6 | ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt |
||||
+ */ |
||||
+ |
||||
+#include "includes.h" |
||||
+ |
||||
+#include <sys/types.h> |
||||
+#include <sys/param.h> |
||||
+#include <stdarg.h> |
||||
+#include <stdio.h> |
||||
+#include <stdlib.h> |
||||
+#include <string.h> |
||||
+#include <ctype.h> |
||||
+ |
||||
+#include "xmalloc.h" |
||||
+#include "log.h" |
||||
+#include "cipher.h" |
||||
+ |
||||
+/* compatibility with old or broken OpenSSL versions */ |
||||
+#include "openbsd-compat/openssl-compat.h" |
||||
+ |
||||
+void usage(void) { |
||||
+ fprintf(stderr, "Usage: ctr-cavstest --algo <ssh-crypto-algorithm>\n" |
||||
+ " --key <hexadecimal-key> --mode <encrypt|decrypt>\n" |
||||
+ " [--iv <hexadecimal-iv>] --data <hexadecimal-data>\n\n" |
||||
+ "Hexadecimal output is printed to stdout.\n" |
||||
+ "Hexadecimal input data can be alternatively read from stdin.\n"); |
||||
+ exit(1); |
||||
+} |
||||
+ |
||||
+void *fromhex(char *hex, size_t *len) |
||||
+{ |
||||
+ unsigned char *bin; |
||||
+ char *p; |
||||
+ size_t n = 0; |
||||
+ int shift = 4; |
||||
+ unsigned char out = 0; |
||||
+ unsigned char *optr; |
||||
+ |
||||
+ bin = xmalloc(strlen(hex)/2); |
||||
+ optr = bin; |
||||
+ |
||||
+ for (p = hex; *p != '\0'; ++p) { |
||||
+ unsigned char c; |
||||
+ |
||||
+ c = *p; |
||||
+ if (isspace(c)) |
||||
+ continue; |
||||
+ |
||||
+ if (c >= '0' && c <= '9') { |
||||
+ c = c - '0'; |
||||
+ } else if (c >= 'A' && c <= 'F') { |
||||
+ c = c - 'A' + 10; |
||||
+ } else if (c >= 'a' && c <= 'f') { |
||||
+ c = c - 'a' + 10; |
||||
+ } else { |
||||
+ /* truncate on nonhex cipher */ |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ out |= c << shift; |
||||
+ shift = (shift + 4) % 8; |
||||
+ |
||||
+ if (shift) { |
||||
+ *(optr++) = out; |
||||
+ out = 0; |
||||
+ ++n; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ *len = n; |
||||
+ return bin; |
||||
+} |
||||
+ |
||||
+#define READ_CHUNK 4096 |
||||
+#define MAX_READ_SIZE 1024*1024*100 |
||||
+char *read_stdin(void) |
||||
+{ |
||||
+ char *buf; |
||||
+ size_t n, total = 0; |
||||
+ |
||||
+ buf = xmalloc(READ_CHUNK); |
||||
+ |
||||
+ do { |
||||
+ n = fread(buf + total, 1, READ_CHUNK, stdin); |
||||
+ if (n < READ_CHUNK) /* terminate on short read */ |
||||
+ break; |
||||
+ |
||||
+ total += n; |
||||
+ buf = xrealloc(buf, total + READ_CHUNK, 1); |
||||
+ } while(total < MAX_READ_SIZE); |
||||
+ return buf; |
||||
+} |
||||
+ |
||||
+int main (int argc, char *argv[]) |
||||
+{ |
||||
+ |
||||
+ const Cipher *c; |
||||
+ CipherContext cc; |
||||
+ char *algo = "aes128-ctr"; |
||||
+ char *hexkey = NULL; |
||||
+ char *hexiv = "00000000000000000000000000000000"; |
||||
+ char *hexdata = NULL; |
||||
+ char *p; |
||||
+ int i; |
||||
+ int encrypt = 1; |
||||
+ void *key; |
||||
+ size_t keylen; |
||||
+ void *iv; |
||||
+ size_t ivlen; |
||||
+ void *data; |
||||
+ size_t datalen; |
||||
+ void *outdata; |
||||
+ |
||||
+ for (i = 1; i < argc; ++i) { |
||||
+ if (strcmp(argv[i], "--algo") == 0) { |
||||
+ algo = argv[++i]; |
||||
+ } else if (strcmp(argv[i], "--key") == 0) { |
||||
+ hexkey = argv[++i]; |
||||
+ } else if (strcmp(argv[i], "--mode") == 0) { |
||||
+ ++i; |
||||
+ if (argv[i] == NULL) { |
||||
+ usage(); |
||||
+ } |
||||
+ if (strncmp(argv[i], "enc", 3) == 0) { |
||||
+ encrypt = 1; |
||||
+ } else if (strncmp(argv[i], "dec", 3) == 0) { |
||||
+ encrypt = 0; |
||||
+ } else { |
||||
+ usage(); |
||||
+ } |
||||
+ } else if (strcmp(argv[i], "--iv") == 0) { |
||||
+ hexiv = argv[++i]; |
||||
+ } else if (strcmp(argv[i], "--data") == 0) { |
||||
+ hexdata = argv[++i]; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (hexkey == NULL || algo == NULL) { |
||||
+ usage(); |
||||
+ } |
||||
+ |
||||
+ SSLeay_add_all_algorithms(); |
||||
+ |
||||
+ c = cipher_by_name(algo); |
||||
+ if (c == NULL) { |
||||
+ fprintf(stderr, "Error: unknown algorithm\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ if (hexdata == NULL) { |
||||
+ hexdata = read_stdin(); |
||||
+ } else { |
||||
+ hexdata = xstrdup(hexdata); |
||||
+ } |
||||
+ |
||||
+ key = fromhex(hexkey, &keylen); |
||||
+ |
||||
+ if (keylen != 16 && keylen != 24 && keylen == 32) { |
||||
+ fprintf(stderr, "Error: unsupported key length\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ iv = fromhex(hexiv, &ivlen); |
||||
+ |
||||
+ if (ivlen != 16) { |
||||
+ fprintf(stderr, "Error: unsupported iv length\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ data = fromhex(hexdata, &datalen); |
||||
+ |
||||
+ if (data == NULL || datalen == 0) { |
||||
+ fprintf(stderr, "Error: no data to encrypt/decrypt\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ cipher_init(&cc, c, key, keylen, iv, ivlen, encrypt); |
||||
+ |
||||
+ free(key); |
||||
+ free(iv); |
||||
+ |
||||
+ outdata = malloc(datalen); |
||||
+ if(outdata == NULL) { |
||||
+ fprintf(stderr, "Error: memory allocation failure\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ cipher_crypt(&cc, 0, outdata, data, datalen, 0, 0); |
||||
+ |
||||
+ free(data); |
||||
+ |
||||
+ cipher_cleanup(&cc); |
||||
+ |
||||
+ for (p = outdata; datalen > 0; ++p, --datalen) { |
||||
+ printf("%02X", (unsigned char)*p); |
||||
+ } |
||||
+ |
||||
+ free(outdata); |
||||
+ |
||||
+ printf("\n"); |
||||
+ return 0; |
||||
+} |
||||
+ |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
diff -up openssh-6.6p1/readconf.c.roaming openssh-6.6p1/readconf.c |
||||
--- openssh-6.6p1/readconf.c.roaming 2016-01-13 15:42:00.423573980 +0100 |
||||
+++ openssh-6.6p1/readconf.c 2016-01-13 15:43:03.565529448 +0100 |
||||
@@ -1608,7 +1608,7 @@ initialize_options(Options * options) |
||||
options->tun_remote = -1; |
||||
options->local_command = NULL; |
||||
options->permit_local_command = -1; |
||||
- options->use_roaming = -1; |
||||
+ options->use_roaming = 0; |
||||
options->visual_host_key = -1; |
||||
options->ip_qos_interactive = -1; |
||||
options->ip_qos_bulk = -1; |
||||
@@ -1783,8 +1783,7 @@ fill_default_options(Options * options) |
||||
options->tun_remote = SSH_TUNID_ANY; |
||||
if (options->permit_local_command == -1) |
||||
options->permit_local_command = 0; |
||||
- if (options->use_roaming == -1) |
||||
- options->use_roaming = 1; |
||||
+ options->use_roaming = 0; |
||||
if (options->visual_host_key == -1) |
||||
options->visual_host_key = 0; |
||||
if (options->ip_qos_interactive == -1) |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
diff --git a/ssh_config.5 b/ssh_config.5 |
||||
index e7accd6..c95fda6 100644 |
||||
--- a/ssh_config.5 |
||||
+++ b/ssh_config.5 |
||||
@@ -1253,6 +1253,10 @@ should be sent to the server. |
||||
Note that environment passing is only supported for protocol 2. |
||||
The server must also support it, and the server must be configured to |
||||
accept these environment variables. |
||||
+Note that the |
||||
+.Ev TERM |
||||
+environment variable is always sent whenever a |
||||
+pseudo-terminal is requested as it is required by the protocol. |
||||
Refer to |
||||
.Cm AcceptEnv |
||||
in |
||||
diff --git a/sshd_config.5 b/sshd_config.5 |
||||
index aa9525d..2320128 100644 |
||||
--- a/sshd_config.5 |
||||
+++ b/sshd_config.5 |
||||
@@ -70,7 +70,11 @@ See |
||||
in |
||||
.Xr ssh_config 5 |
||||
for how to configure the client. |
||||
-Note that environment passing is only supported for protocol 2. |
||||
+Note that environment passing is only supported for protocol 2, and |
||||
+that the |
||||
+.Ev TERM |
||||
+environment variable is always sent whenever the client |
||||
+requests a pseudo-terminal as it is required by the protocol. |
||||
Variables are specified by name, which may contain the wildcard characters |
||||
.Ql * |
||||
and |
@ -0,0 +1,292 @@
@@ -0,0 +1,292 @@
|
||||
diff --git a/entropy.c b/entropy.c |
||||
index 2d483b3..b361a04 100644 |
||||
--- a/entropy.c |
||||
+++ b/entropy.c |
||||
@@ -234,6 +234,9 @@ seed_rng(void) |
||||
memset(buf, '\0', sizeof(buf)); |
||||
|
||||
#endif /* OPENSSL_PRNG_ONLY */ |
||||
+#ifdef __linux__ |
||||
+ linux_seed(); |
||||
+#endif /* __linux__ */ |
||||
if (RAND_status() != 1) |
||||
fatal("PRNG is not seeded"); |
||||
} |
||||
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in |
||||
index b912dbe..9206337 100644 |
||||
--- a/openbsd-compat/Makefile.in |
||||
+++ b/openbsd-compat/Makefile.in |
||||
@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di |
||||
|
||||
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.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 xcrypt.o kludge-fd_set.o |
||||
|
||||
-PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-solaris.o port-tun.o port-uw.o |
||||
+PORTS=port-aix.o port-irix.o port-linux.o port-linux-sshd.o port-linux-prng.o port-solaris.o port-tun.o port-uw.o |
||||
|
||||
.c.o: |
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< |
||||
diff -up openssh-7.4p1/openbsd-compat/port-linux.h.entropy openssh-7.4p1/openbsd-compat/port-linux.h |
||||
--- openssh-7.4p1/openbsd-compat/port-linux.h.entropy 2016-12-23 18:34:27.747753563 +0100 |
||||
+++ openssh-7.4p1/openbsd-compat/port-linux.h 2016-12-23 18:34:27.769753570 +0100 |
||||
@@ -34,4 +34,6 @@ void oom_adjust_restore(void); |
||||
void oom_adjust_setup(void); |
||||
#endif |
||||
|
||||
+void linux_seed(void); |
||||
+ |
||||
#endif /* ! _PORT_LINUX_H */ |
||||
diff --git a/openbsd-compat/port-linux-prng.c b/openbsd-compat/port-linux-prng.c |
||||
new file mode 100644 |
||||
index 0000000..92a617c |
||||
--- /dev/null |
||||
+++ b/openbsd-compat/port-linux-prng.c |
||||
@@ -0,0 +1,59 @@ |
||||
+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ |
||||
+ |
||||
+/* |
||||
+ * Copyright (c) 2011 Jan F. Chadima <jchadima@redhat.com> |
||||
+ * |
||||
+ * Permission to use, copy, modify, and distribute this software for any |
||||
+ * purpose with or without fee is hereby granted, provided that the above |
||||
+ * copyright notice and this permission notice appear in all copies. |
||||
+ * |
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
+ */ |
||||
+ |
||||
+/* |
||||
+ * Linux-specific portability code - prng support |
||||
+ */ |
||||
+ |
||||
+#include "includes.h" |
||||
+ |
||||
+#include <errno.h> |
||||
+#include <stdarg.h> |
||||
+#include <string.h> |
||||
+#include <stdio.h> |
||||
+#include <openssl/rand.h> |
||||
+ |
||||
+#include "log.h" |
||||
+#include "xmalloc.h" |
||||
+#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ |
||||
+#include "servconf.h" |
||||
+#include "port-linux.h" |
||||
+#include "key.h" |
||||
+#include "hostfile.h" |
||||
+#include "auth.h" |
||||
+ |
||||
+void |
||||
+linux_seed(void) |
||||
+{ |
||||
+ char *env = getenv("SSH_USE_STRONG_RNG"); |
||||
+ char *random = "/dev/random"; |
||||
+ size_t len, ienv, randlen = 14; |
||||
+ |
||||
+ if (!env || !strcmp(env, "0")) |
||||
+ random = "/dev/urandom"; |
||||
+ else if ((ienv = atoi(env)) > randlen) |
||||
+ randlen = ienv; |
||||
+ |
||||
+ errno = 0; |
||||
+ if ((len = RAND_load_file(random, randlen)) != randlen) { |
||||
+ if (errno) |
||||
+ fatal ("cannot read from %s, %s", random, strerror(errno)); |
||||
+ else |
||||
+ fatal ("EOF reading %s", random); |
||||
+ } |
||||
+} |
||||
diff --git a/ssh-add.0 b/ssh-add.0 |
||||
index ba43fee..0b2629a 100644 |
||||
--- a/ssh-add.0 |
||||
+++ b/ssh-add.0 |
||||
@@ -82,6 +82,16 @@ ENVIRONMENT |
||||
Identifies the path of a UNIX-domain socket used to communicate |
||||
with the agent. |
||||
|
||||
+ SSH_USE_STRONG_RNG |
||||
+ The reseeding of the OpenSSL random generator is usually done |
||||
+ from /dev/urandom. If the SSH_USE_STRONG_RNG environment vari- |
||||
+ able is set to value other than 0 the OpenSSL random generator is |
||||
+ reseeded from /dev/random. The number of bytes read is defined |
||||
+ by the SSH_USE_STRONG_RNG value. Minimum is 14 bytes. This set- |
||||
+ ting is not recommended on the computers without the hardware |
||||
+ random generator because insufficient entropy causes the connec- |
||||
+ tion to be blocked until enough entropy is available. |
||||
+ |
||||
FILES |
||||
~/.ssh/identity |
||||
Contains the protocol version 1 RSA authentication identity of |
||||
diff --git a/ssh-add.1 b/ssh-add.1 |
||||
index 4812448..16305bf 100644 |
||||
--- a/ssh-add.1 |
||||
+++ b/ssh-add.1 |
||||
@@ -161,6 +161,20 @@ to make this work.) |
||||
Identifies the path of a |
||||
.Ux Ns -domain |
||||
socket used to communicate with the agent. |
||||
+.It Ev SSH_USE_STRONG_RNG |
||||
+The reseeding of the OpenSSL random generator is usually done from |
||||
+.Cm /dev/urandom . |
||||
+If the |
||||
+.Cm SSH_USE_STRONG_RNG |
||||
+environment variable is set to value other than |
||||
+.Cm 0 |
||||
+the OpenSSL random generator is reseeded from |
||||
+.Cm /dev/random . |
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. |
||||
+Minimum is 14 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 |
||||
diff --git a/ssh-agent.1 b/ssh-agent.1 |
||||
index 281ecbd..1a9a635 100644 |
||||
--- a/ssh-agent.1 |
||||
+++ b/ssh-agent.1 |
||||
@@ -201,6 +201,24 @@ 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 14 bytes. |
||||
+This setting is not recommended on the computers without the hardware |
||||
+random generator because insufficient entropy causes the connection to |
||||
+be blocked until enough entropy is available. |
||||
+.El |
||||
.Sh SEE ALSO |
||||
.Xr ssh 1 , |
||||
.Xr ssh-add 1 , |
||||
diff --git a/ssh-keygen.1 b/ssh-keygen.1 |
||||
index 12e00d4..1b51a4a 100644 |
||||
--- a/ssh-keygen.1 |
||||
+++ b/ssh-keygen.1 |
||||
@@ -832,6 +832,24 @@ 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 14 bytes. |
||||
+This setting is not recommended on the computers without the hardware |
||||
+random generator because insufficient entropy causes the connection to |
||||
+be blocked until enough entropy is available. |
||||
+.El |
||||
.Sh SEE ALSO |
||||
.Xr ssh 1 , |
||||
.Xr ssh-add 1 , |
||||
diff --git a/ssh-keysign.8 b/ssh-keysign.8 |
||||
index 69d0829..02d79f8 100644 |
||||
--- a/ssh-keysign.8 |
||||
+++ b/ssh-keysign.8 |
||||
@@ -80,6 +80,24 @@ must be set-uid root if host-based authentication is used. |
||||
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 14 bytes. |
||||
+This setting is not recommended on the computers without the hardware |
||||
+random generator because insufficient entropy causes the connection to |
||||
+be blocked until enough entropy is available. |
||||
+.El |
||||
.Sh SEE ALSO |
||||
.Xr ssh 1 , |
||||
.Xr ssh-keygen 1 , |
||||
diff --git a/ssh.1 b/ssh.1 |
||||
index 929904b..f65e42f 100644 |
||||
--- a/ssh.1 |
||||
+++ b/ssh.1 |
||||
@@ -1309,6 +1309,23 @@ For more information, see the |
||||
.Cm PermitUserEnvironment |
||||
option in |
||||
.Xr sshd_config 5 . |
||||
+.Sh ENVIRONMENT |
||||
+.Bl -tag -width Ds -compact |
||||
+.It Ev SSH_USE_STRONG_RNG |
||||
+The reseeding of the OpenSSL random generator is usually done from |
||||
+.Cm /dev/urandom . |
||||
+If the |
||||
+.Cm SSH_USE_STRONG_RNG |
||||
+environment variable is set to value other than |
||||
+.Cm 0 |
||||
+the OpenSSL random generator is reseeded from |
||||
+.Cm /dev/random . |
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value. |
||||
+Minimum is 14 bytes. |
||||
+This setting is not recommended on the computers without the hardware |
||||
+random generator because insufficient entropy causes the connection to |
||||
+be blocked until enough entropy is available. |
||||
+.El |
||||
.Sh FILES |
||||
.Bl -tag -width Ds -compact |
||||
.It Pa ~/.rhosts |
||||
diff --git a/sshd.8 b/sshd.8 |
||||
index c2c237f..058d37a 100644 |
||||
--- a/sshd.8 |
||||
+++ b/sshd.8 |
||||
@@ -951,6 +951,24 @@ 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 14 bytes. |
||||
+This setting is not recommended on the computers without the hardware |
||||
+random generator because insufficient entropy causes the connection to |
||||
+be blocked until enough entropy is available. |
||||
+.El |
||||
.Sh IPV6 |
||||
IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell. |
||||
.Sh SEE ALSO |
@ -0,0 +1,387 @@
@@ -0,0 +1,387 @@
|
||||
From f98a09cacff7baad8748c9aa217afd155a4d493f Mon Sep 17 00:00:00 2001 |
||||
From: "mmcc@openbsd.org" <mmcc@openbsd.org> |
||||
Date: Tue, 20 Oct 2015 03:36:35 +0000 |
||||
Subject: upstream commit |
||||
|
||||
Replace a function-local allocation with stack memory. |
||||
|
||||
ok djm@ |
||||
|
||||
Upstream-ID: c09fbbab637053a2ab9f33ca142b4e20a4c5a17e |
||||
--- |
||||
clientloop.c | 9 ++------- |
||||
1 file changed, 2 insertions(+), 7 deletions(-) |
||||
|
||||
diff --git a/clientloop.c b/clientloop.c |
||||
index 87ceb3d..1e05cba 100644 |
||||
--- a/clientloop.c |
||||
+++ b/clientloop.c |
||||
@@ -311,11 +311,10 @@ client_x11_get_proto(const char *display, const char *xauth_path, |
||||
static char proto[512], data[512]; |
||||
FILE *f; |
||||
int got_data = 0, generated = 0, do_unlink = 0, i; |
||||
- char *xauthdir, *xauthfile; |
||||
+ char xauthdir[MAXPATHLEN] = "", xauthfile[MAXPATHLEN] = ""; |
||||
struct stat st; |
||||
u_int now, x11_timeout_real; |
||||
|
||||
- xauthdir = xauthfile = NULL; |
||||
*_proto = proto; |
||||
*_data = data; |
||||
proto[0] = data[0] = '\0'; |
||||
@@ -343,8 +342,6 @@ client_x11_get_proto(const char *display, const char *xauth_path, |
||||
display = xdisplay; |
||||
} |
||||
if (trusted == 0) { |
||||
- xauthdir = xmalloc(MAXPATHLEN); |
||||
- xauthfile = xmalloc(MAXPATHLEN); |
||||
mktemp_proto(xauthdir, MAXPATHLEN); |
||||
/* |
||||
* The authentication cookie should briefly outlive |
||||
@@ -407,8 +404,6 @@ client_x11_get_proto(const char *display, const char *xauth_path, |
||||
unlink(xauthfile); |
||||
rmdir(xauthdir); |
||||
} |
||||
- free(xauthdir); |
||||
- free(xauthfile); |
||||
|
||||
/* |
||||
* If we didn't get authentication data, just make up some |
||||
-- |
||||
cgit v0.11.2 |
||||
|
||||
From ed4ce82dbfa8a3a3c8ea6fa0db113c71e234416c Mon Sep 17 00:00:00 2001 |
||||
From: "djm@openbsd.org" <djm@openbsd.org> |
||||
Date: Wed, 13 Jan 2016 23:04:47 +0000 |
||||
Subject: upstream commit |
||||
|
||||
eliminate fallback from untrusted X11 forwarding to trusted |
||||
forwarding when the X server disables the SECURITY extension; Reported by |
||||
Thomas Hoger; ok deraadt@ |
||||
|
||||
Upstream-ID: f76195bd2064615a63ef9674a0e4096b0713f938 |
||||
--- |
||||
clientloop.c | 114 ++++++++++++++++++++++++++++++++++++----------------------- |
||||
clientloop.h | 4 +-- |
||||
mux.c | 22 ++++++------ |
||||
ssh.c | 23 +++++------- |
||||
4 files changed, 93 insertions(+), 70 deletions(-) |
||||
|
||||
diff --git a/clientloop.c b/clientloop.c |
||||
index f555451..c0386d5 100644 |
||||
--- a/clientloop.c |
||||
+++ b/clientloop.c |
||||
@@ -288,6 +288,9 @@ client_x11_display_valid(const char *display) |
||||
{ |
||||
size_t i, dlen; |
||||
|
||||
+ if (display == NULL) |
||||
+ return 0; |
||||
+ |
||||
dlen = strlen(display); |
||||
for (i = 0; i < dlen; i++) { |
||||
if (!isalnum((u_char)display[i]) && |
||||
@@ -301,34 +304,33 @@ client_x11_display_valid(const char *display) |
||||
|
||||
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" |
||||
#define X11_TIMEOUT_SLACK 60 |
||||
-void |
||||
+int |
||||
client_x11_get_proto(const char *display, const char *xauth_path, |
||||
u_int trusted, u_int timeout, char **_proto, char **_data) |
||||
{ |
||||
- char cmd[1024]; |
||||
- char line[512]; |
||||
- char xdisplay[512]; |
||||
+ char cmd[1024], line[512], xdisplay[512]; |
||||
+ char xauthfile[MAXPATHLEN], xauthdir[MAXPATHLEN]; |
||||
static char proto[512], data[512]; |
||||
FILE *f; |
||||
- int got_data = 0, generated = 0, do_unlink = 0, i; |
||||
- char xauthdir[MAXPATHLEN] = "", xauthfile[MAXPATHLEN] = ""; |
||||
+ int got_data = 0, generated = 0, do_unlink = 0, i, r; |
||||
struct stat st; |
||||
u_int now, x11_timeout_real; |
||||
|
||||
*_proto = proto; |
||||
*_data = data; |
||||
- proto[0] = data[0] = '\0'; |
||||
+ proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; |
||||
|
||||
- if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { |
||||
- debug("No xauth program."); |
||||
- } else if (!client_x11_display_valid(display)) { |
||||
- logit("DISPLAY '%s' invalid, falling back to fake xauth data", |
||||
+ if (!client_x11_display_valid(display)) { |
||||
+ logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", |
||||
display); |
||||
- } else { |
||||
- if (display == NULL) { |
||||
- debug("x11_get_proto: DISPLAY not set"); |
||||
- return; |
||||
- } |
||||
+ return -1; |
||||
+ } |
||||
+ if (xauth_path != NULL && stat(xauth_path, &st) == -1) { |
||||
+ debug("No xauth program."); |
||||
+ xauth_path = NULL; |
||||
+ } |
||||
+ |
||||
+ if (xauth_path != NULL) { |
||||
/* |
||||
* Handle FamilyLocal case where $DISPLAY does |
||||
* not match an authorization entry. For this we |
||||
@@ -337,43 +339,60 @@ client_x11_get_proto(const char *display, const char *xauth_path, |
||||
* is not perfect. |
||||
*/ |
||||
if (strncmp(display, "localhost:", 10) == 0) { |
||||
- snprintf(xdisplay, sizeof(xdisplay), "unix:%s", |
||||
- display + 10); |
||||
+ if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s", |
||||
+ display + 10)) < 0 || |
||||
+ (size_t)r >= sizeof(xdisplay)) { |
||||
+ error("%s: display name too long", __func__); |
||||
+ return -1; |
||||
+ } |
||||
display = xdisplay; |
||||
} |
||||
if (trusted == 0) { |
||||
- mktemp_proto(xauthdir, MAXPATHLEN); |
||||
/* |
||||
+ * Generate an untrusted X11 auth cookie. |
||||
+ * |
||||
* The authentication cookie should briefly outlive |
||||
* ssh's willingness to forward X11 connections to |
||||
* avoid nasty fail-open behaviour in the X server. |
||||
*/ |
||||
+ mktemp_proto(xauthdir, sizeof(xauthdir)); |
||||
+ if (mkdtemp(xauthdir) == NULL) { |
||||
+ error("%s: mkdtemp: %s", |
||||
+ __func__, strerror(errno)); |
||||
+ return -1; |
||||
+ } |
||||
+ do_unlink = 1; |
||||
+ if ((r = snprintf(xauthfile, sizeof(xauthfile), |
||||
+ "%s/xauthfile", xauthdir)) < 0 || |
||||
+ (size_t)r >= sizeof(xauthfile)) { |
||||
+ error("%s: xauthfile path too long", __func__); |
||||
+ unlink(xauthfile); |
||||
+ rmdir(xauthdir); |
||||
+ return -1; |
||||
+ } |
||||
+ |
||||
if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK) |
||||
x11_timeout_real = UINT_MAX; |
||||
else |
||||
x11_timeout_real = timeout + X11_TIMEOUT_SLACK; |
||||
- if (mkdtemp(xauthdir) != NULL) { |
||||
- do_unlink = 1; |
||||
- snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", |
||||
- xauthdir); |
||||
- snprintf(cmd, sizeof(cmd), |
||||
- "%s -f %s generate %s " SSH_X11_PROTO |
||||
- " untrusted timeout %u 2>" _PATH_DEVNULL, |
||||
- xauth_path, xauthfile, display, |
||||
- x11_timeout_real); |
||||
- debug2("x11_get_proto: %s", cmd); |
||||
- if (x11_refuse_time == 0) { |
||||
- now = monotime() + 1; |
||||
- if (UINT_MAX - timeout < now) |
||||
- x11_refuse_time = UINT_MAX; |
||||
- else |
||||
- x11_refuse_time = now + timeout; |
||||
- channel_set_x11_refuse_time( |
||||
- x11_refuse_time); |
||||
- } |
||||
- if (system(cmd) == 0) |
||||
- generated = 1; |
||||
+ if ((r = snprintf(cmd, sizeof(cmd), |
||||
+ "%s -f %s generate %s " SSH_X11_PROTO |
||||
+ " untrusted timeout %u 2>" _PATH_DEVNULL, |
||||
+ xauth_path, xauthfile, display, |
||||
+ x11_timeout_real)) < 0 || |
||||
+ (size_t)r >= sizeof(cmd)) |
||||
+ fatal("%s: cmd too long", __func__); |
||||
+ debug2("%s: %s", __func__, cmd); |
||||
+ if (x11_refuse_time == 0) { |
||||
+ now = monotime() + 1; |
||||
+ if (UINT_MAX - timeout < now) |
||||
+ x11_refuse_time = UINT_MAX; |
||||
+ else |
||||
+ x11_refuse_time = now + timeout; |
||||
+ channel_set_x11_refuse_time(x11_refuse_time); |
||||
} |
||||
+ if (system(cmd) == 0) |
||||
+ generated = 1; |
||||
} |
||||
|
||||
/* |
||||
@@ -395,9 +414,7 @@ client_x11_get_proto(const char *display, const char *xauth_path, |
||||
got_data = 1; |
||||
if (f) |
||||
pclose(f); |
||||
- } else |
||||
- error("Warning: untrusted X11 forwarding setup failed: " |
||||
- "xauth key data not generated"); |
||||
+ } |
||||
} |
||||
|
||||
if (do_unlink) { |
||||
@@ -405,6 +422,13 @@ client_x11_get_proto(const char *display, const char *xauth_path, |
||||
rmdir(xauthdir); |
||||
} |
||||
|
||||
+ /* Don't fall back to fake X11 data for untrusted forwarding */ |
||||
+ if (!trusted && !got_data) { |
||||
+ error("Warning: untrusted X11 forwarding setup failed: " |
||||
+ "xauth key data not generated"); |
||||
+ return -1; |
||||
+ } |
||||
+ |
||||
/* |
||||
* If we didn't get authentication data, just make up some |
||||
* data. The forwarding code will check the validity of the |
||||
@@ -427,6 +451,8 @@ client_x11_get_proto(const char *display, const char *xauth_path, |
||||
rnd >>= 8; |
||||
} |
||||
} |
||||
+ |
||||
+ return 0; |
||||
} |
||||
|
||||
/* |
||||
diff --git a/clientloop.h b/clientloop.h |
||||
index 338d451..f4d4c69 100644 |
||||
--- a/clientloop.h |
||||
+++ b/clientloop.h |
||||
@@ -39,7 +39,7 @@ |
||||
|
||||
/* Client side main loop for the interactive session. */ |
||||
int client_loop(int, int, int); |
||||
-void client_x11_get_proto(const char *, const char *, u_int, u_int, |
||||
+int client_x11_get_proto(const char *, const char *, u_int, u_int, |
||||
char **, char **); |
||||
void client_global_request_reply_fwd(int, u_int32_t, void *); |
||||
void client_session2_setup(int, int, int, const char *, struct termios *, |
||||
diff --git a/mux.c b/mux.c |
||||
index f9c3af6..6bf53eb 100644 |
||||
--- a/mux.c |
||||
+++ b/mux.c |
||||
@@ -1354,16 +1354,18 @@ mux_session_confirm(int id, int success, void *arg) |
||||
char *proto, *data; |
||||
|
||||
/* Get reasonable local authentication information. */ |
||||
- client_x11_get_proto(display, options.xauth_location, |
||||
+ if (client_x11_get_proto(display, options.xauth_location, |
||||
options.forward_x11_trusted, options.forward_x11_timeout, |
||||
- &proto, &data); |
||||
- /* Request forwarding with authentication spoofing. */ |
||||
- debug("Requesting X11 forwarding with authentication " |
||||
- "spoofing."); |
||||
- x11_request_forwarding_with_spoofing(id, display, proto, |
||||
- data, 1); |
||||
- client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); |
||||
- /* XXX exit_on_forward_failure */ |
||||
+ &proto, &data) == 0) { |
||||
+ /* Request forwarding with authentication spoofing. */ |
||||
+ debug("Requesting X11 forwarding with authentication " |
||||
+ "spoofing."); |
||||
+ x11_request_forwarding_with_spoofing(id, display, proto, |
||||
+ data, 1); |
||||
+ /* XXX exit_on_forward_failure */ |
||||
+ client_expect_confirm(id, "X11 forwarding", |
||||
+ CONFIRM_WARN); |
||||
+ } |
||||
} |
||||
|
||||
if (cctx->want_agent_fwd && options.forward_agent) { |
||||
diff --git a/ssh.c b/ssh.c |
||||
index 81704ab..096c5b5 100644 |
||||
--- a/ssh.c |
||||
+++ b/ssh.c |
||||
@@ -1626,6 +1626,7 @@ ssh_session(void) |
||||
struct winsize ws; |
||||
char *cp; |
||||
const char *display; |
||||
+ char *proto = NULL, *data = NULL; |
||||
|
||||
/* Enable compression if requested. */ |
||||
if (options.compression) { |
||||
@@ -1696,13 +1697,9 @@ ssh_session(void) |
||||
} |
||||
/* Request X11 forwarding if enabled and DISPLAY is set. */ |
||||
display = getenv("DISPLAY"); |
||||
- if (options.forward_x11 && display != NULL) { |
||||
- char *proto, *data; |
||||
- /* Get reasonable local authentication information. */ |
||||
- client_x11_get_proto(display, options.xauth_location, |
||||
- options.forward_x11_trusted, |
||||
- options.forward_x11_timeout, |
||||
- &proto, &data); |
||||
+ if (options.forward_x11 && client_x11_get_proto(display, |
||||
+ options.xauth_location, options.forward_x11_trusted, |
||||
+ options.forward_x11_timeout, &proto, &data) == 0) { |
||||
/* Request forwarding with authentication spoofing. */ |
||||
debug("Requesting X11 forwarding with authentication " |
||||
"spoofing."); |
||||
@@ -1792,6 +1789,7 @@ ssh_session2_setup(int id, int success, void *arg) |
||||
extern char **environ; |
||||
const char *display; |
||||
int interactive = tty_flag; |
||||
+ char *proto = NULL, *data = NULL; |
||||
|
||||
if (!success) |
||||
return; /* No need for error message, channels code sens one */ |
||||
@@ -1799,12 +1797,9 @@ ssh_session2_setup(int id, int success, void *arg) |
||||
return; /* No need for error message, channels code sens one */ |
||||
|
||||
display = getenv("DISPLAY"); |
||||
- if (options.forward_x11 && display != NULL) { |
||||
- char *proto, *data; |
||||
- /* Get reasonable local authentication information. */ |
||||
- client_x11_get_proto(display, options.xauth_location, |
||||
- options.forward_x11_trusted, |
||||
- options.forward_x11_timeout, &proto, &data); |
||||
+ if (options.forward_x11 && client_x11_get_proto(display, |
||||
+ options.xauth_location, options.forward_x11_trusted, |
||||
+ options.forward_x11_timeout, &proto, &data) == 0) { |
||||
/* Request forwarding with authentication spoofing. */ |
||||
debug("Requesting X11 forwarding with authentication " |
||||
"spoofing."); |
||||
-- |
||||
cgit v0.11.2 |
||||
|
||||
From 5658ef2501e785fbbdf5de2dc33b1ff7a4dca73a Mon Sep 17 00:00:00 2001 |
||||
From: "millert@openbsd.org" <millert@openbsd.org> |
||||
Date: Mon, 1 Feb 2016 21:18:17 +0000 |
||||
Subject: upstream commit |
||||
|
||||
Avoid ugly "DISPLAY "(null)" invalid; disabling X11 |
||||
forwarding" message when DISPLAY is not set. This could also result in a |
||||
crash on systems with a printf that doesn't handle NULL. OK djm@ |
||||
|
||||
Upstream-ID: 20ee0cfbda678a247264c20ed75362042b90b412 |
||||
--- |
||||
clientloop.c | 7 ++++--- |
||||
1 file changed, 4 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/clientloop.c b/clientloop.c |
||||
index f8f9a3f..f0a08f2 100644 |
||||
--- a/clientloop.c |
||||
+++ b/clientloop.c |
||||
@@ -318,8 +318,9 @@ client_x11_get_proto(const char *display, const char *xauth_path, |
||||
proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; |
||||
|
||||
if (!client_x11_display_valid(display)) { |
||||
- logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", |
||||
- display); |
||||
+ if (display != NULL) |
||||
+ logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", |
||||
+ display); |
||||
return -1; |
||||
} |
||||
if (xauth_path != NULL && stat(xauth_path, &st) == -1) { |
||||
-- |
||||
cgit v0.11.2 |
||||
|
||||
|
@ -0,0 +1,415 @@
@@ -0,0 +1,415 @@
|
||||
diff --git a/auth.c b/auth.c |
||||
index 9a36f1d..420a85b 100644 |
||||
--- a/auth.c |
||||
+++ b/auth.c |
||||
@@ -685,9 +685,10 @@ auth_key_is_revoked(Key *key) |
||||
case 1: |
||||
revoked: |
||||
/* Key revoked */ |
||||
- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); |
||||
+ key_fp = key_selected_fingerprint(key, SSH_FP_HEX); |
||||
error("WARNING: authentication attempt with a revoked " |
||||
- "%s key %s ", key_type(key), key_fp); |
||||
+ "%s key %s%s ", key_type(key), |
||||
+ key_fingerprint_prefix(), key_fp); |
||||
free(key_fp); |
||||
return 1; |
||||
} |
||||
diff --git a/auth2-hostbased.c b/auth2-hostbased.c |
||||
index 488008f..eca0069 100644 |
||||
--- a/auth2-hostbased.c |
||||
+++ b/auth2-hostbased.c |
||||
@@ -206,16 +206,18 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, |
||||
|
||||
if (host_status == HOST_OK) { |
||||
if (key_is_cert(key)) { |
||||
- fp = key_fingerprint(key->cert->signature_key, |
||||
- SSH_FP_MD5, SSH_FP_HEX); |
||||
+ fp = key_selected_fingerprint(key->cert->signature_key, |
||||
+ 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, |
||||
+ "%s CA %s%s from %s@%s", key->cert->key_id, |
||||
+ key_type(key->cert->signature_key), |
||||
+ key_fingerprint_prefix(), fp, |
||||
cuser, lookup); |
||||
} else { |
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); |
||||
- verbose("Accepted %s public key %s from %s@%s", |
||||
- key_type(key), fp, cuser, lookup); |
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX); |
||||
+ verbose("Accepted %s public key %s%s from %s@%s", |
||||
+ key_type(key), key_fingerprint_prefix(), |
||||
+ fp, cuser, lookup); |
||||
} |
||||
free(fp); |
||||
} |
||||
diff --git a/auth2-pubkey.c b/auth2-pubkey.c |
||||
index 0fd27bb..749b11a 100644 |
||||
--- a/auth2-pubkey.c |
||||
+++ b/auth2-pubkey.c |
||||
@@ -365,10 +365,10 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) |
||||
continue; |
||||
if (!key_is_cert_authority) |
||||
continue; |
||||
- fp = key_fingerprint(found, SSH_FP_MD5, |
||||
- SSH_FP_HEX); |
||||
- debug("matching CA found: file %s, line %lu, %s %s", |
||||
- file, linenum, key_type(found), fp); |
||||
+ fp = key_selected_fingerprint(found, SSH_FP_HEX); |
||||
+ debug("matching CA found: file %s, line %lu, %s %s%s", |
||||
+ file, linenum, key_type(found), |
||||
+ key_fingerprint_prefix(), fp); |
||||
/* |
||||
* If the user has specified a list of principals as |
||||
* a key option, then prefer that list to matching |
||||
@@ -406,9 +406,9 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) |
||||
if (key_is_cert_authority) |
||||
continue; |
||||
found_key = 1; |
||||
- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); |
||||
- debug("matching key found: file %s, line %lu %s %s", |
||||
- file, linenum, key_type(found), fp); |
||||
+ fp = key_selected_fingerprint(found, SSH_FP_HEX); |
||||
+ verbose("Found matching %s key: %s%s", |
||||
+ key_type(found), key_fingerprint_prefix(), fp); |
||||
free(fp); |
||||
break; |
||||
} |
||||
@@ -431,13 +431,13 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) |
||||
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); |
||||
+ ca_fp = key_selected_fingerprint(key->cert->signature_key, 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, |
||||
+ debug2("%s: CA %s%s %s is not listed in %s", __func__, |
||||
+ key_type(key->cert->signature_key), |
||||
+ key_fingerprint_prefix(), ca_fp, |
||||
options.trusted_user_ca_keys); |
||||
goto out; |
||||
} |
||||
diff --git a/key.c b/key.c |
||||
index 168e1b7..eb98ea8 100644 |
||||
--- a/key.c |
||||
+++ b/key.c |
||||
@@ -628,6 +628,34 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) |
||||
return retval; |
||||
} |
||||
|
||||
+enum fp_type |
||||
+key_fingerprint_selection(void) |
||||
+{ |
||||
+ static enum fp_type rv; |
||||
+ static char rv_defined = 0; |
||||
+ char *env; |
||||
+ |
||||
+ if (!rv_defined) { |
||||
+ env = getenv("SSH_FINGERPRINT_TYPE"); |
||||
+ rv = (env && !strcmp (env, "sha")) ? |
||||
+ SSH_FP_SHA1 : SSH_FP_MD5; |
||||
+ rv_defined = 1; |
||||
+ } |
||||
+ return rv; |
||||
+} |
||||
+ |
||||
+char * |
||||
+key_selected_fingerprint(Key *k, enum fp_rep dgst_rep) |
||||
+{ |
||||
+ return key_fingerprint(k, key_fingerprint_selection(), dgst_rep); |
||||
+} |
||||
+ |
||||
+char * |
||||
+key_fingerprint_prefix(void) |
||||
+{ |
||||
+ return key_fingerprint_selection() == SSH_FP_SHA1 ? "sha1:" : ""; |
||||
+} |
||||
+ |
||||
/* |
||||
* Reads a multiple-precision integer in decimal from the buffer, and advances |
||||
* the pointer. The integer must already be initialized. This function is |
||||
diff --git a/key.h b/key.h |
||||
index d8ad13d..0e3eea5 100644 |
||||
--- a/key.h |
||||
+++ b/key.h |
||||
@@ -104,6 +104,9 @@ int key_equal_public(const Key *, const Key *); |
||||
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 *); |
||||
+enum fp_type key_fingerprint_selection(void); |
||||
+char *key_selected_fingerprint(Key *, enum fp_rep); |
||||
+char *key_fingerprint_prefix(void); |
||||
const char *key_type(const Key *); |
||||
const char *key_cert_type(const Key *); |
||||
int key_write(const Key *, FILE *); |
||||
diff --git a/ssh-add.c b/ssh-add.c |
||||
index 3421452..691949f 100644 |
||||
--- a/ssh-add.c |
||||
+++ b/ssh-add.c |
||||
@@ -330,10 +330,10 @@ list_identities(AuthenticationConnection *ac, int do_fp) |
||||
key = ssh_get_next_identity(ac, &comment, version)) { |
||||
had_identities = 1; |
||||
if (do_fp) { |
||||
- fp = key_fingerprint(key, SSH_FP_MD5, |
||||
- SSH_FP_HEX); |
||||
- printf("%d %s %s (%s)\n", |
||||
- key_size(key), fp, comment, key_type(key)); |
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX); |
||||
+ printf("%d %s%s %s (%s)\n", |
||||
+ key_size(key), key_fingerprint_prefix(), |
||||
+ fp, comment, key_type(key)); |
||||
free(fp); |
||||
} else { |
||||
if (!key_write(key, stdout)) |
||||
diff --git a/ssh-agent.c b/ssh-agent.c |
||||
index ba24612..117fdde 100644 |
||||
--- a/ssh-agent.c |
||||
+++ b/ssh-agent.c |
||||
@@ -198,9 +198,9 @@ confirm_key(Identity *id) |
||||
char *p; |
||||
int ret = -1; |
||||
|
||||
- p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); |
||||
- if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", |
||||
- id->comment, p)) |
||||
+ p = key_selected_fingerprint(id->key, SSH_FP_HEX); |
||||
+ if (ask_permission("Allow use of key %s?\nKey fingerprint %s%s.", |
||||
+ id->comment, key_fingerprint_prefix(), p)) |
||||
ret = 0; |
||||
free(p); |
||||
|
||||
diff --git a/ssh-keygen.c b/ssh-keygen.c |
||||
index 2a316bc..482dc1c 100644 |
||||
--- a/ssh-keygen.c |
||||
+++ b/ssh-keygen.c |
||||
@@ -783,13 +783,14 @@ do_fingerprint(struct passwd *pw) |
||||
{ |
||||
FILE *f; |
||||
Key *public; |
||||
- char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; |
||||
+ char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra, *pfx; |
||||
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_fingerprint_selection(); |
||||
+ pfx = print_bubblebabble ? "" : key_fingerprint_prefix(); |
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; |
||||
|
||||
if (!have_identity) |
||||
@@ -801,8 +802,8 @@ do_fingerprint(struct passwd *pw) |
||||
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); |
||||
- printf("%u %s %s (%s)\n", key_size(public), fp, comment, |
||||
+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); |
||||
+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, comment, |
||||
key_type(public)); |
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE) |
||||
printf("%s\n", ra); |
||||
@@ -867,8 +868,8 @@ do_fingerprint(struct passwd *pw) |
||||
} |
||||
comment = *cp ? cp : comment; |
||||
fp = key_fingerprint(public, fptype, rep); |
||||
- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); |
||||
- printf("%u %s %s (%s)\n", key_size(public), fp, |
||||
+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); |
||||
+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, |
||||
comment ? comment : "no comment", key_type(public)); |
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE) |
||||
printf("%s\n", ra); |
||||
@@ -986,13 +987,15 @@ 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; |
||||
+ char *fp, *ra, *pfx; |
||||
|
||||
- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; |
||||
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection(); |
||||
+ pfx = print_bubblebabble ? "" : key_fingerprint_prefix(); |
||||
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); |
||||
- printf("%u %s %s (%s)\n", key_size(public), fp, name, |
||||
+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART); |
||||
+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, name, |
||||
key_type(public)); |
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE) |
||||
printf("%s\n", ra); |
||||
@@ -1878,16 +1881,17 @@ do_show_cert(struct passwd *pw) |
||||
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); |
||||
- ca_fp = key_fingerprint(key->cert->signature_key, |
||||
- SSH_FP_MD5, SSH_FP_HEX); |
||||
+ key_fp = key_selected_fingerprint(key, SSH_FP_HEX); |
||||
+ ca_fp = key_selected_fingerprint(key->cert->signature_key, 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(" Public key: %s %s%s\n", key_type(key), |
||||
+ key_fingerprint_prefix(), key_fp); |
||||
+ printf(" Signing CA: %s %s%s\n", |
||||
+ key_type(key->cert->signature_key), |
||||
+ key_fingerprint_prefix(), ca_fp); |
||||
printf(" Key ID: \"%s\"\n", key->cert->key_id); |
||||
if (!v00) { |
||||
printf(" Serial: %llu\n", |
||||
@@ -2686,13 +2690,12 @@ passphrase_again: |
||||
fclose(f); |
||||
|
||||
if (!quiet) { |
||||
- char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); |
||||
- char *ra = key_fingerprint(public, SSH_FP_MD5, |
||||
- SSH_FP_RANDOMART); |
||||
+ char *fp = key_selected_fingerprint(public, SSH_FP_HEX); |
||||
+ char *ra = key_selected_fingerprint(public, 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("%s%s %s\n", key_fingerprint_prefix(), fp, comment); |
||||
printf("The key's randomart image is:\n"); |
||||
printf("%s\n", ra); |
||||
free(ra); |
||||
diff --git a/sshconnect.c b/sshconnect.c |
||||
index 573d7a8..394cca8 100644 |
||||
--- a/sshconnect.c |
||||
+++ b/sshconnect.c |
||||
@@ -914,10 +914,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, |
||||
"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, |
||||
- SSH_FP_RANDOMART); |
||||
- logit("Host key fingerprint is %s\n%s\n", fp, ra); |
||||
+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); |
||||
+ ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART); |
||||
+ logit("Host key fingerprint is %s%s\n%s\n", |
||||
+ key_fingerprint_prefix(), fp, ra); |
||||
free(ra); |
||||
free(fp); |
||||
} |
||||
@@ -955,9 +955,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, |
||||
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, |
||||
- SSH_FP_RANDOMART); |
||||
+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); |
||||
+ ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART); |
||||
msg2[0] = '\0'; |
||||
if (options.verify_host_key_dns) { |
||||
if (matching_host_key_dns) |
||||
@@ -972,10 +971,11 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, |
||||
snprintf(msg, sizeof(msg), |
||||
"The authenticity of host '%.200s (%s)' can't be " |
||||
"established%s\n" |
||||
- "%s key fingerprint is %s.%s%s\n%s" |
||||
+ "%s key fingerprint is %s%s.%s%s\n%s" |
||||
"Are you sure you want to continue connecting " |
||||
"(yes/no)? ", |
||||
- host, ip, msg1, type, fp, |
||||
+ host, ip, msg1, type, |
||||
+ key_fingerprint_prefix(), fp, |
||||
options.visual_host_key ? "\n" : "", |
||||
options.visual_host_key ? ra : "", |
||||
msg2); |
||||
@@ -1220,8 +1220,9 @@ 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); |
||||
- debug("Server host key: %s %s", key_type(host_key), fp); |
||||
+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); |
||||
+ debug("Server host key: %s %s%s", key_type(host_key), |
||||
+ key_fingerprint_prefix(), fp); |
||||
free(fp); |
||||
|
||||
/* XXX certs are not yet supported for DNS */ |
||||
@@ -1327,14 +1328,15 @@ show_other_keys(struct hostkeys *hostkeys, Key *key) |
||||
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_selected_fingerprint(found->key, SSH_FP_HEX); |
||||
+ ra = key_selected_fingerprint(found->key, SSH_FP_RANDOMART); |
||||
logit("WARNING: %s key found for host %s\n" |
||||
"in %s:%lu\n" |
||||
- "%s key fingerprint %s.", |
||||
+ "%s key fingerprint %s%s.", |
||||
key_type(found->key), |
||||
found->host, found->file, found->line, |
||||
- key_type(found->key), fp); |
||||
+ key_type(found->key), |
||||
+ key_fingerprint_prefix(), fp); |
||||
if (options.visual_host_key) |
||||
logit("%s", ra); |
||||
free(ra); |
||||
@@ -1349,7 +1351,7 @@ warn_changed_key(Key *host_key) |
||||
{ |
||||
char *fp; |
||||
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); |
||||
+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX); |
||||
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
||||
error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); |
||||
@@ -1357,8 +1359,8 @@ warn_changed_key(Key *host_key) |
||||
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.", |
||||
- key_type(host_key), fp); |
||||
+ error("The fingerprint for the %s key sent by the remote host is\n%s%s.", |
||||
+ key_type(host_key),key_fingerprint_prefix(), fp); |
||||
error("Please contact your system administrator."); |
||||
|
||||
free(fp); |
||||
diff --git a/sshconnect2.c b/sshconnect2.c |
||||
index 7f4ff41..adbbfc7 100644 |
||||
--- a/sshconnect2.c |
||||
+++ b/sshconnect2.c |
||||
@@ -577,8 +577,9 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) |
||||
key->type, pktype); |
||||
goto done; |
||||
} |
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); |
||||
- debug2("input_userauth_pk_ok: fp %s", fp); |
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX); |
||||
+ debug2("input_userauth_pk_ok: fp %s%s", |
||||
+ key_fingerprint_prefix(), fp); |
||||
free(fp); |
||||
|
||||
/* |
||||
@@ -986,8 +987,9 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) |
||||
int have_sig = 1; |
||||
char *fp; |
||||
|
||||
- fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); |
||||
- debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); |
||||
+ fp = key_selected_fingerprint(id->key, SSH_FP_HEX); |
||||
+ debug3("sign_and_send_pubkey: %s %s%s", key_type(id->key), |
||||
+ key_fingerprint_prefix(), fp); |
||||
free(fp); |
||||
|
||||
if (key_to_blob(id->key, &blob, &bloblen) == 0) { |
@ -0,0 +1,813 @@
@@ -0,0 +1,813 @@
|
||||
diff -up openssh-6.6p1/Makefile.in.fips openssh-6.6p1/Makefile.in |
||||
--- openssh-6.6p1/Makefile.in.fips 2015-08-13 15:09:43.343350136 +0200 |
||||
+++ openssh-6.6p1/Makefile.in 2015-08-13 15:09:43.356350114 +0200 |
||||
@@ -154,25 +154,25 @@ libssh.a: $(LIBSSH_OBJS) |
||||
$(RANLIB) $@ |
||||
|
||||
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) |
||||
- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) |
||||
+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(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 -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) |
||||
|
||||
scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o |
||||
$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
|
||||
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o |
||||
- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o |
||||
- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o |
||||
- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o |
||||
- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o |
||||
$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) |
||||
@@ -187,7 +187,7 @@ ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libs |
||||
$(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) |
||||
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o |
||||
- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) |
||||
+ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) |
||||
|
||||
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o |
||||
$(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
diff -up openssh-6.6p1/auth-rsa.c.fips openssh-6.6p1/auth-rsa.c |
||||
--- openssh-6.6p1/auth-rsa.c.fips 2015-08-13 15:09:43.344350134 +0200 |
||||
+++ openssh-6.6p1/auth-rsa.c 2015-08-13 15:09:43.354350118 +0200 |
||||
@@ -244,7 +244,7 @@ rsa_key_allowed_in_file(struct passwd *p |
||||
"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_selected_fingerprint(key, SSH_FP_HEX); |
||||
debug("matching key found: file %s, line %lu %s %s", |
||||
file, linenum, key_type(key), fp); |
||||
free(fp); |
||||
diff -up openssh-6.6p1/auth2-pubkey.c.fips openssh-6.6p1/auth2-pubkey.c |
||||
--- openssh-6.6p1/auth2-pubkey.c.fips 2015-08-13 15:09:43.345350133 +0200 |
||||
+++ openssh-6.6p1/auth2-pubkey.c 2015-08-13 15:09:43.353350119 +0200 |
||||
@@ -214,8 +214,7 @@ pubkey_auth_info(Authctxt *authctxt, con |
||||
} |
||||
|
||||
if (key_is_cert(key)) { |
||||
- fp = key_fingerprint(key->cert->signature_key, |
||||
- SSH_FP_MD5, SSH_FP_HEX); |
||||
+ fp = key_selected_fingerprint(key->cert->signature_key, 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, |
||||
@@ -223,7 +222,7 @@ pubkey_auth_info(Authctxt *authctxt, con |
||||
extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
||||
free(fp); |
||||
} else { |
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); |
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX); |
||||
auth_info(authctxt, "%s %s%s%s", key_type(key), fp, |
||||
extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
||||
free(fp); |
||||
diff -up openssh-6.6p1/authfile.c.fips openssh-6.6p1/authfile.c |
||||
--- openssh-6.6p1/authfile.c.fips 2015-08-13 15:09:43.213350355 +0200 |
||||
+++ openssh-6.6p1/authfile.c 2015-08-13 15:09:43.354350118 +0200 |
||||
@@ -46,6 +46,7 @@ |
||||
#include <openssl/err.h> |
||||
#include <openssl/evp.h> |
||||
#include <openssl/pem.h> |
||||
+#include <openssl/fips.h> |
||||
|
||||
/* compatibility with old or broken OpenSSL versions */ |
||||
#include "openbsd-compat/openssl-compat.h" |
||||
@@ -1008,7 +1009,10 @@ key_parse_private_type(Buffer *blob, int |
||||
|
||||
switch (type) { |
||||
case KEY_RSA1: |
||||
- return key_parse_private_rsa1(blob, passphrase, commentp); |
||||
+ if (! FIPS_mode()) |
||||
+ return key_parse_private_rsa1(blob, passphrase, commentp); |
||||
+ error("%s: cannot parse rsa1 key in FIPS mode", __func__); |
||||
+ break; |
||||
case KEY_DSA: |
||||
case KEY_ECDSA: |
||||
case KEY_RSA: |
||||
@@ -1068,7 +1072,7 @@ Key * |
||||
key_parse_private(Buffer *buffer, const char *filename, |
||||
const char *passphrase, char **commentp) |
||||
{ |
||||
- Key *pub, *prv; |
||||
+ Key *pub, *prv = NULL; |
||||
|
||||
/* it's a SSH v1 key if the public key part is readable */ |
||||
pub = key_parse_public_rsa1(buffer, commentp); |
||||
@@ -1080,9 +1084,10 @@ key_parse_private(Buffer *buffer, const |
||||
*commentp = xstrdup(filename); |
||||
} else { |
||||
key_free(pub); |
||||
- /* key_parse_public_rsa1() has already loaded the comment */ |
||||
- prv = key_parse_private_type(buffer, KEY_RSA1, passphrase, |
||||
- NULL); |
||||
+ if (! FIPS_mode()) |
||||
+ /* key_parse_public_rsa1() has already loaded the comment */ |
||||
+ prv = key_parse_private_type(buffer, KEY_RSA1, passphrase, |
||||
+ NULL); |
||||
} |
||||
return prv; |
||||
} |
||||
diff -up openssh-6.6p1/cipher-ctr.c.fips openssh-6.6p1/cipher-ctr.c |
||||
--- openssh-6.6p1/cipher-ctr.c.fips 2015-08-13 15:09:43.254350286 +0200 |
||||
+++ openssh-6.6p1/cipher-ctr.c 2015-08-13 15:09:43.354350118 +0200 |
||||
@@ -179,7 +179,8 @@ evp_aes_128_ctr(void) |
||||
aes_ctr.do_cipher = ssh_aes_ctr; |
||||
#ifndef SSH_OLD_EVP |
||||
aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | |
||||
- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; |
||||
+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV | |
||||
+ EVP_CIPH_FLAG_FIPS; |
||||
#endif |
||||
return (&aes_ctr); |
||||
} |
||||
diff -up openssh-6.6p1/cipher.c.fips openssh-6.6p1/cipher.c |
||||
--- openssh-6.6p1/cipher.c.fips 2015-08-13 15:09:43.345350133 +0200 |
||||
+++ openssh-6.6p1/cipher.c 2015-08-13 15:09:43.354350118 +0200 |
||||
@@ -39,6 +39,8 @@ |
||||
|
||||
#include <sys/types.h> |
||||
|
||||
+#include <openssl/fips.h> |
||||
+ |
||||
#include <string.h> |
||||
#include <stdarg.h> |
||||
#include <stdio.h> |
||||
@@ -90,6 +92,25 @@ static const struct Cipher ciphers[] = { |
||||
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } |
||||
}; |
||||
|
||||
+static const struct Cipher fips_ciphers[] = { |
||||
+ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, |
||||
+ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, |
||||
+ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, |
||||
+ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, |
||||
+ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, |
||||
+ { "rijndael-cbc@lysator.liu.se", |
||||
+ SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, |
||||
+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, |
||||
+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, |
||||
+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, |
||||
+#ifdef OPENSSL_HAVE_EVPGCM |
||||
+ { "aes128-gcm@openssh.com", |
||||
+ SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, |
||||
+ { "aes256-gcm@openssh.com", |
||||
+ SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, |
||||
+#endif |
||||
+ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } |
||||
+}; |
||||
/*--*/ |
||||
|
||||
/* Returns a list of supported ciphers separated by the specified char. */ |
||||
@@ -100,7 +121,7 @@ cipher_alg_list(char sep, int auth_only) |
||||
size_t nlen, rlen = 0; |
||||
const Cipher *c; |
||||
|
||||
- for (c = ciphers; c->name != NULL; c++) { |
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) { |
||||
if (c->number != SSH_CIPHER_SSH2) |
||||
continue; |
||||
if (auth_only && c->auth_len == 0) |
||||
@@ -180,7 +201,7 @@ const Cipher * |
||||
cipher_by_name(const char *name) |
||||
{ |
||||
const Cipher *c; |
||||
- for (c = ciphers; c->name != NULL; c++) |
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) |
||||
if (strcmp(c->name, name) == 0) |
||||
return c; |
||||
return NULL; |
||||
@@ -190,7 +211,7 @@ const Cipher * |
||||
cipher_by_number(int id) |
||||
{ |
||||
const Cipher *c; |
||||
- for (c = ciphers; c->name != NULL; c++) |
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) |
||||
if (c->number == id) |
||||
return c; |
||||
return NULL; |
||||
@@ -232,7 +253,7 @@ cipher_number(const char *name) |
||||
const Cipher *c; |
||||
if (name == NULL) |
||||
return -1; |
||||
- for (c = ciphers; c->name != NULL; c++) |
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) |
||||
if (strcasecmp(c->name, name) == 0) |
||||
return c->number; |
||||
return -1; |
||||
diff -up openssh-6.6p1/dh.h.fips openssh-6.6p1/dh.h |
||||
--- openssh-6.6p1/dh.h.fips 2013-10-10 01:32:40.000000000 +0200 |
||||
+++ openssh-6.6p1/dh.h 2015-08-13 15:09:43.354350118 +0200 |
||||
@@ -45,6 +45,7 @@ int dh_estimate(int); |
||||
|
||||
/* Min and max values from RFC4419. */ |
||||
#define DH_GRP_MIN 1024 |
||||
+#define DH_GRP_MIN_FIPS 2048 |
||||
#define DH_GRP_MAX 8192 |
||||
|
||||
/* |
||||
diff -up openssh-6.6p1/entropy.c.fips openssh-6.6p1/entropy.c |
||||
--- openssh-6.6p1/entropy.c.fips 2015-08-13 15:09:43.238350313 +0200 |
||||
+++ openssh-6.6p1/entropy.c 2015-08-13 15:09:43.355350116 +0200 |
||||
@@ -222,6 +222,9 @@ seed_rng(void) |
||||
fatal("OpenSSL version mismatch. Built against %lx, you " |
||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); |
||||
|
||||
+ /* clean the PRNG status when exiting the program */ |
||||
+ atexit(RAND_cleanup); |
||||
+ |
||||
#ifndef OPENSSL_PRNG_ONLY |
||||
if (RAND_status() == 1) { |
||||
debug3("RNG is ready, skipping seeding"); |
||||
diff -up openssh-6.6p1/kex.c.fips openssh-6.6p1/kex.c |
||||
--- openssh-6.6p1/kex.c.fips 2015-08-13 15:09:43.350350124 +0200 |
||||
+++ openssh-6.6p1/kex.c 2015-08-13 15:09:43.355350116 +0200 |
||||
@@ -34,6 +34,7 @@ |
||||
#include <string.h> |
||||
|
||||
#include <openssl/crypto.h> |
||||
+#include <openssl/fips.h> |
||||
|
||||
#include "xmalloc.h" |
||||
#include "ssh2.h" |
||||
@@ -103,6 +104,25 @@ static const struct kexalg kexalgs[] = { |
||||
{ NULL, -1, -1, -1}, |
||||
}; |
||||
|
||||
+static const struct kexalg kexalgs_fips[] = { |
||||
+ { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, |
||||
+ { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, |
||||
+#ifdef HAVE_EVP_SHA256 |
||||
+ { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, |
||||
+#endif |
||||
+#ifdef OPENSSL_HAS_ECC |
||||
+ { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, |
||||
+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, |
||||
+ { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, |
||||
+ SSH_DIGEST_SHA384 }, |
||||
+# ifdef OPENSSL_HAS_NISTP521 |
||||
+ { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, |
||||
+ SSH_DIGEST_SHA512 }, |
||||
+# endif |
||||
+#endif |
||||
+ { NULL, -1, -1, NULL}, |
||||
+}; |
||||
+ |
||||
char * |
||||
kex_alg_list(char sep) |
||||
{ |
||||
@@ -126,7 +146,7 @@ kex_alg_by_name(const char *name) |
||||
{ |
||||
const struct kexalg *k; |
||||
|
||||
- for (k = kexalgs; k->name != NULL; k++) { |
||||
+ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { |
||||
if (strcmp(k->name, name) == 0) |
||||
return k; |
||||
#ifdef GSSAPI |
||||
@@ -151,7 +171,10 @@ kex_names_valid(const char *names) |
||||
for ((p = strsep(&cp, ",")); p && *p != '\0'; |
||||
(p = strsep(&cp, ","))) { |
||||
if (kex_alg_by_name(p) == NULL) { |
||||
- error("Unsupported KEX algorithm \"%.100s\"", p); |
||||
+ if (FIPS_mode()) |
||||
+ error("\"%.100s\" is not allowed in FIPS mode", p); |
||||
+ else |
||||
+ error("Unsupported KEX algorithm \"%.100s\"", p); |
||||
free(s); |
||||
return 0; |
||||
} |
||||
diff -up openssh-6.6p1/kexecdhc.c.fips openssh-6.6p1/kexecdhc.c |
||||
--- openssh-6.6p1/kexecdhc.c.fips 2014-02-04 01:20:15.000000000 +0100 |
||||
+++ openssh-6.6p1/kexecdhc.c 2015-08-13 15:09:43.355350116 +0200 |
||||
@@ -154,6 +154,7 @@ kexecdh_client(Kex *kex) |
||||
|
||||
kex_derive_keys_bn(kex, hash, hashlen, shared_secret); |
||||
BN_clear_free(shared_secret); |
||||
+ memset(hash, 0, hashlen); |
||||
kex_finish(kex); |
||||
} |
||||
#else /* OPENSSL_HAS_ECC */ |
||||
diff -up openssh-6.6p1/kexecdhs.c.fips openssh-6.6p1/kexecdhs.c |
||||
--- openssh-6.6p1/kexecdhs.c.fips 2014-02-04 01:20:15.000000000 +0100 |
||||
+++ openssh-6.6p1/kexecdhs.c 2015-08-13 15:09:43.355350116 +0200 |
||||
@@ -150,6 +150,7 @@ kexecdh_server(Kex *kex) |
||||
|
||||
kex_derive_keys_bn(kex, hash, hashlen, shared_secret); |
||||
BN_clear_free(shared_secret); |
||||
+ memset(hash, 0, hashlen); |
||||
kex_finish(kex); |
||||
} |
||||
#else /* OPENSSL_HAS_ECC */ |
||||
diff -up openssh-6.6p1/kexgexc.c.fips openssh-6.6p1/kexgexc.c |
||||
--- openssh-6.6p1/kexgexc.c.fips 2014-02-04 01:20:15.000000000 +0100 |
||||
+++ openssh-6.6p1/kexgexc.c 2015-08-13 15:09:43.355350116 +0200 |
||||
@@ -26,6 +26,8 @@ |
||||
|
||||
#include "includes.h" |
||||
|
||||
+#include <openssl/fips.h> |
||||
+ |
||||
#include <sys/types.h> |
||||
|
||||
#include <openssl/dh.h> |
||||
@@ -64,13 +66,13 @@ kexgex_client(Kex *kex) |
||||
/* Old GEX request */ |
||||
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); |
||||
packet_put_int(nbits); |
||||
- min = DH_GRP_MIN; |
||||
+ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; |
||||
max = DH_GRP_MAX; |
||||
|
||||
debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); |
||||
} else { |
||||
/* New GEX request */ |
||||
- min = DH_GRP_MIN; |
||||
+ min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; |
||||
max = DH_GRP_MAX; |
||||
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); |
||||
packet_put_int(min); |
||||
diff -up openssh-6.6p1/kexgexs.c.fips openssh-6.6p1/kexgexs.c |
||||
--- openssh-6.6p1/kexgexs.c.fips 2014-02-04 01:20:15.000000000 +0100 |
||||
+++ openssh-6.6p1/kexgexs.c 2015-08-13 15:09:43.355350116 +0200 |
||||
@@ -76,16 +76,16 @@ kexgex_server(Kex *kex) |
||||
omin = min = packet_get_int(); |
||||
onbits = nbits = packet_get_int(); |
||||
omax = max = packet_get_int(); |
||||
- min = MAX(DH_GRP_MIN, min); |
||||
+ min = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); |
||||
max = MIN(DH_GRP_MAX, max); |
||||
- nbits = MAX(DH_GRP_MIN, nbits); |
||||
+ nbits = MAX(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); |
||||
nbits = MIN(DH_GRP_MAX, nbits); |
||||
break; |
||||
case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: |
||||
debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); |
||||
onbits = nbits = packet_get_int(); |
||||
/* unused for old GEX */ |
||||
- omin = min = DH_GRP_MIN; |
||||
+ omin = min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; |
||||
omax = max = DH_GRP_MAX; |
||||
break; |
||||
default: |
||||
diff -up openssh-6.6p1/key.c.fips openssh-6.6p1/key.c |
||||
--- openssh-6.6p1/key.c.fips 2015-08-13 15:09:43.345350133 +0200 |
||||
+++ openssh-6.6p1/key.c 2015-08-13 15:09:43.356350114 +0200 |
||||
@@ -42,6 +42,7 @@ |
||||
#include "crypto_api.h" |
||||
|
||||
#include <openssl/evp.h> |
||||
+#include <openssl/fips.h> |
||||
#include <openbsd-compat/openssl-compat.h> |
||||
|
||||
#include <stdarg.h> |
||||
@@ -636,9 +637,13 @@ key_fingerprint_selection(void) |
||||
char *env; |
||||
|
||||
if (!rv_defined) { |
||||
- env = getenv("SSH_FINGERPRINT_TYPE"); |
||||
- rv = (env && !strcmp (env, "sha")) ? |
||||
- SSH_FP_SHA1 : SSH_FP_MD5; |
||||
+ if (FIPS_mode()) |
||||
+ rv = SSH_FP_SHA1; |
||||
+ else { |
||||
+ env = getenv("SSH_FINGERPRINT_TYPE"); |
||||
+ rv = (env && !strcmp (env, "sha")) ? |
||||
+ SSH_FP_SHA1 : SSH_FP_MD5; |
||||
+ } |
||||
rv_defined = 1; |
||||
} |
||||
return rv; |
||||
@@ -1168,8 +1173,11 @@ rsa_generate_private_key(u_int bits) |
||||
fatal("%s: BN_new failed", __func__); |
||||
if (!BN_set_word(f4, RSA_F4)) |
||||
fatal("%s: BN_new failed", __func__); |
||||
- if (!RSA_generate_key_ex(private, bits, f4, NULL)) |
||||
+ if (!RSA_generate_key_ex(private, bits, f4, NULL)) { |
||||
+ if (FIPS_mode()) |
||||
+ logit("%s: the key length might be unsupported by FIPS mode approved key generation method", __func__); |
||||
fatal("%s: key generation failed.", __func__); |
||||
+ } |
||||
BN_free(f4); |
||||
return private; |
||||
} |
||||
diff -up openssh-6.6p1/mac.c.fips openssh-6.6p1/mac.c |
||||
--- openssh-6.6p1/mac.c.fips 2015-08-13 15:09:43.346350131 +0200 |
||||
+++ openssh-6.6p1/mac.c 2015-08-13 15:09:43.356350114 +0200 |
||||
@@ -27,6 +27,8 @@ |
||||
|
||||
#include <sys/types.h> |
||||
|
||||
+#include <openssl/fips.h> |
||||
+ |
||||
#include <stdarg.h> |
||||
#include <string.h> |
||||
#include <signal.h> |
||||
@@ -60,7 +62,7 @@ struct macalg { |
||||
int etm; /* Encrypt-then-MAC */ |
||||
}; |
||||
|
||||
-static const struct macalg macs[] = { |
||||
+static const struct macalg all_macs[] = { |
||||
/* Encrypt-and-MAC (encrypt-and-authenticate) variants */ |
||||
{ "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, |
||||
{ "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, |
||||
@@ -91,6 +93,24 @@ static const struct macalg macs[] = { |
||||
{ NULL, 0, 0, 0, 0, 0, 0 } |
||||
}; |
||||
|
||||
+static const struct macalg fips_macs[] = { |
||||
+ /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ |
||||
+ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, |
||||
+#ifdef HAVE_EVP_SHA256 |
||||
+ { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 }, |
||||
+ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, |
||||
+#endif |
||||
+ |
||||
+ /* Encrypt-then-MAC variants */ |
||||
+ { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, |
||||
+#ifdef HAVE_EVP_SHA256 |
||||
+ { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 }, |
||||
+ { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 }, |
||||
+#endif |
||||
+ |
||||
+ { NULL, 0, 0, 0, 0, 0, 0 } |
||||
+}; |
||||
+ |
||||
/* Returns a list of supported MACs separated by the specified char. */ |
||||
char * |
||||
mac_alg_list(char sep) |
||||
@@ -99,7 +119,7 @@ mac_alg_list(char sep) |
||||
size_t nlen, rlen = 0; |
||||
const struct macalg *m; |
||||
|
||||
- for (m = macs; m->name != NULL; m++) { |
||||
+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { |
||||
if (ret != NULL) |
||||
ret[rlen++] = sep; |
||||
nlen = strlen(m->name); |
||||
@@ -133,7 +153,7 @@ mac_setup(Mac *mac, char *name) |
||||
{ |
||||
const struct macalg *m; |
||||
|
||||
- for (m = macs; m->name != NULL; m++) { |
||||
+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { |
||||
if (strcmp(name, m->name) != 0) |
||||
continue; |
||||
if (mac != NULL) { |
||||
diff -up openssh-6.6p1/myproposal.h.fips openssh-6.6p1/myproposal.h |
||||
--- openssh-6.6p1/myproposal.h.fips 2013-12-07 01:24:02.000000000 +0100 |
||||
+++ openssh-6.6p1/myproposal.h 2015-08-13 15:10:30.288271102 +0200 |
||||
@@ -88,6 +88,12 @@ |
||||
"diffie-hellman-group14-sha1," \ |
||||
"diffie-hellman-group1-sha1" |
||||
|
||||
+#define KEX_DEFAULT_KEX_FIPS \ |
||||
+ KEX_ECDH_METHODS \ |
||||
+ KEX_SHA256_METHODS \ |
||||
+ "diffie-hellman-group-exchange-sha1," \ |
||||
+ "diffie-hellman-group14-sha1" |
||||
+ |
||||
#define KEX_DEFAULT_PK_ALG \ |
||||
HOSTKEY_ECDSA_CERT_METHODS \ |
||||
"ssh-ed25519-cert-v01@openssh.com," \ |
||||
@@ -133,6 +139,22 @@ |
||||
#define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" |
||||
#define KEX_DEFAULT_LANG "" |
||||
|
||||
+#define KEX_FIPS_ENCRYPT \ |
||||
+ "aes128-ctr,aes192-ctr,aes256-ctr," \ |
||||
+ "aes128-cbc,3des-cbc," \ |
||||
+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" |
||||
+#ifdef HAVE_EVP_SHA256 |
||||
+#define KEX_FIPS_MAC \ |
||||
+ "hmac-sha1," \ |
||||
+ "hmac-sha2-256," \ |
||||
+ "hmac-sha2-512," \ |
||||
+ "hmac-sha1-etm@openssh.com," \ |
||||
+ "hmac-sha2-256-etm@openssh.com," \ |
||||
+ "hmac-sha2-512-etm@openssh.com" |
||||
+#else |
||||
+#define KEX_FIPS_MAC \ |
||||
+ "hmac-sha1" |
||||
+#endif |
||||
|
||||
static char *myproposal[PROPOSAL_MAX] = { |
||||
KEX_DEFAULT_KEX, |
||||
diff -up openssh-6.6p1/ssh-keygen.c.fips openssh-6.6p1/ssh-keygen.c |
||||
--- openssh-6.6p1/ssh-keygen.c.fips 2015-08-13 15:09:43.296350215 +0200 |
||||
+++ openssh-6.6p1/ssh-keygen.c 2015-08-13 15:09:43.360350107 +0200 |
||||
@@ -195,6 +195,12 @@ type_bits_valid(int type, u_int32_t *bit |
||||
fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); |
||||
exit(1); |
||||
} |
||||
+ if (FIPS_mode()) { |
||||
+ if (type == KEY_DSA) |
||||
+ fatal("DSA keys are not allowed in FIPS mode"); |
||||
+ if (type == KEY_ED25519) |
||||
+ fatal("ED25519 keys are not allowed in FIPS mode"); |
||||
+ } |
||||
if (type == KEY_DSA && *bitsp != 1024) |
||||
fatal("DSA keys must be 1024 bits"); |
||||
else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) |
||||
@@ -746,7 +752,7 @@ do_download(struct passwd *pw) |
||||
enum fp_type fptype; |
||||
char *fp, *ra; |
||||
|
||||
- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; |
||||
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection(); |
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; |
||||
|
||||
pkcs11_init(0); |
||||
@@ -756,8 +762,7 @@ do_download(struct passwd *pw) |
||||
for (i = 0; i < nkeys; i++) { |
||||
if (print_fingerprint) { |
||||
fp = key_fingerprint(keys[i], fptype, rep); |
||||
- ra = key_fingerprint(keys[i], SSH_FP_MD5, |
||||
- SSH_FP_RANDOMART); |
||||
+ ra = key_selected_fingerprint(keys[i], 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) |
||||
diff -up openssh-6.6p1/ssh.c.fips openssh-6.6p1/ssh.c |
||||
--- openssh-6.6p1/ssh.c.fips 2014-02-27 00:17:13.000000000 +0100 |
||||
+++ openssh-6.6p1/ssh.c 2015-08-13 15:09:43.357350112 +0200 |
||||
@@ -73,6 +73,8 @@ |
||||
|
||||
#include <openssl/evp.h> |
||||
#include <openssl/err.h> |
||||
+#include <openssl/fips.h> |
||||
+#include <fipscheck.h> |
||||
#include "openbsd-compat/openssl-compat.h" |
||||
#include "openbsd-compat/sys-queue.h" |
||||
|
||||
@@ -427,6 +429,13 @@ main(int ac, char **av) |
||||
sanitise_stdfd(); |
||||
|
||||
__progname = ssh_get_progname(av[0]); |
||||
+ SSLeay_add_all_algorithms(); |
||||
+ if (access("/etc/system-fips", F_OK) == 0) |
||||
+ if (! FIPSCHECK_verify(NULL, NULL)) |
||||
+ if (FIPS_mode()) |
||||
+ fatal("FIPS integrity verification test failed."); |
||||
+ else |
||||
+ logit("FIPS integrity verification test failed."); |
||||
|
||||
#ifndef HAVE_SETPROCTITLE |
||||
/* Prepare for later setproctitle emulation */ |
||||
@@ -504,6 +513,9 @@ main(int ac, char **av) |
||||
"ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { |
||||
switch (opt) { |
||||
case '1': |
||||
+ if (FIPS_mode()) { |
||||
+ fatal("Protocol 1 not allowed in the FIPS mode."); |
||||
+ } |
||||
options.protocol = SSH_PROTO_1; |
||||
break; |
||||
case '2': |
||||
@@ -828,7 +840,6 @@ main(int ac, char **av) |
||||
|
||||
host_arg = xstrdup(host); |
||||
|
||||
- OpenSSL_add_all_algorithms(); |
||||
ERR_load_crypto_strings(); |
||||
|
||||
/* Initialize the command to execute on remote host. */ |
||||
@@ -973,6 +984,10 @@ main(int ac, char **av) |
||||
|
||||
seed_rng(); |
||||
|
||||
+ if (FIPS_mode()) { |
||||
+ logit("FIPS mode initialized"); |
||||
+ } |
||||
+ |
||||
if (options.user == NULL) |
||||
options.user = xstrdup(pw->pw_name); |
||||
|
||||
@@ -1020,6 +1035,12 @@ main(int ac, char **av) |
||||
|
||||
timeout_ms = options.connection_timeout * 1000; |
||||
|
||||
+ if (FIPS_mode()) { |
||||
+ options.protocol &= SSH_PROTO_2; |
||||
+ if (options.protocol == 0) |
||||
+ fatal("Protocol 2 disabled by configuration but required in the FIPS mode."); |
||||
+ } |
||||
+ |
||||
/* Open a connection to the remote host. */ |
||||
if (ssh_connect(host, addrs, &hostaddr, options.port, |
||||
options.address_family, options.connection_attempts, |
||||
diff -up openssh-6.6p1/sshconnect2.c.fips openssh-6.6p1/sshconnect2.c |
||||
--- openssh-6.6p1/sshconnect2.c.fips 2015-08-13 15:09:43.342350138 +0200 |
||||
+++ openssh-6.6p1/sshconnect2.c 2015-08-13 15:09:43.357350112 +0200 |
||||
@@ -46,6 +46,8 @@ |
||||
#include <vis.h> |
||||
#endif |
||||
|
||||
+#include <openssl/fips.h> |
||||
+ |
||||
#include "openbsd-compat/sys-queue.h" |
||||
|
||||
#include "xmalloc.h" |
||||
@@ -170,21 +172,26 @@ ssh_kex2(char *host, struct sockaddr *ho |
||||
|
||||
#ifdef GSSAPI |
||||
if (options.gss_keyex) { |
||||
- /* Add the GSSAPI mechanisms currently supported on this |
||||
- * client to the key exchange algorithm proposal */ |
||||
- orig = myproposal[PROPOSAL_KEX_ALGS]; |
||||
- |
||||
- if (options.gss_trust_dns) |
||||
- gss_host = (char *)get_canonical_hostname(1); |
||||
- else |
||||
- gss_host = host; |
||||
- |
||||
- gss = ssh_gssapi_client_mechanisms(gss_host, |
||||
- options.gss_client_identity, options.gss_kex_algorithms); |
||||
- if (gss) { |
||||
- debug("Offering GSSAPI proposal: %s", gss); |
||||
- xasprintf(&myproposal[PROPOSAL_KEX_ALGS], |
||||
- "%s,%s", gss, orig); |
||||
+ if (FIPS_mode()) { |
||||
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); |
||||
+ options.gss_keyex = 0; |
||||
+ } else { |
||||
+ /* Add the GSSAPI mechanisms currently supported on this |
||||
+ * client to the key exchange algorithm proposal */ |
||||
+ orig = myproposal[PROPOSAL_KEX_ALGS]; |
||||
+ |
||||
+ if (options.gss_trust_dns) |
||||
+ gss_host = (char *)get_canonical_hostname(1); |
||||
+ else |
||||
+ gss_host = host; |
||||
+ |
||||
+ gss = ssh_gssapi_client_mechanisms(gss_host, |
||||
+ options.gss_client_identity, options.gss_kex_algorithms); |
||||
+ if (gss) { |
||||
+ debug("Offering GSSAPI proposal: %s", gss); |
||||
+ xasprintf(&myproposal[PROPOSAL_KEX_ALGS], |
||||
+ "%s,%s", gss, orig); |
||||
+ } |
||||
} |
||||
} |
||||
#endif |
||||
@@ -196,6 +203,10 @@ ssh_kex2(char *host, struct sockaddr *ho |
||||
if (options.ciphers != NULL) { |
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; |
||||
+ } else if (FIPS_mode()) { |
||||
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
||||
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; |
||||
+ |
||||
} |
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
||||
compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); |
||||
@@ -211,7 +222,11 @@ ssh_kex2(char *host, struct sockaddr *ho |
||||
if (options.macs != NULL) { |
||||
myproposal[PROPOSAL_MAC_ALGS_CTOS] = |
||||
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; |
||||
+ } else if (FIPS_mode()) { |
||||
+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = |
||||
+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; |
||||
} |
||||
+ |
||||
if (options.hostkeyalgorithms != NULL) |
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = |
||||
compat_pkalg_proposal(options.hostkeyalgorithms); |
||||
@@ -223,9 +238,11 @@ ssh_kex2(char *host, struct sockaddr *ho |
||||
} |
||||
if (options.kex_algorithms != NULL) |
||||
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; |
||||
+ else if (FIPS_mode()) |
||||
+ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; |
||||
+ |
||||
myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( |
||||
myproposal[PROPOSAL_KEX_ALGS]); |
||||
- |
||||
#ifdef GSSAPI |
||||
/* If we've got GSSAPI algorithms, then we also support the |
||||
* 'null' hostkey, as a last resort */ |
||||
diff -up openssh-6.6p1/sshd.c.fips openssh-6.6p1/sshd.c |
||||
--- openssh-6.6p1/sshd.c.fips 2015-08-13 15:09:43.352350121 +0200 |
||||
+++ openssh-6.6p1/sshd.c 2015-08-13 15:09:43.359350109 +0200 |
||||
@@ -75,6 +75,8 @@ |
||||
#include <openssl/dh.h> |
||||
#include <openssl/bn.h> |
||||
#include <openssl/rand.h> |
||||
+#include <openssl/fips.h> |
||||
+#include <fipscheck.h> |
||||
#include "openbsd-compat/openssl-compat.h" |
||||
|
||||
#ifdef HAVE_SECUREWARE |
||||
@@ -1473,6 +1475,18 @@ main(int ac, char **av) |
||||
#endif |
||||
__progname = ssh_get_progname(av[0]); |
||||
|
||||
+ SSLeay_add_all_algorithms(); |
||||
+ if (access("/etc/system-fips", F_OK) == 0) |
||||
+ if (! FIPSCHECK_verify(NULL, NULL)) { |
||||
+ openlog(__progname, LOG_PID, LOG_AUTHPRIV); |
||||
+ if (FIPS_mode()) { |
||||
+ syslog(LOG_CRIT, "FIPS integrity verification test failed."); |
||||
+ cleanup_exit(255); |
||||
+ } |
||||
+ else |
||||
+ syslog(LOG_INFO, "FIPS integrity verification test failed."); |
||||
+ closelog(); |
||||
+ } |
||||
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ |
||||
saved_argc = ac; |
||||
rexec_argc = ac; |
||||
@@ -1624,8 +1638,6 @@ main(int ac, char **av) |
||||
else |
||||
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); |
||||
|
||||
- OpenSSL_add_all_algorithms(); |
||||
- |
||||
/* If requested, redirect the logs to the specified logfile. */ |
||||
if (logfile != NULL) { |
||||
log_redirect_stderr_to(logfile); |
||||
@@ -1803,6 +1815,10 @@ main(int ac, char **av) |
||||
debug("private host key: #%d type %d %s", i, keytype, |
||||
key_type(key ? key : pubkey)); |
||||
} |
||||
+ if ((options.protocol & SSH_PROTO_1) && FIPS_mode()) { |
||||
+ logit("Disabling protocol version 1. Not allowed in the FIPS mode."); |
||||
+ options.protocol &= ~SSH_PROTO_1; |
||||
+ } |
||||
if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { |
||||
logit("Disabling protocol version 1. Could not load host key"); |
||||
options.protocol &= ~SSH_PROTO_1; |
||||
@@ -1966,6 +1982,10 @@ main(int ac, char **av) |
||||
/* Reinitialize the log (because of the fork above). */ |
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr); |
||||
|
||||
+ if (FIPS_mode()) { |
||||
+ logit("FIPS mode initialized"); |
||||
+ } |
||||
+ |
||||
/* Chdir to the root directory so that the current disk can be |
||||
unmounted if desired. */ |
||||
if (chdir("/") == -1) |
||||
@@ -2537,6 +2557,9 @@ do_ssh2_kex(void) |
||||
if (options.ciphers != NULL) { |
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; |
||||
+ } else if (FIPS_mode()) { |
||||
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
||||
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; |
||||
} |
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
||||
compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); |
||||
@@ -2546,6 +2569,9 @@ do_ssh2_kex(void) |
||||
if (options.macs != NULL) { |
||||
myproposal[PROPOSAL_MAC_ALGS_CTOS] = |
||||
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; |
||||
+ } else if (FIPS_mode()) { |
||||
+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = |
||||
+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; |
||||
} |
||||
if (options.compression == COMP_NONE) { |
||||
myproposal[PROPOSAL_COMP_ALGS_CTOS] = |
||||
@@ -2556,6 +2582,8 @@ do_ssh2_kex(void) |
||||
} |
||||
if (options.kex_algorithms != NULL) |
||||
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; |
||||
+ else if (FIPS_mode()) |
||||
+ myproposal[PROPOSAL_KEX_ALGS] = KEX_DEFAULT_KEX_FIPS; |
||||
|
||||
myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( |
||||
myproposal[PROPOSAL_KEX_ALGS]); |
||||
@@ -2582,10 +2610,14 @@ do_ssh2_kex(void) |
||||
if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) |
||||
orig = NULL; |
||||
|
||||
- if (options.gss_keyex) |
||||
- gss = ssh_gssapi_server_mechanisms(); |
||||
- else |
||||
- gss = NULL; |
||||
+ if (options.gss_keyex) { |
||||
+ if (FIPS_mode()) { |
||||
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); |
||||
+ options.gss_keyex = 0; |
||||
+ } else { |
||||
+ gss = ssh_gssapi_server_mechanisms(); |
||||
+ } |
||||
+ } |
||||
|
||||
if (gss && orig) |
||||
xasprintf(&newstr, "%s,%s", gss, orig); |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id |
||||
index 8e1091c..4bba5d6 100644 |
||||
--- a/contrib/ssh-copy-id |
||||
+++ b/contrib/ssh-copy-id |
||||
@@ -274,9 +274,7 @@ case "$REMOTE_VERSION" in |
||||
populate_new_ids 0 |
||||
fi |
||||
[ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " |
||||
- umask 077 ; |
||||
+ exec sh -c 'umask 077; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1; if type restorecon >/dev/null 2>&1; then restorecon -F .ssh .ssh/authorized_keys; fi'" \ |
||||
- mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; |
||||
- if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \ |
||||
|| exit 1 |
||||
ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) |
||||
;; |
@ -0,0 +1,278 @@
@@ -0,0 +1,278 @@
|
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c |
||||
index 42de994..60de320 100644 |
||||
--- a/gss-serv-krb5.c |
||||
+++ b/gss-serv-krb5.c |
||||
@@ -32,7 +32,9 @@ |
||||
#include <sys/types.h> |
||||
|
||||
#include <stdarg.h> |
||||
+#include <stdio.h> |
||||
#include <string.h> |
||||
+#include <unistd.h> |
||||
|
||||
#include "xmalloc.h" |
||||
#include "key.h" |
||||
@@ -40,6 +42,7 @@ |
||||
#include "buffer.h" |
||||
#include "ssh-gss.h" |
||||
|
||||
+extern Authctxt *the_authctxt; |
||||
extern ServerOptions options; |
||||
|
||||
#ifdef HEIMDAL |
||||
@@ -55,6 +59,13 @@ extern ServerOptions options; |
||||
# include <gssapi/gssapi_krb5.h> |
||||
#endif |
||||
|
||||
+/* all commands are allowed by default */ |
||||
+char **k5users_allowed_cmds = NULL; |
||||
+ |
||||
+static int ssh_gssapi_k5login_exists(); |
||||
+static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, |
||||
+ int); |
||||
+ |
||||
static krb5_context krb_context = NULL; |
||||
|
||||
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */ |
||||
@@ -87,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) |
||||
krb5_principal princ; |
||||
int retval; |
||||
const char *errmsg; |
||||
+ int k5login_exists; |
||||
|
||||
if (ssh_gssapi_krb5_init() == 0) |
||||
return 0; |
||||
@@ -98,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) |
||||
krb5_free_error_message(krb_context, errmsg); |
||||
return 0; |
||||
} |
||||
- if (krb5_kuserok(krb_context, princ, name)) { |
||||
+ /* krb5_kuserok() returns 1 if .k5login DNE and this is self-login. |
||||
+ * We have to make sure to check .k5users in that case. */ |
||||
+ k5login_exists = ssh_gssapi_k5login_exists(); |
||||
+ /* NOTE: .k5login and .k5users must opened as root, not the user, |
||||
+ * because if they are on a krb5-protected filesystem, user credentials |
||||
+ * to access these files aren't available yet. */ |
||||
+ if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { |
||||
retval = 1; |
||||
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", |
||||
name, (char *)client->displayname.value); |
||||
+ } else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value, |
||||
+ name, k5login_exists)) { |
||||
+ retval = 1; |
||||
+ logit("Authorized to %s, krb5 principal %s " |
||||
+ "(ssh_gssapi_krb5_cmdok)", |
||||
+ name, (char *)client->displayname.value); |
||||
} else |
||||
retval = 0; |
||||
|
||||
@@ -109,6 +133,135 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) |
||||
return retval; |
||||
} |
||||
|
||||
+/* Test for existence of .k5login. |
||||
+ * We need this as part of our .k5users check, because krb5_kuserok() |
||||
+ * returns success if .k5login DNE and user is logging in as himself. |
||||
+ * With .k5login absent and .k5users present, we don't want absence |
||||
+ * of .k5login to authorize self-login. (absence of both is required) |
||||
+ * Returns 1 if .k5login is available, 0 otherwise. |
||||
+ */ |
||||
+static int |
||||
+ssh_gssapi_k5login_exists() |
||||
+{ |
||||
+ char file[MAXPATHLEN]; |
||||
+ struct passwd *pw = the_authctxt->pw; |
||||
+ |
||||
+ snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); |
||||
+ return access(file, F_OK) == 0; |
||||
+} |
||||
+ |
||||
+/* check .k5users for login or command authorization |
||||
+ * Returns 1 if principal is authorized, 0 otherwise. |
||||
+ * If principal is authorized, (global) k5users_allowed_cmds may be populated. |
||||
+ */ |
||||
+static int |
||||
+ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, |
||||
+ const char *luser, int k5login_exists) |
||||
+{ |
||||
+ FILE *fp; |
||||
+ char file[MAXPATHLEN]; |
||||
+ char line[BUFSIZ]; |
||||
+ char kuser[65]; /* match krb5_kuserok() */ |
||||
+ struct stat st; |
||||
+ struct passwd *pw = the_authctxt->pw; |
||||
+ int found_principal = 0; |
||||
+ int ncommands = 0, allcommands = 0; |
||||
+ u_long linenum; |
||||
+ |
||||
+ snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); |
||||
+ /* If both .k5login and .k5users DNE, self-login is ok. */ |
||||
+ if (!k5login_exists && (access(file, F_OK) == -1)) { |
||||
+ return (krb5_aname_to_localname(krb_context, principal, |
||||
+ sizeof(kuser), kuser) == 0) && |
||||
+ (strcmp(kuser, luser) == 0); |
||||
+ } |
||||
+ if ((fp = fopen(file, "r")) == NULL) { |
||||
+ int saved_errno = errno; |
||||
+ /* 2nd access check to ease debugging if file perms are wrong. |
||||
+ * But we don't want to report this if .k5users simply DNE. */ |
||||
+ if (access(file, F_OK) == 0) { |
||||
+ logit("User %s fopen %s failed: %s", |
||||
+ pw->pw_name, file, strerror(saved_errno)); |
||||
+ } |
||||
+ return 0; |
||||
+ } |
||||
+ /* .k5users must be owned either by the user or by root */ |
||||
+ if (fstat(fileno(fp), &st) == -1) { |
||||
+ /* can happen, but very wierd error so report it */ |
||||
+ logit("User %s fstat %s failed: %s", |
||||
+ pw->pw_name, file, strerror(errno)); |
||||
+ fclose(fp); |
||||
+ return 0; |
||||
+ } |
||||
+ if (!(st.st_uid == pw->pw_uid || st.st_uid == 0)) { |
||||
+ logit("User %s %s is not owned by root or user", |
||||
+ pw->pw_name, file); |
||||
+ fclose(fp); |
||||
+ return 0; |
||||
+ } |
||||
+ /* .k5users must be a regular file. krb5_kuserok() doesn't do this |
||||
+ * check, but we don't want to be deficient if they add a check. */ |
||||
+ if (!S_ISREG(st.st_mode)) { |
||||
+ logit("User %s %s is not a regular file", pw->pw_name, file); |
||||
+ fclose(fp); |
||||
+ return 0; |
||||
+ } |
||||
+ /* file exists; initialize k5users_allowed_cmds (to none!) */ |
||||
+ k5users_allowed_cmds = xcalloc(++ncommands, |
||||
+ sizeof(*k5users_allowed_cmds)); |
||||
+ |
||||
+ /* Check each line. ksu allows unlimited length lines. We don't. */ |
||||
+ while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line), |
||||
+ &linenum) != -1) { |
||||
+ char *token; |
||||
+ |
||||
+ /* we parse just like ksu, even though we could do better */ |
||||
+ if ((token = strtok(line, " \t\n")) == NULL) |
||||
+ continue; |
||||
+ if (strcmp(name, token) == 0) { |
||||
+ /* we matched on client principal */ |
||||
+ found_principal = 1; |
||||
+ if ((token = strtok(NULL, " \t\n")) == NULL) { |
||||
+ /* only shell is allowed */ |
||||
+ k5users_allowed_cmds[ncommands-1] = |
||||
+ xstrdup(pw->pw_shell); |
||||
+ k5users_allowed_cmds = |
||||
+ xreallocarray(k5users_allowed_cmds, ++ncommands, |
||||
+ sizeof(*k5users_allowed_cmds)); |
||||
+ break; |
||||
+ } |
||||
+ /* process the allowed commands */ |
||||
+ while (token) { |
||||
+ if (strcmp(token, "*") == 0) { |
||||
+ allcommands = 1; |
||||
+ break; |
||||
+ } |
||||
+ k5users_allowed_cmds[ncommands-1] = |
||||
+ xstrdup(token); |
||||
+ k5users_allowed_cmds = |
||||
+ xreallocarray(k5users_allowed_cmds, ++ncommands, |
||||
+ sizeof(*k5users_allowed_cmds)); |
||||
+ token = strtok(NULL, " \t\n"); |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ if (k5users_allowed_cmds) { |
||||
+ /* terminate vector */ |
||||
+ k5users_allowed_cmds[ncommands-1] = NULL; |
||||
+ /* if all commands are allowed, free vector */ |
||||
+ if (allcommands) { |
||||
+ int i; |
||||
+ for (i = 0; i < ncommands; i++) { |
||||
+ free(k5users_allowed_cmds[i]); |
||||
+ } |
||||
+ free(k5users_allowed_cmds); |
||||
+ k5users_allowed_cmds = NULL; |
||||
+ } |
||||
+ } |
||||
+ fclose(fp); |
||||
+ return found_principal; |
||||
+} |
||||
+ |
||||
|
||||
/* This writes out any forwarded credentials from the structure populated |
||||
* during userauth. Called after we have setuid to the user */ |
||||
diff --git a/session.c b/session.c |
||||
index b5dc144..ba4589b 100644 |
||||
--- a/session.c |
||||
+++ b/session.c |
||||
@@ -806,6 +806,29 @@ do_exec(Session *s, const char *command) |
||||
command = forced_command; |
||||
forced = "(key-option)"; |
||||
} |
||||
+#ifdef GSSAPI |
||||
+#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */ |
||||
+ else if (k5users_allowed_cmds) { |
||||
+ const char *match = command; |
||||
+ int allowed = 0, i = 0; |
||||
+ |
||||
+ if (!match) |
||||
+ match = s->pw->pw_shell; |
||||
+ while (k5users_allowed_cmds[i]) { |
||||
+ if (strcmp(match, k5users_allowed_cmds[i++]) == 0) { |
||||
+ debug("Allowed command '%.900s'", match); |
||||
+ allowed = 1; |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ if (!allowed) { |
||||
+ debug("command '%.900s' not allowed", match); |
||||
+ return 1; |
||||
+ } |
||||
+ } |
||||
+#endif |
||||
+#endif |
||||
+ |
||||
if (forced != NULL) { |
||||
if (IS_INTERNAL_SFTP(command)) { |
||||
s->is_subsystem = s->is_subsystem ? |
||||
diff --git a/ssh-gss.h b/ssh-gss.h |
||||
index 0374c88..509109a 100644 |
||||
--- a/ssh-gss.h |
||||
+++ b/ssh-gss.h |
||||
@@ -49,6 +49,10 @@ |
||||
# endif /* !HAVE_DECL_GSS_C_NT_... */ |
||||
|
||||
# endif /* !HEIMDAL */ |
||||
+ |
||||
+/* .k5users support */ |
||||
+extern char **k5users_allowed_cmds; |
||||
+ |
||||
#endif /* KRB5 */ |
||||
|
||||
/* draft-ietf-secsh-gsskeyex-06 */ |
||||
diff --git a/sshd.8 b/sshd.8 |
||||
index 058d37a..5c4f15b 100644 |
||||
--- a/sshd.8 |
||||
+++ b/sshd.8 |
||||
@@ -327,6 +327,7 @@ Finally, the server and the client enter an authentication dialog. |
||||
The client tries to authenticate itself using |
||||
host-based authentication, |
||||
public key authentication, |
||||
+GSSAPI authentication, |
||||
challenge-response authentication, |
||||
or password authentication. |
||||
.Pp |
||||
@@ -800,6 +801,12 @@ This file is used in exactly the same way as |
||||
but allows host-based authentication without permitting login with |
||||
rlogin/rsh. |
||||
.Pp |
||||
+.It Pa ~/.k5login |
||||
+.It Pa ~/.k5users |
||||
+These files enforce GSSAPI/Kerberos authentication access control. |
||||
+Further details are described in |
||||
+.Xr ksu 1 . |
||||
+.Pp |
||||
.It Pa ~/.ssh/ |
||||
This directory is the default location for all user-specific configuration |
||||
and authentication information. |
@ -0,0 +1,398 @@
@@ -0,0 +1,398 @@
|
||||
diff -up openssh-6.6p1/gss-genr.c.gsskexalg openssh-6.6p1/gss-genr.c |
||||
--- openssh-6.6p1/gss-genr.c.gsskexalg 2015-08-14 16:07:33.271343064 +0200 |
||||
+++ openssh-6.6p1/gss-genr.c 2015-08-14 16:07:33.338342936 +0200 |
||||
@@ -76,7 +76,8 @@ ssh_gssapi_oid_table_ok() { |
||||
*/ |
||||
|
||||
char * |
||||
-ssh_gssapi_client_mechanisms(const char *host, const char *client) { |
||||
+ssh_gssapi_client_mechanisms(const char *host, const char *client, |
||||
+ const char *kex) { |
||||
gss_OID_set gss_supported; |
||||
OM_uint32 min_status; |
||||
|
||||
@@ -84,12 +85,12 @@ ssh_gssapi_client_mechanisms(const char |
||||
return NULL; |
||||
|
||||
return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, |
||||
- host, client)); |
||||
+ host, client, kex)); |
||||
} |
||||
|
||||
char * |
||||
ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, |
||||
- const char *host, const char *client) { |
||||
+ const char *host, const char *client, const char *kex) { |
||||
Buffer buf; |
||||
size_t i; |
||||
int oidpos, enclen; |
||||
@@ -98,6 +99,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
||||
char deroid[2]; |
||||
const EVP_MD *evp_md = EVP_md5(); |
||||
EVP_MD_CTX md; |
||||
+ char *s, *cp, *p; |
||||
|
||||
if (gss_enc2oid != NULL) { |
||||
for (i = 0; gss_enc2oid[i].encoded != NULL; i++) |
||||
@@ -111,6 +113,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
||||
buffer_init(&buf); |
||||
|
||||
oidpos = 0; |
||||
+ s = cp = xstrdup(kex); |
||||
for (i = 0; i < gss_supported->count; i++) { |
||||
if (gss_supported->elements[i].length < 128 && |
||||
(*check)(NULL, &(gss_supported->elements[i]), host, client)) { |
||||
@@ -129,26 +132,22 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
||||
enclen = __b64_ntop(digest, EVP_MD_size(evp_md), |
||||
encoded, EVP_MD_size(evp_md) * 2); |
||||
|
||||
- if (oidpos != 0) |
||||
- buffer_put_char(&buf, ','); |
||||
- |
||||
- buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, |
||||
- sizeof(KEX_GSS_GEX_SHA1_ID) - 1); |
||||
- buffer_append(&buf, encoded, enclen); |
||||
- buffer_put_char(&buf, ','); |
||||
- buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, |
||||
- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); |
||||
- buffer_append(&buf, encoded, enclen); |
||||
- buffer_put_char(&buf, ','); |
||||
- buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, |
||||
- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); |
||||
- buffer_append(&buf, encoded, enclen); |
||||
+ cp = strncpy(s, kex, strlen(kex)); |
||||
+ for ((p = strsep(&cp, ",")); p && *p != '\0'; |
||||
+ (p = strsep(&cp, ","))) { |
||||
+ if (buffer_len(&buf) != 0) |
||||
+ buffer_put_char(&buf, ','); |
||||
+ buffer_append(&buf, p, |
||||
+ strlen(p)); |
||||
+ buffer_append(&buf, encoded, enclen); |
||||
+ } |
||||
|
||||
gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); |
||||
gss_enc2oid[oidpos].encoded = encoded; |
||||
oidpos++; |
||||
} |
||||
} |
||||
+ free(s); |
||||
gss_enc2oid[oidpos].oid = NULL; |
||||
gss_enc2oid[oidpos].encoded = NULL; |
||||
|
||||
diff -up openssh-6.6p1/gss-serv.c.gsskexalg openssh-6.6p1/gss-serv.c |
||||
--- openssh-6.6p1/gss-serv.c.gsskexalg 2015-08-14 16:07:33.296343016 +0200 |
||||
+++ openssh-6.6p1/gss-serv.c 2015-08-14 16:07:33.338342936 +0200 |
||||
@@ -151,7 +151,7 @@ ssh_gssapi_server_mechanisms() { |
||||
|
||||
ssh_gssapi_supported_oids(&supported); |
||||
return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, |
||||
- NULL, NULL)); |
||||
+ NULL, NULL, options.gss_kex_algorithms)); |
||||
} |
||||
|
||||
/* Unprivileged */ |
||||
diff -up openssh-6.6p1/kex.c.gsskexalg openssh-6.6p1/kex.c |
||||
--- openssh-6.6p1/kex.c.gsskexalg 2015-08-14 16:07:33.271343064 +0200 |
||||
+++ openssh-6.6p1/kex.c 2015-08-14 16:07:33.339342935 +0200 |
||||
@@ -160,6 +160,29 @@ kex_names_valid(const char *names) |
||||
return 1; |
||||
} |
||||
|
||||
+/* Validate GSS KEX method name list */ |
||||
+int |
||||
+gss_kex_names_valid(const char *names) |
||||
+{ |
||||
+ char *s, *cp, *p; |
||||
+ |
||||
+ if (names == NULL || *names == '\0') |
||||
+ return 0; |
||||
+ s = cp = xstrdup(names); |
||||
+ for ((p = strsep(&cp, ",")); p && *p != '\0'; |
||||
+ (p = strsep(&cp, ","))) { |
||||
+ if (strncmp(p, "gss-", 4) != 0 |
||||
+ || kex_alg_by_name(p) == NULL) { |
||||
+ error("Unsupported KEX algorithm \"%.100s\"", p); |
||||
+ free(s); |
||||
+ return 0; |
||||
+ } |
||||
+ } |
||||
+ debug3("gss kex names ok: [%s]", names); |
||||
+ free(s); |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
/* put algorithm proposal into buffer */ |
||||
static void |
||||
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) |
||||
diff -up openssh-6.6p1/readconf.c.gsskexalg openssh-6.6p1/readconf.c |
||||
--- openssh-6.6p1/readconf.c.gsskexalg 2015-08-14 16:07:33.274343058 +0200 |
||||
+++ openssh-6.6p1/readconf.c 2015-08-14 16:14:17.600574919 +0200 |
||||
@@ -55,6 +55,7 @@ |
||||
#include "kex.h" |
||||
#include "mac.h" |
||||
#include "uidswap.h" |
||||
+#include "ssh-gss.h" |
||||
|
||||
/* Format of the configuration file: |
||||
|
||||
@@ -142,7 +143,7 @@ typedef enum { |
||||
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, |
||||
oAddressFamily, oGssAuthentication, oGssDelegateCreds, |
||||
oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, |
||||
- oGssServerIdentity, |
||||
+ oGssServerIdentity, oGssKexAlgorithms, |
||||
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, |
||||
oSendEnv, oControlPath, oControlMaster, oControlPersist, |
||||
oHashKnownHosts, |
||||
@@ -191,6 +192,7 @@ static struct { |
||||
{ "gssapiclientidentity", oGssClientIdentity }, |
||||
{ "gssapiserveridentity", oGssServerIdentity }, |
||||
{ "gssapirenewalforcesrekey", oGssRenewalRekey }, |
||||
+ { "gssapikexalgorithms", oGssKexAlgorithms }, |
||||
#else |
||||
{ "gssapiauthentication", oUnsupported }, |
||||
{ "gssapikeyexchange", oUnsupported }, |
||||
@@ -198,6 +200,7 @@ static struct { |
||||
{ "gssapitrustdns", oUnsupported }, |
||||
{ "gssapiclientidentity", oUnsupported }, |
||||
{ "gssapirenewalforcesrekey", oUnsupported }, |
||||
+ { "gssapikexalgorithms", oUnsupported }, |
||||
#endif |
||||
{ "fallbacktorsh", oDeprecated }, |
||||
{ "usersh", oDeprecated }, |
||||
@@ -876,6 +879,18 @@ parse_time: |
||||
intptr = &options->gss_renewal_rekey; |
||||
goto parse_flag; |
||||
|
||||
+ case oGssKexAlgorithms: |
||||
+ arg = strdelim(&s); |
||||
+ if (!arg || *arg == '\0') |
||||
+ fatal("%.200s line %d: Missing argument.", |
||||
+ filename, linenum); |
||||
+ if (!gss_kex_names_valid(arg)) |
||||
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", |
||||
+ filename, linenum, arg ? arg : "<NONE>"); |
||||
+ if (*activep && options->gss_kex_algorithms == NULL) |
||||
+ options->gss_kex_algorithms = xstrdup(arg); |
||||
+ break; |
||||
+ |
||||
case oBatchMode: |
||||
intptr = &options->batch_mode; |
||||
goto parse_flag; |
||||
@@ -1534,6 +1549,7 @@ initialize_options(Options * options) |
||||
options->gss_renewal_rekey = -1; |
||||
options->gss_client_identity = NULL; |
||||
options->gss_server_identity = NULL; |
||||
+ options->gss_kex_algorithms = NULL; |
||||
options->password_authentication = -1; |
||||
options->kbd_interactive_authentication = -1; |
||||
options->kbd_interactive_devices = NULL; |
||||
@@ -1660,6 +1676,8 @@ fill_default_options(Options * options) |
||||
options->gss_trust_dns = 0; |
||||
if (options->gss_renewal_rekey == -1) |
||||
options->gss_renewal_rekey = 0; |
||||
+ if (options->gss_kex_algorithms == NULL) |
||||
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); |
||||
if (options->password_authentication == -1) |
||||
options->password_authentication = 1; |
||||
if (options->kbd_interactive_authentication == -1) |
||||
diff -up openssh-6.6p1/readconf.h.gsskexalg openssh-6.6p1/readconf.h |
||||
--- openssh-6.6p1/readconf.h.gsskexalg 2015-08-14 16:07:33.274343058 +0200 |
||||
+++ openssh-6.6p1/readconf.h 2015-08-14 16:07:33.339342935 +0200 |
||||
@@ -60,6 +60,7 @@ typedef struct { |
||||
int gss_renewal_rekey; /* Credential renewal forces rekey */ |
||||
char *gss_client_identity; /* Principal to initiate GSSAPI with */ |
||||
char *gss_server_identity; /* GSSAPI target principal */ |
||||
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ |
||||
int password_authentication; /* Try password |
||||
* authentication. */ |
||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ |
||||
diff -up openssh-6.6p1/servconf.c.gsskexalg openssh-6.6p1/servconf.c |
||||
--- openssh-6.6p1/servconf.c.gsskexalg 2015-08-14 16:07:45.704319443 +0200 |
||||
+++ openssh-6.6p1/servconf.c 2015-08-14 16:14:15.306579277 +0200 |
||||
@@ -54,6 +54,7 @@ |
||||
#include "packet.h" |
||||
#include "hostfile.h" |
||||
#include "auth.h" |
||||
+#include "ssh-gss.h" |
||||
|
||||
static void add_listen_addr(ServerOptions *, char *, int); |
||||
static void add_one_listen_addr(ServerOptions *, char *, int); |
||||
@@ -112,6 +113,7 @@ initialize_server_options(ServerOptions |
||||
options->gss_cleanup_creds = -1; |
||||
options->gss_strict_acceptor = -1; |
||||
options->gss_store_rekey = -1; |
||||
+ options->gss_kex_algorithms = NULL; |
||||
options->password_authentication = -1; |
||||
options->kbd_interactive_authentication = -1; |
||||
options->challenge_response_authentication = -1; |
||||
@@ -258,6 +260,8 @@ fill_default_server_options(ServerOption |
||||
options->gss_strict_acceptor = 1; |
||||
if (options->gss_store_rekey == -1) |
||||
options->gss_store_rekey = 0; |
||||
+ if (options->gss_kex_algorithms == NULL) |
||||
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); |
||||
if (options->password_authentication == -1) |
||||
options->password_authentication = 1; |
||||
if (options->kbd_interactive_authentication == -1) |
||||
@@ -360,7 +364,7 @@ typedef enum { |
||||
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, |
||||
sClientAliveCountMax, sAuthorizedKeysFile, |
||||
sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, |
||||
- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, |
||||
+ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, |
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
||||
sUsePrivilegeSeparation, sAllowAgentForwarding, |
||||
sHostCertificate, |
||||
@@ -434,6 +438,7 @@ static struct { |
||||
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, |
||||
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, |
||||
{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, |
||||
+ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, |
||||
#else |
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL }, |
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, |
||||
@@ -442,6 +447,7 @@ static struct { |
||||
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapienablek5users", sUnsupported, SSHCFG_ALL }, |
||||
+ { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, |
||||
#endif |
||||
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, |
||||
@@ -1137,6 +1143,18 @@ process_server_config_line(ServerOptions |
||||
intptr = &options->gss_store_rekey; |
||||
goto parse_flag; |
||||
|
||||
+ case sGssKexAlgorithms: |
||||
+ arg = strdelim(&cp); |
||||
+ if (!arg || *arg == '\0') |
||||
+ fatal("%.200s line %d: Missing argument.", |
||||
+ filename, linenum); |
||||
+ if (!gss_kex_names_valid(arg)) |
||||
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", |
||||
+ filename, linenum, arg ? arg : "<NONE>"); |
||||
+ if (*activep && options->gss_kex_algorithms == NULL) |
||||
+ options->gss_kex_algorithms = xstrdup(arg); |
||||
+ break; |
||||
+ |
||||
case sPasswordAuthentication: |
||||
intptr = &options->password_authentication; |
||||
goto parse_flag; |
||||
@@ -2068,6 +2086,7 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); |
||||
dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); |
||||
dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); |
||||
+ dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); |
||||
#endif |
||||
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); |
||||
dump_cfg_fmtint(sKbdInteractiveAuthentication, |
||||
diff -up openssh-6.6p1/servconf.h.gsskexalg openssh-6.6p1/servconf.h |
||||
--- openssh-6.6p1/servconf.h.gsskexalg 2015-08-14 16:07:48.160314777 +0200 |
||||
+++ openssh-6.6p1/servconf.h 2015-08-14 16:09:34.447112854 +0200 |
||||
@@ -116,6 +116,7 @@ typedef struct { |
||||
int gss_cleanup_creds; /* If true, destroy cred cache on logout */ |
||||
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ |
||||
int gss_store_rekey; |
||||
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ |
||||
int password_authentication; /* If true, permit password |
||||
* authentication. */ |
||||
int kbd_interactive_authentication; /* If true, permit */ |
||||
diff -up openssh-6.6p1/sshconnect2.c.gsskexalg openssh-6.6p1/sshconnect2.c |
||||
--- openssh-6.6p1/sshconnect2.c.gsskexalg 2015-08-14 16:07:33.304343001 +0200 |
||||
+++ openssh-6.6p1/sshconnect2.c 2015-08-14 16:07:33.339342935 +0200 |
||||
@@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho |
||||
else |
||||
gss_host = host; |
||||
|
||||
- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); |
||||
+ gss = ssh_gssapi_client_mechanisms(gss_host, |
||||
+ options.gss_client_identity, options.gss_kex_algorithms); |
||||
if (gss) { |
||||
debug("Offering GSSAPI proposal: %s", gss); |
||||
xasprintf(&myproposal[PROPOSAL_KEX_ALGS], |
||||
diff -up openssh-6.6p1/ssh-gss.h.gsskexalg openssh-6.6p1/ssh-gss.h |
||||
--- openssh-6.6p1/ssh-gss.h.gsskexalg 2015-08-14 16:07:33.278343050 +0200 |
||||
+++ openssh-6.6p1/ssh-gss.h 2015-08-14 16:07:33.340342932 +0200 |
||||
@@ -76,6 +76,11 @@ extern char **k5users_allowed_cmds; |
||||
#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" |
||||
#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" |
||||
|
||||
+#define GSS_KEX_DEFAULT_KEX \ |
||||
+ KEX_GSS_GEX_SHA1_ID "," \ |
||||
+ KEX_GSS_GRP1_SHA1_ID "," \ |
||||
+ KEX_GSS_GRP14_SHA1_ID |
||||
+ |
||||
typedef struct { |
||||
char *filename; |
||||
char *envvar; |
||||
@@ -147,9 +152,9 @@ int ssh_gssapi_credentials_updated(Gssct |
||||
/* In the server */ |
||||
typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, |
||||
const char *); |
||||
-char *ssh_gssapi_client_mechanisms(const char *, const char *); |
||||
+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); |
||||
char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, |
||||
- const char *); |
||||
+ const char *, const char *); |
||||
gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); |
||||
int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, |
||||
const char *); |
||||
diff --git a/ssh.1 b/ssh.1 |
||||
index 4a7d1cd..c795c40 100644 |
||||
--- a/ssh.1 |
||||
+++ b/ssh.1 |
||||
@@ -449,6 +449,7 @@ For full details of the options listed below, and their possible values, see |
||||
.It GSSAPIDelegateCredentials |
||||
.It GSSAPIRenewalForcesRekey |
||||
.It GSSAPITrustDns |
||||
+.It GSSAPIKexAlgorithms |
||||
.It HashKnownHosts |
||||
.It Host |
||||
.It HostbasedAuthentication |
||||
diff --git a/ssh_config.5 b/ssh_config.5 |
||||
index c95fda6..a2af9c4 100644 |
||||
--- a/ssh_config.5 |
||||
+++ b/ssh_config.5 |
||||
@@ -719,6 +719,18 @@ command line will be passed untouched to the GSSAPI library. |
||||
The default is |
||||
.Dq no . |
||||
This option only applies to protocol version 2 connections using GSSAPI. |
||||
+.It Cm GSSAPIKexAlgorithms |
||||
+The list of key exchange algorithms that are offered for GSSAPI |
||||
+key exchange. Possible values are |
||||
+.Bd -literal -offset 3n |
||||
+gss-gex-sha1-, |
||||
+gss-group1-sha1-, |
||||
+gss-group14-sha1- |
||||
+.Ed |
||||
+.Pp |
||||
+The default is |
||||
+.Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- . |
||||
+This option only applies to protocol version 2 connections using GSSAPI. |
||||
.It Cm HashKnownHosts |
||||
Indicates that |
||||
.Xr ssh 1 |
||||
diff --git a/sshd_config.5 b/sshd_config.5 |
||||
index 5e8c6c6..4c670aa 100644 |
||||
--- a/sshd_config.5 |
||||
+++ b/sshd_config.5 |
||||
@@ -545,6 +545,18 @@ Controls whether the user's GSSAPI credentials should be updated following a |
||||
successful connection rekeying. This option can be used to accepted renewed |
||||
or updated credentials from a compatible client. The default is |
||||
.Dq no . |
||||
+.It Cm GSSAPIKexAlgorithms |
||||
+The list of key exchange algorithms that are accepted by GSSAPI |
||||
+key exchange. Possible values are |
||||
+.Bd -literal -offset 3n |
||||
+gss-gex-sha1-, |
||||
+gss-group1-sha1-, |
||||
+gss-group14-sha1- |
||||
+.Ed |
||||
+.Pp |
||||
+The default is |
||||
+.Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- . |
||||
+This option only applies to protocol version 2 connections using GSSAPI. |
||||
.It Cm HostbasedAuthentication |
||||
Specifies whether rhosts or /etc/hosts.equiv authentication together |
||||
with successful public key client host authentication is allowed |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
diff --git a/auth-krb5.c b/auth-krb5.c |
||||
index 2b02a04..19b9364 100644 |
||||
--- a/auth-krb5.c |
||||
+++ b/auth-krb5.c |
||||
@@ -375,6 +375,22 @@ cleanup: |
||||
return -1; |
||||
} |
||||
|
||||
+/* |
||||
+ * Reads k5login_directory option from the krb5.conf |
||||
+ */ |
||||
+krb5_error_code |
||||
+ssh_krb5_get_k5login_directory(krb5_context ctx, char **k5login_directory) { |
||||
+ profile_t p; |
||||
+ int ret = 0; |
||||
+ |
||||
+ ret = krb5_get_profile(ctx, &p); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
+ return profile_get_string(p, "libdefaults", "k5login_directory", NULL, NULL, |
||||
+ k5login_directory); |
||||
+} |
||||
+ |
||||
krb5_error_code |
||||
ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) { |
||||
profile_t p; |
||||
diff --git a/auth.h b/auth.h |
||||
index f9d191c..c432d2f 100644 |
||||
--- a/auth.h |
||||
+++ b/auth.h |
||||
@@ -222,5 +222,7 @@ int sys_auth_passwd(Authctxt *, const char *); |
||||
#if defined(KRB5) && !defined(HEIMDAL) |
||||
#include <krb5.h> |
||||
krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); |
||||
+krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx, |
||||
+ char **k5login_directory); |
||||
#endif |
||||
#endif |
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c |
||||
index a7c0c5f..df8cc9a 100644 |
||||
--- a/gss-serv-krb5.c |
||||
+++ b/gss-serv-krb5.c |
||||
@@ -244,8 +244,27 @@ ssh_gssapi_k5login_exists() |
||||
{ |
||||
char file[MAXPATHLEN]; |
||||
struct passwd *pw = the_authctxt->pw; |
||||
+ char *k5login_directory = NULL; |
||||
+ int ret = 0; |
||||
+ |
||||
+ ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory); |
||||
+ debug3("%s: k5login_directory = %s (rv=%d)", __func__, k5login_directory, ret); |
||||
+ if (k5login_directory == NULL || ret != 0) { |
||||
+ /* If not set, the library will look for k5login |
||||
+ * files in the user's home directory, with the filename .k5login. |
||||
+ */ |
||||
+ snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); |
||||
+ } else { |
||||
+ /* If set, the library will look for a local user's k5login file |
||||
+ * within the named directory, with a filename corresponding to the |
||||
+ * local username. |
||||
+ */ |
||||
+ snprintf(file, sizeof(file), "%s%s%s", k5login_directory, |
||||
+ k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "", |
||||
+ pw->pw_name); |
||||
+ } |
||||
+ debug("%s: Checking existence of file %s", __func__, file); |
||||
|
||||
- snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); |
||||
return access(file, F_OK) == 0; |
||||
} |
||||
|
||||
diff --git a/sshd.8 b/sshd.8 |
||||
index 5c4f15b..135e290 100644 |
||||
--- a/sshd.8 |
||||
+++ b/sshd.8 |
||||
@@ -806,6 +806,10 @@ rlogin/rsh. |
||||
These files enforce GSSAPI/Kerberos authentication access control. |
||||
Further details are described in |
||||
.Xr ksu 1 . |
||||
+The location of the k5login file depends on the configuration option |
||||
+.Cm k5login_directory |
||||
+in the |
||||
+.Xr krb5.conf 5 . |
||||
.Pp |
||||
.It Pa ~/.ssh/ |
||||
This directory is the default location for all user-specific configuration |
@ -0,0 +1,481 @@
@@ -0,0 +1,481 @@
|
||||
diff -up openssh-7.4p1/auth2-pubkey.c.keycat openssh-7.4p1/auth2-pubkey.c |
||||
--- openssh-7.4p1/auth2-pubkey.c.keycat 2017-02-08 14:32:33.015581448 +0100 |
||||
+++ openssh-7.4p1/auth2-pubkey.c 2017-02-08 14:40:26.125216292 +0100 |
||||
@@ -1043,6 +1043,14 @@ user_key_command_allowed2(struct passwd |
||||
xasprintf(&command, "%s %s", av[0], av[1]); |
||||
} |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+ if (sshd_selinux_setup_env_variables() < 0) { |
||||
+ error ("failed to copy environment: %s", |
||||
+ strerror(errno)); |
||||
+ _exit(127); |
||||
+ } |
||||
+#endif |
||||
+ |
||||
if ((pid = subprocess("AuthorizedKeysCommand", pw, command, |
||||
ac, av, &f)) == 0) |
||||
goto out; |
||||
diff -up openssh-7.4p1/configure.ac.keycat openssh-7.4p1/configure.ac |
||||
--- openssh-7.4p1/configure.ac.keycat 2017-02-08 14:32:33.011581451 +0100 |
||||
+++ openssh-7.4p1/configure.ac 2017-02-08 14:32:33.016581448 +0100 |
||||
@@ -3129,6 +3129,7 @@ AC_ARG_WITH([pam], |
||||
PAM_MSG="yes" |
||||
|
||||
SSHDLIBS="$SSHDLIBS -lpam" |
||||
+ KEYCATLIBS="$KEYCATLIBS -lpam" |
||||
AC_DEFINE([USE_PAM], [1], |
||||
[Define if you want to enable PAM support]) |
||||
|
||||
@@ -3139,6 +3140,7 @@ AC_ARG_WITH([pam], |
||||
;; |
||||
*) |
||||
SSHDLIBS="$SSHDLIBS -ldl" |
||||
+ KEYCATLIBS="$KEYCATLIBS -ldl" |
||||
;; |
||||
esac |
||||
fi |
||||
@@ -4255,6 +4257,7 @@ AC_ARG_WITH([selinux], |
||||
) |
||||
AC_SUBST([SSHLIBS]) |
||||
AC_SUBST([SSHDLIBS]) |
||||
+AC_SUBST([KEYCATLIBS]) |
||||
|
||||
# Check whether user wants Kerberos 5 support |
||||
KRB5_MSG="no" |
||||
@@ -5206,6 +5209,9 @@ fi |
||||
if test ! -z "${SSHLIBS}"; then |
||||
echo " +for ssh: ${SSHLIBS}" |
||||
fi |
||||
+if test ! -z "${KEYCATLIBS}"; then |
||||
+echo " +for ssh-keycat: ${KEYCATLIBS}" |
||||
+fi |
||||
|
||||
echo "" |
||||
|
||||
diff -up openssh-7.4p1/HOWTO.ssh-keycat.keycat openssh-7.4p1/HOWTO.ssh-keycat |
||||
--- openssh-7.4p1/HOWTO.ssh-keycat.keycat 2017-02-08 14:32:33.014581449 +0100 |
||||
+++ openssh-7.4p1/HOWTO.ssh-keycat 2017-02-08 14:32:33.014581449 +0100 |
||||
@@ -0,0 +1,12 @@ |
||||
+The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys |
||||
+of an user in any environment. This includes environments with |
||||
+polyinstantiation of home directories and SELinux MLS policy enabled. |
||||
+ |
||||
+To use ssh-keycat, set these options in /etc/ssh/sshd_config file: |
||||
+ AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat |
||||
+ AuthorizedKeysCommandUser root |
||||
+ |
||||
+Do not forget to enable public key authentication: |
||||
+ PubkeyAuthentication yes |
||||
+ |
||||
+ |
||||
diff -up openssh-7.4p1/Makefile.in.keycat openssh-7.4p1/Makefile.in |
||||
--- openssh-7.4p1/Makefile.in.keycat 2017-02-08 14:32:33.012581451 +0100 |
||||
+++ openssh-7.4p1/Makefile.in 2017-02-08 14:38:28.839306815 +0100 |
||||
@@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server |
||||
SSH_KEYSIGN=$(libexecdir)/ssh-keysign |
||||
SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper |
||||
SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper |
||||
+SSH_KEYCAT=$(libexecdir)/ssh-keycat |
||||
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper |
||||
PRIVSEP_PATH=@PRIVSEP_PATH@ |
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ |
||||
@@ -51,6 +52,7 @@ K5LIBS=@K5LIBS@ |
||||
GSSLIBS=@GSSLIBS@ |
||||
SSHLIBS=@SSHLIBS@ |
||||
SSHDLIBS=@SSHDLIBS@ |
||||
+KEYCATLIBS=@KEYCATLIBS@ |
||||
LIBEDIT=@LIBEDIT@ |
||||
AR=@AR@ |
||||
AWK=@AWK@ |
||||
@@ -65,7 +67,7 @@ EXEEXT=@EXEEXT@ |
||||
MANFMT=@MANFMT@ |
||||
INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ |
||||
|
||||
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) |
||||
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) |
||||
|
||||
LIBOPENSSH_OBJS=\ |
||||
ssh_api.o \ |
||||
@@ -190,6 +192,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) |
||||
ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o |
||||
$(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o |
||||
+ $(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) |
||||
+ |
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o |
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) |
||||
|
||||
@@ -332,6 +337,7 @@ install-files: |
||||
$(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ |
||||
$(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ |
||||
fi |
||||
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) |
||||
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 |
||||
diff -up openssh-7.4p1/openbsd-compat/port-linux.h.keycat openssh-7.4p1/openbsd-compat/port-linux.h |
||||
--- openssh-7.4p1/openbsd-compat/port-linux.h.keycat 2017-02-08 14:32:33.009581453 +0100 |
||||
+++ openssh-7.4p1/openbsd-compat/port-linux.h 2017-02-08 14:32:33.015581448 +0100 |
||||
@@ -23,8 +23,10 @@ void ssh_selinux_setup_pty(char *, const |
||||
void ssh_selinux_change_context(const char *); |
||||
void ssh_selinux_setfscreatecon(const char *); |
||||
|
||||
+int sshd_selinux_enabled(void); |
||||
void sshd_selinux_copy_context(void); |
||||
void sshd_selinux_setup_exec_context(char *); |
||||
+int sshd_selinux_setup_env_variables(void); |
||||
#endif |
||||
|
||||
#ifdef LINUX_OOM_ADJUST |
||||
diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.keycat openssh-7.4p1/openbsd-compat/port-linux-sshd.c |
||||
--- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.keycat 2017-02-08 14:32:33.008581454 +0100 |
||||
+++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2017-02-08 14:32:33.015581448 +0100 |
||||
@@ -53,6 +53,20 @@ extern Authctxt *the_authctxt; |
||||
extern int inetd_flag; |
||||
extern int rexeced_flag; |
||||
|
||||
+/* Wrapper around is_selinux_enabled() to log its return value once only */ |
||||
+int |
||||
+sshd_selinux_enabled(void) |
||||
+{ |
||||
+ static int enabled = -1; |
||||
+ |
||||
+ if (enabled == -1) { |
||||
+ enabled = (is_selinux_enabled() == 1); |
||||
+ debug("SELinux support %s", enabled ? "enabled" : "disabled"); |
||||
+ } |
||||
+ |
||||
+ return (enabled); |
||||
+} |
||||
+ |
||||
/* Send audit message */ |
||||
static int |
||||
sshd_selinux_send_audit_message(int success, security_context_t default_context, |
||||
@@ -307,7 +321,7 @@ sshd_selinux_getctxbyname(char *pwname, |
||||
|
||||
/* Setup environment variables for pam_selinux */ |
||||
static int |
||||
-sshd_selinux_setup_pam_variables(void) |
||||
+sshd_selinux_setup_variables(int(*set_it)(char *, const char *)) |
||||
{ |
||||
const char *reqlvl; |
||||
char *role; |
||||
@@ -318,16 +332,16 @@ sshd_selinux_setup_pam_variables(void) |
||||
|
||||
ssh_selinux_get_role_level(&role, &reqlvl); |
||||
|
||||
- rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); |
||||
+ rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : ""); |
||||
|
||||
if (inetd_flag && !rexeced_flag) { |
||||
use_current = "1"; |
||||
} else { |
||||
use_current = ""; |
||||
- rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); |
||||
+ rv = rv || set_it("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); |
||||
} |
||||
|
||||
- rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); |
||||
+ rv = rv || set_it("SELINUX_USE_CURRENT_RANGE", use_current); |
||||
|
||||
if (role != NULL) |
||||
free(role); |
||||
@@ -335,6 +349,24 @@ sshd_selinux_setup_pam_variables(void) |
||||
return rv; |
||||
} |
||||
|
||||
+static int |
||||
+sshd_selinux_setup_pam_variables(void) |
||||
+{ |
||||
+ return sshd_selinux_setup_variables(do_pam_putenv); |
||||
+} |
||||
+ |
||||
+static int |
||||
+do_setenv(char *name, const char *value) |
||||
+{ |
||||
+ return setenv(name, value, 1); |
||||
+} |
||||
+ |
||||
+int |
||||
+sshd_selinux_setup_env_variables(void) |
||||
+{ |
||||
+ return sshd_selinux_setup_variables(do_setenv); |
||||
+} |
||||
+ |
||||
/* Set the execution context to the default for the specified user */ |
||||
void |
||||
sshd_selinux_setup_exec_context(char *pwname) |
||||
@@ -343,7 +375,7 @@ sshd_selinux_setup_exec_context(char *pw |
||||
int r = 0; |
||||
security_context_t default_ctx = NULL; |
||||
|
||||
- if (!ssh_selinux_enabled()) |
||||
+ if (!sshd_selinux_enabled()) |
||||
return; |
||||
|
||||
if (options.use_pam) { |
||||
@@ -414,7 +446,7 @@ sshd_selinux_copy_context(void) |
||||
{ |
||||
security_context_t *ctx; |
||||
|
||||
- if (!ssh_selinux_enabled()) |
||||
+ if (!sshd_selinux_enabled()) |
||||
return; |
||||
|
||||
if (getexeccon((security_context_t *)&ctx) != 0) { |
||||
diff -up openssh-7.4p1/platform.c.keycat openssh-7.4p1/platform.c |
||||
--- openssh-7.4p1/platform.c.keycat 2017-02-08 14:32:33.007581455 +0100 |
||||
+++ openssh-7.4p1/platform.c 2017-02-08 14:32:33.015581448 +0100 |
||||
@@ -99,7 +99,7 @@ platform_setusercontext(struct passwd *p |
||||
{ |
||||
#ifdef WITH_SELINUX |
||||
/* Cache selinux status for later use */ |
||||
- (void)ssh_selinux_enabled(); |
||||
+ (void)sshd_selinux_enabled(); |
||||
#endif |
||||
|
||||
#ifdef USE_SOLARIS_PROJECTS |
||||
diff -up openssh-7.4p1/ssh-keycat.c.keycat openssh-7.4p1/ssh-keycat.c |
||||
--- openssh-7.4p1/ssh-keycat.c.keycat 2017-02-08 14:32:33.015581448 +0100 |
||||
+++ openssh-7.4p1/ssh-keycat.c 2017-02-08 14:32:33.015581448 +0100 |
||||
@@ -0,0 +1,238 @@ |
||||
+/* |
||||
+ * 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, and the entire permission notice in its entirety, |
||||
+ * including the disclaimer of warranties. |
||||
+ * 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. |
||||
+ * 3. The name of the author may not be used to endorse or promote |
||||
+ * products derived from this software without specific prior |
||||
+ * written permission. |
||||
+ * |
||||
+ * ALTERNATIVELY, this product may be distributed under the terms of |
||||
+ * the GNU Public License, in which case the provisions of the GPL are |
||||
+ * required INSTEAD OF the above restrictions. (This clause is |
||||
+ * necessary due to a potential bad interaction between the GPL and |
||||
+ * the restrictions contained in a BSD-style copyright.) |
||||
+ * |
||||
+ * THIS SOFTWARE IS PROVIDED ``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. |
||||
+ */ |
||||
+ |
||||
+/* |
||||
+ * Copyright (c) 2011 Red Hat, Inc. |
||||
+ * Written by Tomas Mraz <tmraz@redhat.com> |
||||
+*/ |
||||
+ |
||||
+#define _GNU_SOURCE |
||||
+ |
||||
+#include "config.h" |
||||
+#include <stdio.h> |
||||
+#include <stdlib.h> |
||||
+#include <string.h> |
||||
+#include <sys/types.h> |
||||
+#include <sys/stat.h> |
||||
+#include <pwd.h> |
||||
+#include <fcntl.h> |
||||
+#include <unistd.h> |
||||
+ |
||||
+#include <security/pam_appl.h> |
||||
+ |
||||
+#include "uidswap.h" |
||||
+#include "misc.h" |
||||
+ |
||||
+#define ERR_USAGE 1 |
||||
+#define ERR_PAM_START 2 |
||||
+#define ERR_OPEN_SESSION 3 |
||||
+#define ERR_CLOSE_SESSION 4 |
||||
+#define ERR_PAM_END 5 |
||||
+#define ERR_GETPWNAM 6 |
||||
+#define ERR_MEMORY 7 |
||||
+#define ERR_OPEN 8 |
||||
+#define ERR_FILE_MODE 9 |
||||
+#define ERR_FDOPEN 10 |
||||
+#define ERR_STAT 11 |
||||
+#define ERR_WRITE 12 |
||||
+#define ERR_PAM_PUTENV 13 |
||||
+#define BUFLEN 4096 |
||||
+ |
||||
+/* Just ignore the messages in the conversation function */ |
||||
+static int |
||||
+dummy_conv(int num_msg, const struct pam_message **msgm, |
||||
+ struct pam_response **response, void *appdata_ptr) |
||||
+{ |
||||
+ struct pam_response *rsp; |
||||
+ |
||||
+ (void)msgm; |
||||
+ (void)appdata_ptr; |
||||
+ |
||||
+ if (num_msg <= 0) |
||||
+ return PAM_CONV_ERR; |
||||
+ |
||||
+ /* Just allocate the array as empty responses */ |
||||
+ rsp = calloc (num_msg, sizeof (struct pam_response)); |
||||
+ if (rsp == NULL) |
||||
+ return PAM_CONV_ERR; |
||||
+ |
||||
+ *response = rsp; |
||||
+ return PAM_SUCCESS; |
||||
+} |
||||
+ |
||||
+static struct pam_conv conv = { |
||||
+ dummy_conv, |
||||
+ NULL |
||||
+}; |
||||
+ |
||||
+char * |
||||
+make_auth_keys_name(const struct passwd *pwd) |
||||
+{ |
||||
+ char *fname; |
||||
+ |
||||
+ if (asprintf(&fname, "%s/.ssh/authorized_keys", pwd->pw_dir) < 0) |
||||
+ return NULL; |
||||
+ |
||||
+ return fname; |
||||
+} |
||||
+ |
||||
+int |
||||
+dump_keys(const char *user) |
||||
+{ |
||||
+ struct passwd *pwd; |
||||
+ int fd = -1; |
||||
+ FILE *f = NULL; |
||||
+ char *fname = NULL; |
||||
+ int rv = 0; |
||||
+ char buf[BUFLEN]; |
||||
+ size_t len; |
||||
+ struct stat st; |
||||
+ |
||||
+ if ((pwd = getpwnam(user)) == NULL) { |
||||
+ return ERR_GETPWNAM; |
||||
+ } |
||||
+ |
||||
+ if ((fname = make_auth_keys_name(pwd)) == NULL) { |
||||
+ return ERR_MEMORY; |
||||
+ } |
||||
+ |
||||
+ temporarily_use_uid(pwd); |
||||
+ |
||||
+ if ((fd = open(fname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < 0) { |
||||
+ rv = ERR_OPEN; |
||||
+ goto fail; |
||||
+ } |
||||
+ |
||||
+ if (fstat(fd, &st) < 0) { |
||||
+ rv = ERR_STAT; |
||||
+ goto fail; |
||||
+ } |
||||
+ |
||||
+ if (!S_ISREG(st.st_mode) || |
||||
+ (st.st_uid != pwd->pw_uid && st.st_uid != 0)) { |
||||
+ rv = ERR_FILE_MODE; |
||||
+ goto fail; |
||||
+ } |
||||
+ |
||||
+ unset_nonblock(fd); |
||||
+ |
||||
+ if ((f = fdopen(fd, "r")) == NULL) { |
||||
+ rv = ERR_FDOPEN; |
||||
+ goto fail; |
||||
+ } |
||||
+ |
||||
+ fd = -1; |
||||
+ |
||||
+ while ((len = fread(buf, 1, sizeof(buf), f)) > 0) { |
||||
+ rv = fwrite(buf, 1, len, stdout) != len ? ERR_WRITE : 0; |
||||
+ } |
||||
+ |
||||
+fail: |
||||
+ if (fd != -1) |
||||
+ close(fd); |
||||
+ if (f != NULL) |
||||
+ fclose(f); |
||||
+ free(fname); |
||||
+ restore_uid(); |
||||
+ return rv; |
||||
+} |
||||
+ |
||||
+static const char *env_names[] = { "SELINUX_ROLE_REQUESTED", |
||||
+ "SELINUX_LEVEL_REQUESTED", |
||||
+ "SELINUX_USE_CURRENT_RANGE" |
||||
+}; |
||||
+ |
||||
+extern char **environ; |
||||
+ |
||||
+int |
||||
+set_pam_environment(pam_handle_t *pamh) |
||||
+{ |
||||
+ int i; |
||||
+ size_t j; |
||||
+ |
||||
+ for (j = 0; j < sizeof(env_names)/sizeof(env_names[0]); ++j) { |
||||
+ int len = strlen(env_names[j]); |
||||
+ |
||||
+ for (i = 0; environ[i] != NULL; ++i) { |
||||
+ if (strncmp(env_names[j], environ[i], len) == 0 && |
||||
+ environ[i][len] == '=') { |
||||
+ if (pam_putenv(pamh, environ[i]) != PAM_SUCCESS) |
||||
+ return ERR_PAM_PUTENV; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+int |
||||
+main(int argc, char *argv[]) |
||||
+{ |
||||
+ pam_handle_t *pamh = NULL; |
||||
+ int retval; |
||||
+ int ev = 0; |
||||
+ |
||||
+ if (argc != 2) { |
||||
+ fprintf(stderr, "Usage: %s <user-name>\n", argv[0]); |
||||
+ return ERR_USAGE; |
||||
+ } |
||||
+ |
||||
+ retval = pam_start("ssh-keycat", argv[1], &conv, &pamh); |
||||
+ if (retval != PAM_SUCCESS) { |
||||
+ return ERR_PAM_START; |
||||
+ } |
||||
+ |
||||
+ ev = set_pam_environment(pamh); |
||||
+ if (ev != 0) |
||||
+ goto finish; |
||||
+ |
||||
+ retval = pam_open_session(pamh, PAM_SILENT); |
||||
+ if (retval != PAM_SUCCESS) { |
||||
+ ev = ERR_OPEN_SESSION; |
||||
+ goto finish; |
||||
+ } |
||||
+ |
||||
+ ev = dump_keys(argv[1]); |
||||
+ |
||||
+ retval = pam_close_session(pamh, PAM_SILENT); |
||||
+ if (retval != PAM_SUCCESS) { |
||||
+ ev = ERR_CLOSE_SESSION; |
||||
+ } |
||||
+ |
||||
+finish: |
||||
+ retval = pam_end (pamh,retval); |
||||
+ if (retval != PAM_SUCCESS) { |
||||
+ ev = ERR_PAM_END; |
||||
+ } |
||||
+ return ev; |
||||
+} |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
diff -up openssh-6.6p1/authfile.c.keyperm openssh-6.6p1/authfile.c |
||||
--- openssh-6.6p1/authfile.c.keyperm 2014-02-04 01:20:15.000000000 +0100 |
||||
+++ openssh-6.6p1/authfile.c 2014-05-05 15:20:43.075246776 +0200 |
||||
@@ -54,6 +54,7 @@ |
||||
|
||||
#include <errno.h> |
||||
#include <fcntl.h> |
||||
+#include <grp.h> |
||||
#include <stdio.h> |
||||
#include <stdarg.h> |
||||
#include <stdlib.h> |
||||
@@ -979,6 +980,13 @@ key_perm_ok(int fd, const char *filename |
||||
#ifdef HAVE_CYGWIN |
||||
if (check_ntsec(filename)) |
||||
#endif |
||||
+ if (st.st_mode & 040) { |
||||
+ struct group *gr; |
||||
+ |
||||
+ if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid)) |
||||
+ st.st_mode &= ~040; |
||||
+ } |
||||
+ |
||||
if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { |
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |
||||
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); |
@ -0,0 +1,294 @@
@@ -0,0 +1,294 @@
|
||||
diff --git a/auth-krb5.c b/auth-krb5.c |
||||
index 6c62bdf..11c8562 100644 |
||||
--- a/auth-krb5.c |
||||
+++ b/auth-krb5.c |
||||
@@ -54,6 +54,21 @@ |
||||
|
||||
extern ServerOptions options; |
||||
|
||||
+int |
||||
+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client, |
||||
+ int k5login_exists) |
||||
+{ |
||||
+ if (options.use_kuserok || !k5login_exists) |
||||
+ return krb5_kuserok(krb5_ctx, krb5_user, client); |
||||
+ else { |
||||
+ char kuser[65]; |
||||
+ |
||||
+ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) |
||||
+ return 0; |
||||
+ return strcmp(kuser, client) == 0; |
||||
+ } |
||||
+} |
||||
+ |
||||
static int |
||||
krb5_init(void *context) |
||||
{ |
||||
@@ -157,8 +172,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password) |
||||
if (problem) |
||||
goto out; |
||||
|
||||
- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, |
||||
- authctxt->pw->pw_name)) { |
||||
+ /* Use !options.use_kuserok here to make ssh_krb5_kuserok() not |
||||
+ * depend on the existance of .k5login */ |
||||
+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name, !options.use_kuserok)) { |
||||
problem = -1; |
||||
goto out; |
||||
} |
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c |
||||
index 60de320..0a4930e 100644 |
||||
--- a/gss-serv-krb5.c |
||||
+++ b/gss-serv-krb5.c |
||||
@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, |
||||
int); |
||||
|
||||
static krb5_context krb_context = NULL; |
||||
+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *, int); |
||||
|
||||
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */ |
||||
|
||||
@@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void) |
||||
* Returns true if the user is OK to log in, otherwise returns 0 |
||||
*/ |
||||
|
||||
+/* The purpose of the function is to find out if a Kerberos principal is |
||||
+ * allowed to log in as the given local user. This is a general problem with |
||||
+ * Kerberized services because by design the Kerberos principals are |
||||
+ * completely independent from the local user names. This is one of the |
||||
+ * reasons why Kerberos is working well on different operating systems like |
||||
+ * Windows and UNIX/Linux. Nevertheless a relationship between a Kerberos |
||||
+ * principal and a local user name must be established because otherwise every |
||||
+ * access would be granted for every principal with a valid ticket. |
||||
+ * |
||||
+ * Since it is a general issue libkrb5 provides some functions for |
||||
+ * applications to find out about the relationship between the Kerberos |
||||
+ * principal and a local user name. They are krb5_kuserok() and |
||||
+ * krb5_aname_to_localname(). |
||||
+ * |
||||
+ * krb5_kuserok() can be used to "Determine if a principal is authorized to |
||||
+ * log in as a local user" (from the MIT Kerberos documentation of this |
||||
+ * function). Which is exactly what we are looking for and should be the |
||||
+ * preferred choice. It accepts the Kerberos principal and a local user name |
||||
+ * and let libkrb5 or its plugins determine if they relate to each other or |
||||
+ * not. |
||||
+ * |
||||
+ * krb5_aname_to_localname() can use used to "Convert a principal name to a |
||||
+ * local name" (from the MIT Kerberos documentation of this function). It |
||||
+ * accepts a Kerberos principle and returns a local name and it is up to the |
||||
+ * application to do any additional checks. There are two issues using |
||||
+ * krb5_aname_to_localname(). First, since POSIX user names are case |
||||
+ * sensitive, the calling application in general has no other choice than |
||||
+ * doing a case-sensitive string comparison between the name returned by |
||||
+ * krb5_aname_to_localname() and the name used at the login prompt. When the |
||||
+ * users are provided by a case in-sensitive server, e.g. Active Directory, |
||||
+ * this might lead to login failures because the user typing the name at the |
||||
+ * login prompt might not be aware of the right case. Another issue might be |
||||
+ * caused if there are multiple alias names available for a single user. E.g. |
||||
+ * the canonical name of a user is user@group.department.example.com but there |
||||
+ * exists a shorter login name, e.g. user@example.com, to safe typing at the |
||||
+ * login prompt. Here krb5_aname_to_localname() can only return the canonical |
||||
+ * name, but if the short alias is used at the login prompt authentication |
||||
+ * will fail as well. All this can be avoided by using krb5_kuserok() and |
||||
+ * configuring krb5.conf or using a suitable plugin to meet the needs of the |
||||
+ * given environment. |
||||
+ * |
||||
+ * The Fedora and RHEL version of openssh contain two patches which modify the |
||||
+ * access control behavior: |
||||
+ * - openssh-6.6p1-kuserok.patch |
||||
+ * - openssh-6.6p1-force_krb.patch |
||||
+ * |
||||
+ * openssh-6.6p1-kuserok.patch adds a new option KerberosUseKuserok for |
||||
+ * sshd_config which controls if krb5_kuserok() is used to check if the |
||||
+ * principle is authorized or if krb5_aname_to_localname() should be used. |
||||
+ * The reason to add this patch was that krb5_kuserok() by default checks if |
||||
+ * a .k5login file exits in the users home-directory. With this the user can |
||||
+ * give access to his account for any given principal which might be |
||||
+ * in violation with company policies and it would be useful if this can be |
||||
+ * rejected. Nevertheless the patch ignores the fact that krb5_kuserok() does |
||||
+ * no only check .k5login but other sources as well and checking .k5login can |
||||
+ * be disabled for all applications in krb5.conf as well. With this new |
||||
+ * option KerberosUseKuserok set to 'no' (and this is the default for RHEL7 |
||||
+ * and Fedora 21) openssh can only use krb5_aname_to_localname() with the |
||||
+ * restrictions mentioned above. |
||||
+ * |
||||
+ * openssh-6.6p1-force_krb.patch adds a ksu like behaviour to ssh, i.e. when |
||||
+ * using GSSAPI authentication only commands configured in the .k5user can be |
||||
+ * executed. Here the wrong assumption that krb5_kuserok() only checks |
||||
+ * .k5login is made as well. In contrast ksu checks .k5login directly and |
||||
+ * does not use krb5_kuserok() which might be more useful for the given |
||||
+ * purpose. Additionally this patch is not synced with |
||||
+ * openssh-6.6p1-kuserok.patch. |
||||
+ * |
||||
+ * The current patch tries to restore the usage of krb5_kuserok() so that e.g. |
||||
+ * localauth plugins can be used. It does so by adding a forth parameter to |
||||
+ * ssh_krb5_kuserok() which indicates whether .k5login exists or not. If it |
||||
+ * does not exists krb5_kuserok() is called even if KerberosUseKuserok is set |
||||
+ * to 'no' because the intent of the option is to not check .k5login and if it |
||||
+ * does not exists krb5_kuserok() returns a result without checking .k5login. |
||||
+ * If .k5login does exists and KerberosUseKuserok is 'no' we fall back to |
||||
+ * krb5_aname_to_localname(). This is in my point of view an acceptable |
||||
+ * limitation and does not break the current behaviour. |
||||
+ * |
||||
+ * Additionally with this patch ssh_krb5_kuserok() is called in |
||||
+ * ssh_gssapi_krb5_cmdok() instead of only krb5_aname_to_localname() is |
||||
+ * neither .k5login nor .k5users exists to allow plugin evaluation via |
||||
+ * krb5_kuserok() as well. |
||||
+ * |
||||
+ * I tried to keep the patch as minimal as possible, nevertheless I see some |
||||
+ * areas for improvement which, if they make sense, have to be evaluated |
||||
+ * carefully because they might change existing behaviour and cause breaks |
||||
+ * during upgrade: |
||||
+ * - I wonder if disabling .k5login usage make sense in sshd or if it should |
||||
+ * be better disabled globally in krb5.conf |
||||
+ * - if really needed openssh-6.6p1-kuserok.patch should be fixed to really |
||||
+ * only disable checking .k5login and maybe .k5users |
||||
+ * - the ksu behaviour should be configurable and maybe check the .k5login and |
||||
+ * .k5users files directly like ksu itself does |
||||
+ * - to make krb5_aname_to_localname() more useful an option for sshd to use |
||||
+ * the canonical name (the one returned by getpwnam()) instead of the name |
||||
+ * given at the login prompt might be useful */ |
||||
+ |
||||
static int |
||||
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) |
||||
{ |
||||
@@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) |
||||
/* NOTE: .k5login and .k5users must opened as root, not the user, |
||||
* because if they are on a krb5-protected filesystem, user credentials |
||||
* to access these files aren't available yet. */ |
||||
- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { |
||||
+ if (ssh_krb5_kuserok(krb_context, princ, name, k5login_exists) |
||||
+ && k5login_exists) { |
||||
retval = 1; |
||||
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", |
||||
name, (char *)client->displayname.value); |
||||
@@ -171,9 +270,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, |
||||
snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); |
||||
/* If both .k5login and .k5users DNE, self-login is ok. */ |
||||
if (!k5login_exists && (access(file, F_OK) == -1)) { |
||||
- return (krb5_aname_to_localname(krb_context, principal, |
||||
- sizeof(kuser), kuser) == 0) && |
||||
- (strcmp(kuser, luser) == 0); |
||||
+ return ssh_krb5_kuserok(krb_context, principal, luser, |
||||
+ k5login_exists); |
||||
} |
||||
if ((fp = fopen(file, "r")) == NULL) { |
||||
int saved_errno = errno; |
||||
diff --git a/servconf.c b/servconf.c |
||||
index 68fb9ef..904c869 100644 |
||||
--- a/servconf.c |
||||
+++ b/servconf.c |
||||
@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions *options) |
||||
options->ip_qos_interactive = -1; |
||||
options->ip_qos_bulk = -1; |
||||
options->version_addendum = NULL; |
||||
+ options->use_kuserok = -1; |
||||
} |
||||
|
||||
void |
||||
@@ -312,6 +313,8 @@ fill_default_server_options(ServerOptions *options) |
||||
options->version_addendum = xstrdup(""); |
||||
if (options->show_patchlevel == -1) |
||||
options->show_patchlevel = 0; |
||||
+ if (options->use_kuserok == -1) |
||||
+ options->use_kuserok = 1; |
||||
|
||||
/* Turn privilege separation on by default */ |
||||
if (use_privsep == -1) |
||||
@@ -338,7 +341,7 @@ typedef enum { |
||||
sPermitRootLogin, sLogFacility, sLogLevel, |
||||
sRhostsRSAAuthentication, sRSAAuthentication, |
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, |
||||
- sKerberosGetAFSToken, |
||||
+ sKerberosGetAFSToken, sKerberosUseKuserok, |
||||
sKerberosTgtPassing, sChallengeResponseAuthentication, |
||||
sPasswordAuthentication, sKbdInteractiveAuthentication, |
||||
sListenAddress, sAddressFamily, |
||||
@@ -410,11 +413,13 @@ static struct { |
||||
#else |
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, |
||||
#endif |
||||
+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, |
||||
#else |
||||
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL }, |
||||
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, |
||||
+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, |
||||
#endif |
||||
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, |
||||
@@ -1526,6 +1531,10 @@ process_server_config_line(ServerOptions *options, char *line, |
||||
*activep = value; |
||||
break; |
||||
|
||||
+ case sKerberosUseKuserok: |
||||
+ intptr = &options->use_kuserok; |
||||
+ goto parse_flag; |
||||
+ |
||||
case sPermitOpen: |
||||
arg = strdelim(&cp); |
||||
if (!arg || *arg == '\0') |
||||
@@ -1811,6 +1820,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) |
||||
M_CP_INTOPT(max_authtries); |
||||
M_CP_INTOPT(ip_qos_interactive); |
||||
M_CP_INTOPT(ip_qos_bulk); |
||||
+ M_CP_INTOPT(use_kuserok); |
||||
M_CP_INTOPT(rekey_limit); |
||||
M_CP_INTOPT(rekey_interval); |
||||
|
||||
@@ -2062,6 +2072,7 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_fmtint(sUseDNS, o->use_dns); |
||||
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); |
||||
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); |
||||
+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); |
||||
|
||||
/* string arguments */ |
||||
dump_cfg_string(sPidFile, o->pid_file); |
||||
diff --git a/servconf.h b/servconf.h |
||||
index 37cfa9b..5117dfa 100644 |
||||
--- a/servconf.h |
||||
+++ b/servconf.h |
||||
@@ -173,6 +173,7 @@ typedef struct { |
||||
|
||||
int num_permitted_opens; |
||||
|
||||
+ int use_kuserok; |
||||
char *chroot_directory; |
||||
char *revoked_keys_file; |
||||
char *trusted_user_ca_keys; |
||||
diff --git a/sshd_config b/sshd_config |
||||
index adfd7b1..e772ed5 100644 |
||||
--- a/sshd_config |
||||
+++ b/sshd_config |
||||
@@ -87,6 +87,7 @@ ChallengeResponseAuthentication no |
||||
#KerberosOrLocalPasswd yes |
||||
#KerberosTicketCleanup yes |
||||
#KerberosGetAFSToken no |
||||
+#KerberosUseKuserok yes |
||||
|
||||
# GSSAPI options |
||||
GSSAPIAuthentication yes |
||||
diff --git a/sshd_config.5 b/sshd_config.5 |
||||
index 1fb002d..e0e5fff 100644 |
||||
--- a/sshd_config.5 |
||||
+++ b/sshd_config.5 |
||||
@@ -697,6 +697,10 @@ Specifies whether to automatically destroy the user's ticket cache |
||||
file on logout. |
||||
The default is |
||||
.Dq yes . |
||||
+.It Cm KerberosUseKuserok |
||||
+Specifies whether to look at .k5login file for user's aliases. |
||||
+The default is |
||||
+.Dq yes . |
||||
.It Cm KexAlgorithms |
||||
Specifies the available KEX (Key Exchange) algorithms. |
||||
Multiple algorithms must be comma-separated. |
||||
@@ -862,6 +866,7 @@ Available keywords are |
||||
.Cm HostbasedUsesNameFromPacketOnly , |
||||
.Cm KbdInteractiveAuthentication , |
||||
.Cm KerberosAuthentication , |
||||
+.Cm KerberosUseKuserok , |
||||
.Cm MaxAuthTries , |
||||
.Cm MaxSessions , |
||||
.Cm PasswordAuthentication , |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
diff --git a/sshd.c b/sshd.c |
||||
index a7b8b6a..24ab272 100644 |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -1620,6 +1620,10 @@ main(int ac, char **av) |
||||
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, |
||||
&cfg, NULL); |
||||
|
||||
+ /* 'UsePAM no' is not supported in Red Hat Enterprise Linux */ |
||||
+ if (! options.use_pam) |
||||
+ logit("WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several problems."); |
||||
+ |
||||
seed_rng(); |
||||
|
||||
/* Fill in default values for those options not explicitly set. */ |
||||
diff --git a/sshd_config b/sshd_config |
||||
index 36cb27a..c1b7c03 100644 |
||||
--- a/sshd_config |
||||
+++ b/sshd_config |
||||
@@ -101,6 +101,8 @@ GSSAPICleanupCredentials no |
||||
# 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'. |
||||
+# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several |
||||
+# problems. |
||||
UsePAM yes |
||||
|
||||
#AllowAgentForwarding yes |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
diff -up openssh-7.4p1/servconf.c.memory-problems openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.memory-problems 2017-02-09 10:41:42.483123417 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-09 10:42:16.392102462 +0100 |
||||
@@ -2006,6 +2006,8 @@ copy_set_server_options(ServerOptions *d |
||||
dst->n = src->n; \ |
||||
} while (0) |
||||
|
||||
+ u_int i; |
||||
+ |
||||
M_CP_INTOPT(password_authentication); |
||||
M_CP_INTOPT(gss_authentication); |
||||
M_CP_INTOPT(pubkey_authentication); |
||||
@@ -2058,8 +2060,10 @@ copy_set_server_options(ServerOptions *d |
||||
} while(0) |
||||
#define M_CP_STRARRAYOPT(n, num_n) do {\ |
||||
if (src->num_n != 0) { \ |
||||
+ for (i = 0; i < dst->num_n; i++) \ |
||||
+ free(dst->n[i]); \ |
||||
for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ |
||||
- dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ |
||||
+ dst->n[dst->num_n] = src->n[dst->num_n]; \ |
||||
} \ |
||||
} while(0) |
||||
|
||||
diff -up openssh-7.4p1/sshd.c.memory-problems openssh-7.4p1/sshd.c |
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c |
||||
index c18524e..d04f4ed 100644 |
||||
--- a/openbsd-compat/port-linux-sshd.c |
||||
+++ b/openbsd-compat/port-linux-sshd.c |
||||
@@ -409,6 +409,25 @@ sshd_selinux_setup_exec_context(char *pwname) |
||||
debug3("%s: done", __func__); |
||||
} |
||||
|
||||
+void |
||||
+sshd_selinux_copy_context(void) |
||||
+{ |
||||
+ security_context_t *ctx; |
||||
+ |
||||
+ if (!ssh_selinux_enabled()) |
||||
+ return; |
||||
+ |
||||
+ if (getexeccon((security_context_t *)&ctx) != 0) { |
||||
+ logit("%s: getcon failed with %s", __func__, strerror (errno)); |
||||
+ return; |
||||
+ } |
||||
+ if (ctx != NULL) { |
||||
+ if (setcon(ctx) != 0) |
||||
+ logit("%s: setcon failed with %s", __func__, strerror (errno)); |
||||
+ freecon(ctx); |
||||
+ } |
||||
+} |
||||
+ |
||||
#endif |
||||
#endif |
||||
|
||||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h |
||||
index 8ef6cc4..b18893c 100644 |
||||
--- a/openbsd-compat/port-linux.h |
||||
+++ b/openbsd-compat/port-linux.h |
||||
@@ -25,6 +25,7 @@ void ssh_selinux_setup_pty(char *, const char *); |
||||
void ssh_selinux_change_context(const char *); |
||||
void ssh_selinux_setfscreatecon(const char *); |
||||
|
||||
+void sshd_selinux_copy_context(void); |
||||
void sshd_selinux_setup_exec_context(char *); |
||||
#endif |
||||
|
||||
diff --git a/session.c b/session.c |
||||
index 2bcf818..b5dc144 100644 |
||||
--- a/session.c |
||||
+++ b/session.c |
||||
@@ -1538,6 +1538,9 @@ do_setusercontext(struct passwd *pw) |
||||
pw->pw_uid); |
||||
chroot_path = percent_expand(tmp, "h", pw->pw_dir, |
||||
"u", pw->pw_name, (char *)NULL); |
||||
+#ifdef WITH_SELINUX |
||||
+ sshd_selinux_copy_context(); |
||||
+#endif |
||||
safely_chroot(chroot_path, pw->pw_uid); |
||||
free(tmp); |
||||
free(chroot_path); |
||||
@@ -1565,6 +1568,12 @@ do_setusercontext(struct passwd *pw) |
||||
/* Permanently switch to the desired uid. */ |
||||
permanently_set_uid(pw); |
||||
#endif |
||||
+ |
||||
+#ifdef WITH_SELINUX |
||||
+ if (options.chroot_directory == NULL || |
||||
+ strcasecmp(options.chroot_directory, "none") == 0) |
||||
+ sshd_selinux_copy_context(); |
||||
+#endif |
||||
} else if (options.chroot_directory != NULL && |
||||
strcasecmp(options.chroot_directory, "none") != 0) { |
||||
fatal("server lacks privileges to chroot to ChrootDirectory"); |
||||
@@ -1826,9 +1835,6 @@ do_child(Session *s, const char *command) |
||||
argv[i] = NULL; |
||||
optind = optreset = 1; |
||||
__progname = argv[0]; |
||||
-#ifdef WITH_SELINUX |
||||
- ssh_selinux_change_context("sftpd_t"); |
||||
-#endif |
||||
exit(sftp_server_main(i, argv, s->pw)); |
||||
} |
||||
|
||||
diff --git a/sshd.c b/sshd.c |
||||
index 07f9926..a97f8b7 100644 |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -632,6 +632,10 @@ privsep_preauth_child(void) |
||||
/* Demote the private keys to public keys. */ |
||||
demote_sensitive_data(); |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+ ssh_selinux_change_context("sshd_net_t"); |
||||
+#endif |
||||
+ |
||||
/* Demote the child */ |
||||
if (getuid() == 0 || geteuid() == 0) { |
||||
/* Change our root directory */ |
||||
@@ -768,6 +772,13 @@ privsep_postauth(Authctxt *authctxt) |
||||
do_setusercontext(authctxt->pw); |
||||
|
||||
skip: |
||||
+#ifdef WITH_SELINUX |
||||
+ /* switch SELinux content for root too */ |
||||
+ if (authctxt->pw->pw_uid == 0) { |
||||
+ sshd_selinux_copy_context(); |
||||
+ } |
||||
+#endif |
||||
+ |
||||
/* It is safe now to apply the key state */ |
||||
monitor_apply_keystate(pmonitor); |
||||
|
@ -0,0 +1,131 @@
@@ -0,0 +1,131 @@
|
||||
diff -up openssh-7.4p1/ssh_config.redhat openssh-7.4p1/ssh_config |
||||
--- openssh-7.4p1/ssh_config.redhat 2017-02-08 15:22:30.811307915 +0100 |
||||
+++ openssh-7.4p1/ssh_config 2017-02-08 15:22:30.812307915 +0100 |
||||
@@ -52,3 +52,15 @@ |
||||
# Uncomment this if you want to use .local domain |
||||
# Host *.local |
||||
# CheckHostIP no |
||||
+ |
||||
+Host * |
||||
+ GSSAPIAuthentication yes |
||||
+# If this option is set to yes then remote X11 clients will have full access |
||||
+# to the original X11 display. As virtually no X11 client supports the untrusted |
||||
+# mode correctly we set this to yes. |
||||
+ ForwardX11Trusted yes |
||||
+# Send locale-related environment variables |
||||
+ SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES |
||||
+ SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT |
||||
+ SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE |
||||
+ SendEnv XMODIFIERS |
||||
diff -up openssh-7.4p1/sshd_config.0.redhat openssh-7.4p1/sshd_config.0 |
||||
--- openssh-7.4p1/sshd_config.0.redhat 2016-12-19 06:21:22.000000000 +0100 |
||||
+++ openssh-7.4p1/sshd_config.0 2017-02-08 15:22:30.813307914 +0100 |
||||
@@ -837,9 +837,9 @@ DESCRIPTION |
||||
|
||||
SyslogFacility |
||||
Gives the facility code that is used when logging messages from |
||||
- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0, |
||||
- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The |
||||
- default is AUTH. |
||||
+ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV, |
||||
+ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. |
||||
+ The default is AUTH. |
||||
|
||||
TCPKeepAlive |
||||
Specifies whether the system should send TCP keepalive messages |
||||
diff -up openssh-7.4p1/sshd_config.5.redhat openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.redhat 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2017-02-08 15:22:30.813307914 +0100 |
||||
@@ -1393,7 +1393,7 @@ By default no subsystems are defined. |
||||
.It Cm SyslogFacility |
||||
Gives the facility code that is used when logging messages from |
||||
.Xr sshd 8 . |
||||
-The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, |
||||
+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, |
||||
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. |
||||
The default is AUTH. |
||||
.It Cm TCPKeepAlive |
||||
diff -up openssh-7.4p1/sshd_config.redhat openssh-7.4p1/sshd_config |
||||
--- openssh-7.4p1/sshd_config.redhat 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/sshd_config 2017-02-08 15:33:24.705736576 +0100 |
||||
@@ -10,21 +10,26 @@ |
||||
# possible, but leave them commented. Uncommented options override the |
||||
# default value. |
||||
|
||||
+# If you want to change the port on a SELinux system, you have to tell |
||||
+# SELinux about this change. |
||||
+# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER |
||||
+# |
||||
#Port 22 |
||||
#AddressFamily any |
||||
#ListenAddress 0.0.0.0 |
||||
#ListenAddress :: |
||||
|
||||
-#HostKey /etc/ssh/ssh_host_rsa_key |
||||
+HostKey /etc/ssh/ssh_host_rsa_key |
||||
#HostKey /etc/ssh/ssh_host_dsa_key |
||||
-#HostKey /etc/ssh/ssh_host_ecdsa_key |
||||
-#HostKey /etc/ssh/ssh_host_ed25519_key |
||||
+HostKey /etc/ssh/ssh_host_ecdsa_key |
||||
+HostKey /etc/ssh/ssh_host_ed25519_key |
||||
|
||||
# Ciphers and keying |
||||
#RekeyLimit default none |
||||
|
||||
# Logging |
||||
#SyslogFacility AUTH |
||||
+SyslogFacility AUTHPRIV |
||||
#LogLevel INFO |
||||
|
||||
# Authentication: |
||||
@@ -57,9 +62,11 @@ AuthorizedKeysFile .ssh/authorized_keys |
||||
# To disable tunneled clear text passwords, change to no here! |
||||
#PasswordAuthentication yes |
||||
#PermitEmptyPasswords no |
||||
+PasswordAuthentication yes |
||||
|
||||
# Change to no to disable s/key passwords |
||||
#ChallengeResponseAuthentication yes |
||||
+ChallengeResponseAuthentication no |
||||
|
||||
# Kerberos options |
||||
#KerberosAuthentication no |
||||
@@ -68,8 +75,8 @@ AuthorizedKeysFile .ssh/authorized_keys |
||||
#KerberosGetAFSToken no |
||||
|
||||
# GSSAPI options |
||||
-#GSSAPIAuthentication no |
||||
-#GSSAPICleanupCredentials yes |
||||
+GSSAPIAuthentication yes |
||||
+GSSAPICleanupCredentials no |
||||
|
||||
# Set this to 'yes' to enable PAM authentication, account processing, |
||||
# and session processing. If this is enabled, PAM authentication will |
||||
@@ -80,12 +87,12 @@ 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 |
||||
+UsePAM yes |
||||
|
||||
#AllowAgentForwarding yes |
||||
#AllowTcpForwarding yes |
||||
#GatewayPorts no |
||||
-#X11Forwarding no |
||||
+X11Forwarding yes |
||||
#X11DisplayOffset 10 |
||||
#X11UseLocalhost yes |
||||
#PermitTTY yes |
||||
@@ -108,6 +115,12 @@ AuthorizedKeysFile .ssh/authorized_keys |
||||
# no default banner path |
||||
#Banner none |
||||
|
||||
+# Accept locale-related environment variables |
||||
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES |
||||
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT |
||||
+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE |
||||
+AcceptEnv XMODIFIERS |
||||
+ |
||||
# override default of no subsystems |
||||
Subsystem sftp /usr/libexec/sftp-server |
||||
|
@ -0,0 +1,896 @@
@@ -0,0 +1,896 @@
|
||||
diff --git a/auth-pam.c b/auth-pam.c |
||||
index d789bad..cd1a775 100644 |
||||
--- a/auth-pam.c |
||||
+++ b/auth-pam.c |
||||
@@ -1068,7 +1068,7 @@ is_pam_session_open(void) |
||||
* during the ssh authentication process. |
||||
*/ |
||||
int |
||||
-do_pam_putenv(char *name, char *value) |
||||
+do_pam_putenv(char *name, const char *value) |
||||
{ |
||||
int ret = 1; |
||||
#ifdef HAVE_PAM_PUTENV |
||||
diff --git a/auth-pam.h b/auth-pam.h |
||||
index a1a2b52..b109a5a 100644 |
||||
--- a/auth-pam.h |
||||
+++ b/auth-pam.h |
||||
@@ -38,7 +38,7 @@ void do_pam_session(void); |
||||
void do_pam_set_tty(const char *); |
||||
void do_pam_setcred(int ); |
||||
void do_pam_chauthtok(void); |
||||
-int do_pam_putenv(char *, char *); |
||||
+int do_pam_putenv(char *, const char *); |
||||
char ** fetch_pam_environment(void); |
||||
char ** fetch_pam_child_environment(void); |
||||
void free_pam_environment(char **); |
||||
diff --git a/auth.h b/auth.h |
||||
index 124e597..4605588 100644 |
||||
--- a/auth.h |
||||
+++ b/auth.h |
||||
@@ -59,6 +59,9 @@ struct Authctxt { |
||||
char *service; |
||||
struct passwd *pw; /* set if 'valid' */ |
||||
char *style; |
||||
+#ifdef WITH_SELINUX |
||||
+ char *role; |
||||
+#endif |
||||
void *kbdintctxt; |
||||
char *info; /* Extra info for next auth_log */ |
||||
#ifdef BSD_AUTH |
||||
diff --git a/auth1.c b/auth1.c |
||||
index 0f870b3..df040bb 100644 |
||||
--- a/auth1.c |
||||
+++ b/auth1.c |
||||
@@ -381,6 +381,9 @@ do_authentication(Authctxt *authctxt) |
||||
{ |
||||
u_int ulen; |
||||
char *user, *style = NULL; |
||||
+#ifdef WITH_SELINUX |
||||
+ char *role=NULL; |
||||
+#endif |
||||
|
||||
/* Get the name of the user that we wish to log in as. */ |
||||
packet_read_expect(SSH_CMSG_USER); |
||||
@@ -389,11 +392,24 @@ do_authentication(Authctxt *authctxt) |
||||
user = packet_get_cstring(&ulen); |
||||
packet_check_eom(); |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+ if ((role = strchr(user, '/')) != NULL) |
||||
+ *role++ = '\0'; |
||||
+#endif |
||||
+ |
||||
if ((style = strchr(user, ':')) != NULL) |
||||
*style++ = '\0'; |
||||
+#ifdef WITH_SELINUX |
||||
+ else |
||||
+ if (role && (style = strchr(role, ':')) != NULL) |
||||
+ *style++ = '\0'; |
||||
+#endif |
||||
|
||||
authctxt->user = user; |
||||
authctxt->style = style; |
||||
+#ifdef WITH_SELINUX |
||||
+ authctxt->role = role; |
||||
+#endif |
||||
|
||||
/* Verify that the user is a valid user. */ |
||||
if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) |
||||
diff --git a/auth2-gss.c b/auth2-gss.c |
||||
index c28a705..4756dd7 100644 |
||||
--- a/auth2-gss.c |
||||
+++ b/auth2-gss.c |
||||
@@ -251,6 +251,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) |
||||
Authctxt *authctxt = ctxt; |
||||
Gssctxt *gssctxt; |
||||
int authenticated = 0; |
||||
+ char *micuser; |
||||
Buffer b; |
||||
gss_buffer_desc mic, gssbuf; |
||||
u_int len; |
||||
@@ -263,7 +264,13 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) |
||||
mic.value = packet_get_string(&len); |
||||
mic.length = len; |
||||
|
||||
- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, |
||||
+#ifdef WITH_SELINUX |
||||
+ if (authctxt->role && (strlen(authctxt->role) > 0)) |
||||
+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); |
||||
+ else |
||||
+#endif |
||||
+ micuser = authctxt->user; |
||||
+ ssh_gssapi_buildmic(&b, micuser, authctxt->service, |
||||
"gssapi-with-mic"); |
||||
|
||||
gssbuf.value = buffer_ptr(&b); |
||||
@@ -275,6 +282,8 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) |
||||
logit("GSSAPI MIC check failed"); |
||||
|
||||
buffer_free(&b); |
||||
+ if (micuser != authctxt->user) |
||||
+ free(micuser); |
||||
free(mic.value); |
||||
|
||||
authctxt->postponed = 0; |
||||
diff --git a/auth2-hostbased.c b/auth2-hostbased.c |
||||
index eca0069..95d678e 100644 |
||||
--- a/auth2-hostbased.c |
||||
+++ b/auth2-hostbased.c |
||||
@@ -112,7 +112,15 @@ userauth_hostbased(Authctxt *authctxt) |
||||
buffer_put_string(&b, session_id2, session_id2_len); |
||||
/* reconstruct packet */ |
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); |
||||
- buffer_put_cstring(&b, authctxt->user); |
||||
+#ifdef WITH_SELINUX |
||||
+ if (authctxt->role) { |
||||
+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); |
||||
+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); |
||||
+ buffer_put_char(&b, '/'); |
||||
+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); |
||||
+ } else |
||||
+#endif |
||||
+ buffer_put_cstring(&b, authctxt->user); |
||||
buffer_put_cstring(&b, service); |
||||
buffer_put_cstring(&b, "hostbased"); |
||||
buffer_put_string(&b, pkalg, alen); |
||||
diff --git a/auth2-pubkey.c b/auth2-pubkey.c |
||||
index 749b11a..c0ae0d4 100644 |
||||
--- a/auth2-pubkey.c |
||||
+++ b/auth2-pubkey.c |
||||
@@ -133,9 +133,11 @@ userauth_pubkey(Authctxt *authctxt) |
||||
} |
||||
/* reconstruct packet */ |
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); |
||||
- xasprintf(&userstyle, "%s%s%s", authctxt->user, |
||||
+ xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user, |
||||
authctxt->style ? ":" : "", |
||||
- authctxt->style ? authctxt->style : ""); |
||||
+ authctxt->style ? authctxt->style : "", |
||||
+ authctxt->role ? "/" : "", |
||||
+ authctxt->role ? authctxt->role : ""); |
||||
buffer_put_cstring(&b, userstyle); |
||||
free(userstyle); |
||||
buffer_put_cstring(&b, |
||||
diff --git a/auth2.c b/auth2.c |
||||
index a5490c0..5f4f26f 100644 |
||||
--- a/auth2.c |
||||
+++ b/auth2.c |
||||
@@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) |
||||
Authctxt *authctxt = ctxt; |
||||
Authmethod *m = NULL; |
||||
char *user, *service, *method, *style = NULL; |
||||
+#ifdef WITH_SELINUX |
||||
+ char *role = NULL; |
||||
+#endif |
||||
int authenticated = 0; |
||||
|
||||
if (authctxt == NULL) |
||||
@@ -226,6 +229,11 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) |
||||
debug("userauth-request for user %s service %s method %s", user, service, method); |
||||
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+ if ((role = strchr(user, '/')) != NULL) |
||||
+ *role++ = 0; |
||||
+#endif |
||||
+ |
||||
if ((style = strchr(user, ':')) != NULL) |
||||
*style++ = 0; |
||||
|
||||
@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) |
||||
use_privsep ? " [net]" : ""); |
||||
authctxt->service = xstrdup(service); |
||||
authctxt->style = style ? xstrdup(style) : NULL; |
||||
- if (use_privsep) |
||||
+#ifdef WITH_SELINUX |
||||
+ authctxt->role = role ? xstrdup(role) : NULL; |
||||
+#endif |
||||
+ if (use_privsep) { |
||||
mm_inform_authserv(service, style); |
||||
+#ifdef WITH_SELINUX |
||||
+ mm_inform_authrole(role); |
||||
+#endif |
||||
+ } |
||||
userauth_banner(); |
||||
if (auth2_setup_methods_lists(authctxt) != 0) |
||||
packet_disconnect("no authentication methods enabled"); |
||||
diff --git a/misc.c b/misc.c |
||||
index e4c8c32..f31cd91 100644 |
||||
--- a/misc.c |
||||
+++ b/misc.c |
||||
@@ -430,6 +430,7 @@ char * |
||||
colon(char *cp) |
||||
{ |
||||
int flag = 0; |
||||
+ int start = 1; |
||||
|
||||
if (*cp == ':') /* Leading colon is part of file name. */ |
||||
return NULL; |
||||
@@ -445,6 +446,13 @@ colon(char *cp) |
||||
return (cp); |
||||
if (*cp == '/') |
||||
return NULL; |
||||
+ if (start) { |
||||
+ /* Slash on beginning or after dots only denotes file name. */ |
||||
+ if (*cp == '/') |
||||
+ return (0); |
||||
+ if (*cp != '.') |
||||
+ start = 0; |
||||
+ } |
||||
} |
||||
return NULL; |
||||
} |
||||
diff --git a/monitor.c b/monitor.c |
||||
index 531c4f9..229fada 100644 |
||||
--- a/monitor.c |
||||
+++ b/monitor.c |
||||
@@ -145,6 +145,9 @@ int mm_answer_sign(int, Buffer *); |
||||
int mm_answer_pwnamallow(int, Buffer *); |
||||
int mm_answer_auth2_read_banner(int, Buffer *); |
||||
int mm_answer_authserv(int, Buffer *); |
||||
+#ifdef WITH_SELINUX |
||||
+int mm_answer_authrole(int, Buffer *); |
||||
+#endif |
||||
int mm_answer_authpassword(int, Buffer *); |
||||
int mm_answer_bsdauthquery(int, Buffer *); |
||||
int mm_answer_bsdauthrespond(int, Buffer *); |
||||
@@ -219,6 +222,9 @@ struct mon_table mon_dispatch_proto20[] = { |
||||
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, |
||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, |
||||
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, |
||||
+#ifdef WITH_SELINUX |
||||
+ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, |
||||
+#endif |
||||
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, |
||||
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, |
||||
#ifdef USE_PAM |
||||
@@ -805,6 +811,9 @@ mm_answer_pwnamallow(int sock, Buffer *m) |
||||
else { |
||||
/* Allow service/style information on the auth context */ |
||||
monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
||||
+#ifdef WITH_SELINUX |
||||
+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); |
||||
+#endif |
||||
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
||||
} |
||||
#ifdef USE_PAM |
||||
@@ -846,6 +855,25 @@ mm_answer_authserv(int sock, Buffer *m) |
||||
return (0); |
||||
} |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+int |
||||
+mm_answer_authrole(int sock, Buffer *m) |
||||
+{ |
||||
+ monitor_permit_authentications(1); |
||||
+ |
||||
+ authctxt->role = buffer_get_string(m, NULL); |
||||
+ debug3("%s: role=%s", |
||||
+ __func__, authctxt->role); |
||||
+ |
||||
+ if (strlen(authctxt->role) == 0) { |
||||
+ free(authctxt->role); |
||||
+ authctxt->role = NULL; |
||||
+ } |
||||
+ |
||||
+ return (0); |
||||
+} |
||||
+#endif |
||||
+ |
||||
int |
||||
mm_answer_authpassword(int sock, Buffer *m) |
||||
{ |
||||
@@ -1220,7 +1248,7 @@ static int |
||||
monitor_valid_userblob(u_char *data, u_int datalen) |
||||
{ |
||||
Buffer b; |
||||
- char *p, *userstyle; |
||||
+ char *p, *r, *userstyle; |
||||
u_int len; |
||||
int fail = 0; |
||||
|
||||
@@ -1246,6 +1274,8 @@ monitor_valid_userblob(u_char *data, u_int datalen) |
||||
if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) |
||||
fail++; |
||||
p = buffer_get_cstring(&b, NULL); |
||||
+ if ((r = strchr(p, '/')) != NULL) |
||||
+ *r = '\0'; |
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user, |
||||
authctxt->style ? ":" : "", |
||||
authctxt->style ? authctxt->style : ""); |
||||
@@ -1281,7 +1311,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, |
||||
char *chost) |
||||
{ |
||||
Buffer b; |
||||
- char *p, *userstyle; |
||||
+ char *p, *r, *userstyle; |
||||
u_int len; |
||||
int fail = 0; |
||||
|
||||
@@ -1298,6 +1328,8 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, |
||||
if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) |
||||
fail++; |
||||
p = buffer_get_cstring(&b, NULL); |
||||
+ if ((r = strchr(p, '/')) != NULL) |
||||
+ *r = '\0'; |
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user, |
||||
authctxt->style ? ":" : "", |
||||
authctxt->style ? authctxt->style : ""); |
||||
diff --git a/monitor.h b/monitor.h |
||||
index 5bc41b5..20e2b4a 100644 |
||||
--- a/monitor.h |
||||
+++ b/monitor.h |
||||
@@ -57,6 +57,10 @@ enum monitor_reqtype { |
||||
MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, |
||||
MONITOR_REQ_TERM = 50, |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+ MONITOR_REQ_AUTHROLE = 80, |
||||
+#endif |
||||
+ |
||||
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, |
||||
diff --git a/monitor_wrap.c b/monitor_wrap.c |
||||
index 1a47e41..d1b6d99 100644 |
||||
--- a/monitor_wrap.c |
||||
+++ b/monitor_wrap.c |
||||
@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char *style) |
||||
buffer_free(&m); |
||||
} |
||||
|
||||
+/* Inform the privileged process about role */ |
||||
+ |
||||
+#ifdef WITH_SELINUX |
||||
+void |
||||
+mm_inform_authrole(char *role) |
||||
+{ |
||||
+ Buffer m; |
||||
+ |
||||
+ debug3("%s entering", __func__); |
||||
+ |
||||
+ buffer_init(&m); |
||||
+ buffer_put_cstring(&m, role ? role : ""); |
||||
+ |
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); |
||||
+ |
||||
+ buffer_free(&m); |
||||
+} |
||||
+#endif |
||||
+ |
||||
/* Do the password authentication */ |
||||
int |
||||
mm_auth_password(Authctxt *authctxt, char *password) |
||||
diff --git a/monitor_wrap.h b/monitor_wrap.h |
||||
index 18c2501..9d5e5ba 100644 |
||||
--- a/monitor_wrap.h |
||||
+++ b/monitor_wrap.h |
||||
@@ -42,6 +42,9 @@ int mm_is_monitor(void); |
||||
DH *mm_choose_dh(int, int, int); |
||||
int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); |
||||
void mm_inform_authserv(char *, char *); |
||||
+#ifdef WITH_SELINUX |
||||
+void mm_inform_authrole(char *); |
||||
+#endif |
||||
struct passwd *mm_getpwnamallow(const char *); |
||||
char *mm_auth2_read_banner(void); |
||||
int mm_auth_password(struct Authctxt *, char *); |
||||
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in |
||||
index 6ecfb93..b912dbe 100644 |
||||
--- a/openbsd-compat/Makefile.in |
||||
+++ b/openbsd-compat/Makefile.in |
||||
@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di |
||||
|
||||
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-sshd.o port-solaris.o port-tun.o port-uw.o |
||||
|
||||
.c.o: |
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< |
||||
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c |
||||
new file mode 100644 |
||||
index 0000000..c18524e |
||||
--- /dev/null |
||||
+++ b/openbsd-compat/port-linux-sshd.c |
||||
@@ -0,0 +1,414 @@ |
||||
+/* |
||||
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> |
||||
+ * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com> |
||||
+ * |
||||
+ * Permission to use, copy, modify, and distribute this software for any |
||||
+ * purpose with or without fee is hereby granted, provided that the above |
||||
+ * copyright notice and this permission notice appear in all copies. |
||||
+ * |
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
+ */ |
||||
+ |
||||
+/* |
||||
+ * Linux-specific portability code - just SELinux support for sshd at present |
||||
+ */ |
||||
+ |
||||
+#include "includes.h" |
||||
+ |
||||
+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) |
||||
+#include <errno.h> |
||||
+#include <stdarg.h> |
||||
+#include <string.h> |
||||
+#include <stdio.h> |
||||
+ |
||||
+#include "log.h" |
||||
+#include "xmalloc.h" |
||||
+#include "servconf.h" |
||||
+#include "port-linux.h" |
||||
+#include "key.h" |
||||
+#include "hostfile.h" |
||||
+#include "auth.h" |
||||
+ |
||||
+#ifdef WITH_SELINUX |
||||
+#include <selinux/selinux.h> |
||||
+#include <selinux/flask.h> |
||||
+#include <selinux/context.h> |
||||
+#include <selinux/get_context_list.h> |
||||
+#include <selinux/get_default_type.h> |
||||
+#include <selinux/av_permissions.h> |
||||
+ |
||||
+#ifdef HAVE_LINUX_AUDIT |
||||
+#include <libaudit.h> |
||||
+#include <unistd.h> |
||||
+#endif |
||||
+ |
||||
+extern ServerOptions options; |
||||
+extern Authctxt *the_authctxt; |
||||
+extern int inetd_flag; |
||||
+extern int rexeced_flag; |
||||
+ |
||||
+/* Send audit message */ |
||||
+static int |
||||
+sshd_selinux_send_audit_message(int success, security_context_t default_context, |
||||
+ security_context_t selected_context) |
||||
+{ |
||||
+ int rc=0; |
||||
+#ifdef HAVE_LINUX_AUDIT |
||||
+ char *msg = NULL; |
||||
+ int audit_fd = audit_open(); |
||||
+ security_context_t default_raw=NULL; |
||||
+ security_context_t selected_raw=NULL; |
||||
+ rc = -1; |
||||
+ if (audit_fd < 0) { |
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT || |
||||
+ errno == EAFNOSUPPORT) |
||||
+ return 0; /* No audit support in kernel */ |
||||
+ error("Error connecting to audit system."); |
||||
+ return rc; |
||||
+ } |
||||
+ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { |
||||
+ error("Error translating default context."); |
||||
+ default_raw = NULL; |
||||
+ } |
||||
+ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { |
||||
+ error("Error translating selected context."); |
||||
+ selected_raw = NULL; |
||||
+ } |
||||
+ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s", |
||||
+ default_raw ? default_raw : (default_context ? default_context: "?"), |
||||
+ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) { |
||||
+ error("Error allocating memory."); |
||||
+ goto out; |
||||
+ } |
||||
+ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, |
||||
+ msg, NULL, NULL, NULL, success) <= 0) { |
||||
+ error("Error sending audit message."); |
||||
+ goto out; |
||||
+ } |
||||
+ rc = 0; |
||||
+ out: |
||||
+ free(msg); |
||||
+ freecon(default_raw); |
||||
+ freecon(selected_raw); |
||||
+ close(audit_fd); |
||||
+#endif |
||||
+ return rc; |
||||
+} |
||||
+ |
||||
+static int |
||||
+mls_range_allowed(security_context_t src, security_context_t dst) |
||||
+{ |
||||
+ struct av_decision avd; |
||||
+ int retval; |
||||
+ unsigned int bit = CONTEXT__CONTAINS; |
||||
+ |
||||
+ debug("%s: src:%s dst:%s", __func__, src, dst); |
||||
+ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); |
||||
+ if (retval || ((bit & avd.allowed) != bit)) |
||||
+ return 0; |
||||
+ |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
+static int |
||||
+get_user_context(const char *sename, const char *role, const char *lvl, |
||||
+ security_context_t *sc) { |
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
||||
+ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) { |
||||
+ /* User may have requested a level completely outside of his |
||||
+ allowed range. We get a context just for auditing as the |
||||
+ range check below will certainly fail for default context. */ |
||||
+#endif |
||||
+ if (get_default_context(sename, NULL, sc) != 0) { |
||||
+ *sc = NULL; |
||||
+ return -1; |
||||
+ } |
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
||||
+ } |
||||
+#endif |
||||
+ if (role != NULL && role[0]) { |
||||
+ context_t con; |
||||
+ char *type=NULL; |
||||
+ if (get_default_type(role, &type) != 0) { |
||||
+ error("get_default_type: failed to get default type for '%s'", |
||||
+ role); |
||||
+ goto out; |
||||
+ } |
||||
+ con = context_new(*sc); |
||||
+ if (!con) { |
||||
+ goto out; |
||||
+ } |
||||
+ context_role_set(con, role); |
||||
+ context_type_set(con, type); |
||||
+ freecon(*sc); |
||||
+ *sc = strdup(context_str(con)); |
||||
+ context_free(con); |
||||
+ if (!*sc) |
||||
+ return -1; |
||||
+ } |
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
||||
+ if (lvl != NULL && lvl[0]) { |
||||
+ /* verify that the requested range is obtained */ |
||||
+ context_t con; |
||||
+ security_context_t obtained_raw; |
||||
+ security_context_t requested_raw; |
||||
+ con = context_new(*sc); |
||||
+ if (!con) { |
||||
+ goto out; |
||||
+ } |
||||
+ context_range_set(con, lvl); |
||||
+ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) { |
||||
+ context_free(con); |
||||
+ goto out; |
||||
+ } |
||||
+ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) { |
||||
+ freecon(obtained_raw); |
||||
+ context_free(con); |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ debug("get_user_context: obtained context '%s' requested context '%s'", |
||||
+ obtained_raw, requested_raw); |
||||
+ if (strcmp(obtained_raw, requested_raw)) { |
||||
+ /* set the context to the real requested one but fail */ |
||||
+ freecon(requested_raw); |
||||
+ freecon(obtained_raw); |
||||
+ freecon(*sc); |
||||
+ *sc = strdup(context_str(con)); |
||||
+ context_free(con); |
||||
+ return -1; |
||||
+ } |
||||
+ freecon(requested_raw); |
||||
+ freecon(obtained_raw); |
||||
+ context_free(con); |
||||
+ } |
||||
+#endif |
||||
+ return 0; |
||||
+ out: |
||||
+ freecon(*sc); |
||||
+ *sc = NULL; |
||||
+ return -1; |
||||
+} |
||||
+ |
||||
+static void |
||||
+ssh_selinux_get_role_level(char **role, const char **level) |
||||
+{ |
||||
+ *role = NULL; |
||||
+ *level = NULL; |
||||
+ if (the_authctxt) { |
||||
+ if (the_authctxt->role != NULL) { |
||||
+ char *slash; |
||||
+ *role = xstrdup(the_authctxt->role); |
||||
+ if ((slash = strchr(*role, '/')) != NULL) { |
||||
+ *slash = '\0'; |
||||
+ *level = slash + 1; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+} |
||||
+ |
||||
+/* Return the default security context for the given username */ |
||||
+static int |
||||
+sshd_selinux_getctxbyname(char *pwname, |
||||
+ security_context_t *default_sc, security_context_t *user_sc) |
||||
+{ |
||||
+ char *sename, *lvl; |
||||
+ char *role; |
||||
+ const char *reqlvl; |
||||
+ int r = 0; |
||||
+ context_t con = NULL; |
||||
+ |
||||
+ ssh_selinux_get_role_level(&role, &reqlvl); |
||||
+ |
||||
+#ifdef HAVE_GETSEUSERBYNAME |
||||
+ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { |
||||
+ sename = NULL; |
||||
+ lvl = NULL; |
||||
+ } |
||||
+#else |
||||
+ sename = pwname; |
||||
+ lvl = ""; |
||||
+#endif |
||||
+ |
||||
+ if (r == 0) { |
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
||||
+ r = get_default_context_with_level(sename, lvl, NULL, default_sc); |
||||
+#else |
||||
+ r = get_default_context(sename, NULL, default_sc); |
||||
+#endif |
||||
+ } |
||||
+ |
||||
+ if (r == 0) { |
||||
+ /* If launched from xinetd, we must use current level */ |
||||
+ if (inetd_flag && !rexeced_flag) { |
||||
+ security_context_t sshdsc=NULL; |
||||
+ |
||||
+ if (getcon_raw(&sshdsc) < 0) |
||||
+ fatal("failed to allocate security context"); |
||||
+ |
||||
+ if ((con=context_new(sshdsc)) == NULL) |
||||
+ fatal("failed to allocate selinux context"); |
||||
+ reqlvl = context_range_get(con); |
||||
+ freecon(sshdsc); |
||||
+ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0) |
||||
+ /* we actually don't change level */ |
||||
+ reqlvl = ""; |
||||
+ |
||||
+ debug("%s: current connection level '%s'", __func__, reqlvl); |
||||
+ |
||||
+ } |
||||
+ |
||||
+ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { |
||||
+ r = get_user_context(sename, role, reqlvl, user_sc); |
||||
+ |
||||
+ if (r == 0 && reqlvl != NULL && reqlvl[0]) { |
||||
+ security_context_t default_level_sc = *default_sc; |
||||
+ if (role != NULL && role[0]) { |
||||
+ if (get_user_context(sename, role, lvl, &default_level_sc) < 0) |
||||
+ default_level_sc = *default_sc; |
||||
+ } |
||||
+ /* verify that the requested range is contained in the user range */ |
||||
+ if (mls_range_allowed(default_level_sc, *user_sc)) { |
||||
+ logit("permit MLS level %s (user range %s)", reqlvl, lvl); |
||||
+ } else { |
||||
+ r = -1; |
||||
+ error("deny MLS level %s (user range %s)", reqlvl, lvl); |
||||
+ } |
||||
+ if (default_level_sc != *default_sc) |
||||
+ freecon(default_level_sc); |
||||
+ } |
||||
+ } else { |
||||
+ *user_sc = *default_sc; |
||||
+ } |
||||
+ } |
||||
+ if (r != 0) { |
||||
+ error("%s: Failed to get default SELinux security " |
||||
+ "context for %s", __func__, pwname); |
||||
+ } |
||||
+ |
||||
+#ifdef HAVE_GETSEUSERBYNAME |
||||
+ free(sename); |
||||
+ free(lvl); |
||||
+#endif |
||||
+ |
||||
+ if (role != NULL) |
||||
+ free(role); |
||||
+ if (con) |
||||
+ context_free(con); |
||||
+ |
||||
+ return (r); |
||||
+} |
||||
+ |
||||
+/* Setup environment variables for pam_selinux */ |
||||
+static int |
||||
+sshd_selinux_setup_pam_variables(void) |
||||
+{ |
||||
+ const char *reqlvl; |
||||
+ char *role; |
||||
+ char *use_current; |
||||
+ int rv; |
||||
+ |
||||
+ debug3("%s: setting execution context", __func__); |
||||
+ |
||||
+ ssh_selinux_get_role_level(&role, &reqlvl); |
||||
+ |
||||
+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); |
||||
+ |
||||
+ if (inetd_flag && !rexeced_flag) { |
||||
+ use_current = "1"; |
||||
+ } else { |
||||
+ use_current = ""; |
||||
+ rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); |
||||
+ } |
||||
+ |
||||
+ rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); |
||||
+ |
||||
+ if (role != NULL) |
||||
+ free(role); |
||||
+ |
||||
+ return rv; |
||||
+} |
||||
+ |
||||
+/* Set the execution context to the default for the specified user */ |
||||
+void |
||||
+sshd_selinux_setup_exec_context(char *pwname) |
||||
+{ |
||||
+ security_context_t user_ctx = NULL; |
||||
+ int r = 0; |
||||
+ security_context_t default_ctx = NULL; |
||||
+ |
||||
+ if (!ssh_selinux_enabled()) |
||||
+ return; |
||||
+ |
||||
+ if (options.use_pam) { |
||||
+ /* do not compute context, just setup environment for pam_selinux */ |
||||
+ if (sshd_selinux_setup_pam_variables()) { |
||||
+ switch (security_getenforce()) { |
||||
+ case -1: |
||||
+ fatal("%s: security_getenforce() failed", __func__); |
||||
+ case 0: |
||||
+ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", |
||||
+ __func__); |
||||
+ break; |
||||
+ default: |
||||
+ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", |
||||
+ __func__); |
||||
+ } |
||||
+ } |
||||
+ return; |
||||
+ } |
||||
+ |
||||
+ debug3("%s: setting execution context", __func__); |
||||
+ |
||||
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); |
||||
+ if (r >= 0) { |
||||
+ r = setexeccon(user_ctx); |
||||
+ if (r < 0) { |
||||
+ error("%s: Failed to set SELinux execution context %s for %s", |
||||
+ __func__, user_ctx, pwname); |
||||
+ } |
||||
+#ifdef HAVE_SETKEYCREATECON |
||||
+ else if (setkeycreatecon(user_ctx) < 0) { |
||||
+ error("%s: Failed to set SELinux keyring creation context %s for %s", |
||||
+ __func__, user_ctx, pwname); |
||||
+ } |
||||
+#endif |
||||
+ } |
||||
+ if (user_ctx == NULL) { |
||||
+ user_ctx = default_ctx; |
||||
+ } |
||||
+ if (r < 0 || user_ctx != default_ctx) { |
||||
+ /* audit just the case when user changed a role or there was |
||||
+ a failure */ |
||||
+ sshd_selinux_send_audit_message(r >= 0, default_ctx, user_ctx); |
||||
+ } |
||||
+ if (r < 0) { |
||||
+ switch (security_getenforce()) { |
||||
+ case -1: |
||||
+ fatal("%s: security_getenforce() failed", __func__); |
||||
+ case 0: |
||||
+ error("%s: SELinux failure. Continuing in permissive mode.", |
||||
+ __func__); |
||||
+ break; |
||||
+ default: |
||||
+ fatal("%s: SELinux failure. Aborting connection.", |
||||
+ __func__); |
||||
+ } |
||||
+ } |
||||
+ if (user_ctx != NULL && user_ctx != default_ctx) |
||||
+ freecon(user_ctx); |
||||
+ if (default_ctx != NULL) |
||||
+ freecon(default_ctx); |
||||
+ |
||||
+ debug3("%s: done", __func__); |
||||
+} |
||||
+ |
||||
+#endif |
||||
+#endif |
||||
+ |
||||
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c |
||||
index 4637a7a..22ea8ef 100644 |
||||
--- a/openbsd-compat/port-linux.c |
||||
+++ b/openbsd-compat/port-linux.c |
||||
@@ -103,37 +103,6 @@ ssh_selinux_getctxbyname(char *pwname) |
||||
return sc; |
||||
} |
||||
|
||||
-/* Set the execution context to the default for the specified user */ |
||||
-void |
||||
-ssh_selinux_setup_exec_context(char *pwname) |
||||
-{ |
||||
- security_context_t user_ctx = NULL; |
||||
- |
||||
- if (!ssh_selinux_enabled()) |
||||
- return; |
||||
- |
||||
- debug3("%s: setting execution context", __func__); |
||||
- |
||||
- user_ctx = ssh_selinux_getctxbyname(pwname); |
||||
- if (setexeccon(user_ctx) != 0) { |
||||
- switch (security_getenforce()) { |
||||
- case -1: |
||||
- fatal("%s: security_getenforce() failed", __func__); |
||||
- case 0: |
||||
- error("%s: Failed to set SELinux execution " |
||||
- "context for %s", __func__, pwname); |
||||
- break; |
||||
- default: |
||||
- fatal("%s: Failed to set SELinux execution context " |
||||
- "for %s (in enforcing mode)", __func__, pwname); |
||||
- } |
||||
- } |
||||
- if (user_ctx != NULL) |
||||
- freecon(user_ctx); |
||||
- |
||||
- debug3("%s: done", __func__); |
||||
-} |
||||
- |
||||
/* Set the TTY context for the specified user */ |
||||
void |
||||
ssh_selinux_setup_pty(char *pwname, const char *tty) |
||||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h |
||||
index e3d1004..8ef6cc4 100644 |
||||
--- a/openbsd-compat/port-linux.h |
||||
+++ b/openbsd-compat/port-linux.h |
||||
@@ -22,9 +22,10 @@ |
||||
#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 *); |
||||
+ |
||||
+void sshd_selinux_setup_exec_context(char *); |
||||
#endif |
||||
|
||||
#ifdef LINUX_OOM_ADJUST |
||||
diff --git a/platform.c b/platform.c |
||||
index 30fc609..0d39ab2 100644 |
||||
--- a/platform.c |
||||
+++ b/platform.c |
||||
@@ -183,7 +183,7 @@ platform_setusercontext_post_groups(struct passwd *pw) |
||||
} |
||||
#endif /* HAVE_SETPCRED */ |
||||
#ifdef WITH_SELINUX |
||||
- ssh_selinux_setup_exec_context(pw->pw_name); |
||||
+ sshd_selinux_setup_exec_context(pw->pw_name); |
||||
#endif |
||||
} |
||||
|
||||
diff --git a/sshd.c b/sshd.c |
||||
index 7523de9..07f9926 100644 |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -2138,6 +2138,9 @@ main(int ac, char **av) |
||||
restore_uid(); |
||||
} |
||||
#endif |
||||
+#ifdef WITH_SELINUX |
||||
+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name); |
||||
+#endif |
||||
#ifdef USE_PAM |
||||
if (options.use_pam) { |
||||
do_pam_setcred(1); |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
Zseries only: Leave the hardware filedescriptors open. |
||||
|
||||
All filedescriptors above 2 are getting closed when a new |
||||
sshd process to handle a new client connection is |
||||
spawned. As the process also chroot into an empty filesystem |
||||
without any device nodes, there is no chance to reopen the |
||||
files. This patch filters out the reqired fds in the |
||||
closefrom function so these are skipped in the close loop. |
||||
|
||||
Author: Harald Freudenberger <freude@de.ibm.com> |
||||
|
||||
--- |
||||
openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++ |
||||
1 file changed, 26 insertions(+) |
||||
|
||||
--- a/openbsd-compat/bsd-closefrom.c |
||||
+++ b/openbsd-compat/bsd-closefrom.c |
||||
@@ -82,7 +82,33 @@ closefrom(int lowfd) |
||||
fd = strtol(dent->d_name, &endp, 10); |
||||
if (dent->d_name != endp && *endp == '\0' && |
||||
fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) |
||||
+#ifdef __s390__ |
||||
+ { |
||||
+ /* |
||||
+ * the filedescriptors used to communicate with |
||||
+ * the device drivers to provide hardware support |
||||
+ * should survive. HF <freude@de.ibm.com> |
||||
+ */ |
||||
+ char fpath[PATH_MAX], lpath[PATH_MAX]; |
||||
+ len = snprintf(fpath, sizeof(fpath), "%s/%s", |
||||
+ fdpath, dent->d_name); |
||||
+ if (len > 0 && (size_t)len <= sizeof(fpath)) { |
||||
+ len = readlink(fpath, lpath, sizeof(lpath)); |
||||
+ if (len > 0) { |
||||
+ lpath[len] = 0; |
||||
+ if (strstr(lpath, "dev/z90crypt") |
||||
+ || strstr(lpath, "dev/zcrypt") |
||||
+ || strstr(lpath, "dev/prandom") |
||||
+ || strstr(lpath, "dev/shm/icastats")) |
||||
+ fd = -1; |
||||
+ } |
||||
+ } |
||||
+ if (fd >= 0) |
||||
+ (void) close((int) fd); |
||||
+ } |
||||
+#else |
||||
(void) close((int) fd); |
||||
+#endif |
||||
} |
||||
(void) closedir(dirp); |
||||
} else |
||||
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
diff --git a/monitor.c b/monitor.c |
||||
index b410965..f1b873d 100644 |
||||
--- a/monitor.c |
||||
+++ b/monitor.c |
||||
@@ -1084,9 +1084,7 @@ extern KbdintDevice sshpam_device; |
||||
int |
||||
mm_answer_pam_init_ctx(int sock, Buffer *m) |
||||
{ |
||||
- |
||||
debug3("%s", __func__); |
||||
- authctxt->user = buffer_get_string(m, NULL); |
||||
sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); |
||||
sshpam_authok = NULL; |
||||
buffer_clear(m); |
||||
@@ -1166,14 +1166,16 @@ mm_answer_pam_respond(int sock, Buffer *m) |
||||
int |
||||
mm_answer_pam_free_ctx(int sock, Buffer *m) |
||||
{ |
||||
+ int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; |
||||
|
||||
debug3("%s", __func__); |
||||
(sshpam_device.free_ctx)(sshpam_ctxt); |
||||
+ sshpam_ctxt = sshpam_authok = NULL; |
||||
buffer_clear(m); |
||||
mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); |
||||
auth_method = "keyboard-interactive"; |
||||
auth_submethod = "pam"; |
||||
- return (sshpam_authok == sshpam_ctxt); |
||||
+ return r; |
||||
} |
||||
#endif |
||||
|
||||
diff --git a/monitor_wrap.c b/monitor_wrap.c |
||||
index e6217b3..eac421b 100644 |
||||
--- a/monitor_wrap.c |
||||
+++ b/monitor_wrap.c |
||||
@@ -614,7 +614,6 @@ mm_sshpam_init_ctx(Authctxt *authctxt) |
||||
|
||||
debug3("%s", __func__); |
||||
buffer_init(&m); |
||||
- buffer_put_cstring(&m, authctxt->user); |
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); |
||||
debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); |
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); |
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
diff --git a/canohost.c b/canohost.c |
||||
index 97ce58c..1f9320a 100644 |
||||
--- a/canohost.c |
||||
+++ b/canohost.c |
||||
@@ -338,6 +338,21 @@ clear_cached_addr(void) |
||||
cached_port = -1; |
||||
} |
||||
|
||||
+void set_remote_ipaddr(void) { |
||||
+ if (canonical_host_ip != NULL) |
||||
+ free(canonical_host_ip); |
||||
+ |
||||
+ if (packet_connection_is_on_socket()) { |
||||
+ canonical_host_ip = |
||||
+ get_peer_ipaddr(packet_get_connection_in()); |
||||
+ if (canonical_host_ip == NULL) |
||||
+ cleanup_exit(255); |
||||
+ } else { |
||||
+ /* If not on socket, return UNKNOWN. */ |
||||
+ canonical_host_ip = xstrdup("UNKNOWN"); |
||||
+ } |
||||
+} |
||||
+ |
||||
/* |
||||
* Returns the IP-address of the remote host as a string. The returned |
||||
* string must not be freed. |
||||
@@ -347,17 +362,9 @@ const char * |
||||
get_remote_ipaddr(void) |
||||
{ |
||||
/* Check whether we have cached the ipaddr. */ |
||||
- if (canonical_host_ip == NULL) { |
||||
- if (packet_connection_is_on_socket()) { |
||||
- canonical_host_ip = |
||||
- get_peer_ipaddr(packet_get_connection_in()); |
||||
- if (canonical_host_ip == NULL) |
||||
- cleanup_exit(255); |
||||
- } else { |
||||
- /* If not on socket, return UNKNOWN. */ |
||||
- canonical_host_ip = xstrdup("UNKNOWN"); |
||||
- } |
||||
- } |
||||
+ if (canonical_host_ip == NULL) |
||||
+ set_remote_ipaddr(); |
||||
+ |
||||
return canonical_host_ip; |
||||
} |
||||
|
||||
diff --git a/canohost.h b/canohost.h |
||||
index 4c8636f..4079953 100644 |
||||
--- a/canohost.h |
||||
+++ b/canohost.h |
||||
@@ -13,6 +13,7 @@ |
||||
*/ |
||||
|
||||
const char *get_canonical_hostname(int); |
||||
+void set_remote_ipaddr(void); |
||||
const char *get_remote_ipaddr(void); |
||||
const char *get_remote_name_or_ip(u_int, int); |
||||
|
||||
diff --git a/sshconnect.c b/sshconnect.c |
||||
index e636f33..451a58b 100644 |
||||
--- a/sshconnect.c |
||||
+++ b/sshconnect.c |
||||
@@ -62,6 +62,7 @@ |
||||
#include "monitor_fdpass.h" |
||||
#include "ssh2.h" |
||||
#include "version.h" |
||||
+#include "canohost.h" |
||||
|
||||
char *client_version_string = NULL; |
||||
char *server_version_string = NULL; |
||||
@@ -170,6 +171,7 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, |
||||
|
||||
/* Set the connection file descriptors. */ |
||||
packet_set_connection(sock, sock); |
||||
+ set_remote_ipaddr(); |
||||
|
||||
return 0; |
||||
} |
||||
@@ -492,6 +494,7 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, |
||||
|
||||
/* Set the connection. */ |
||||
packet_set_connection(sock, sock); |
||||
+ set_remote_ipaddr(); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,98 @@
@@ -0,0 +1,98 @@
|
||||
diff -up openssh-7.4p1/sftp-server.8.sftp-force-mode openssh-7.4p1/sftp-server.8 |
||||
--- openssh-7.4p1/sftp-server.8.sftp-force-mode 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/sftp-server.8 2017-02-09 10:35:41.926475399 +0100 |
||||
@@ -38,6 +38,7 @@ |
||||
.Op Fl P Ar blacklisted_requests |
||||
.Op Fl p Ar whitelisted_requests |
||||
.Op Fl u Ar umask |
||||
+.Op Fl m Ar force_file_perms |
||||
.Ek |
||||
.Nm |
||||
.Fl Q Ar protocol_feature |
||||
@@ -138,6 +139,10 @@ 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_perms |
||||
+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 |
||||
On some systems, |
||||
diff -up openssh-7.4p1/sftp-server.c.sftp-force-mode openssh-7.4p1/sftp-server.c |
||||
--- openssh-7.4p1/sftp-server.c.sftp-force-mode 2017-02-09 10:22:36.498019921 +0100 |
||||
+++ openssh-7.4p1/sftp-server.c 2017-02-09 10:35:07.190520959 +0100 |
||||
@@ -65,6 +65,10 @@ struct sshbuf *oqueue; |
||||
/* Version of client */ |
||||
static u_int version; |
||||
|
||||
+/* Force file permissions */ |
||||
+int permforce = 0; |
||||
+long permforcemode; |
||||
+ |
||||
/* SSH2_FXP_INIT received */ |
||||
static int init_done; |
||||
|
||||
@@ -679,6 +683,7 @@ process_open(u_int32_t id) |
||||
Attrib a; |
||||
char *name; |
||||
int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; |
||||
+ mode_t old_umask = 0; |
||||
|
||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || |
||||
(r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ |
||||
@@ -688,6 +693,10 @@ process_open(u_int32_t id) |
||||
debug3("request %u: open flags %d", id, pflags); |
||||
flags = flags_from_portable(pflags); |
||||
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; |
||||
+ if (permforce == 1) { /* Force perm if -m is set */ |
||||
+ mode = permforcemode; |
||||
+ old_umask = umask(0); /* so umask does not interfere */ |
||||
+ } |
||||
logit("open \"%s\" flags %s mode 0%o", |
||||
name, string_from_portable(pflags), mode); |
||||
if (readonly && |
||||
@@ -709,6 +718,8 @@ process_open(u_int32_t id) |
||||
} |
||||
} |
||||
} |
||||
+ if (permforce == 1) |
||||
+ (void) umask(old_umask); /* restore umask to something sane */ |
||||
if (status != SSH2_FX_OK) |
||||
send_status(id, status); |
||||
free(name); |
||||
@@ -1490,7 +1501,7 @@ sftp_server_usage(void) |
||||
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] [-m force_file_perms]\n" |
||||
" %s -Q protocol_feature\n", |
||||
__progname, __progname); |
||||
exit(1); |
||||
@@ -1516,7 +1527,7 @@ sftp_server_main(int argc, char **argv, |
||||
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) { |
||||
@@ -1576,6 +1587,15 @@ sftp_server_main(int argc, char **argv, |
||||
fatal("Invalid umask \"%s\"", optarg); |
||||
(void)umask((mode_t)mask); |
||||
break; |
||||
+ case 'm': |
||||
+ /* Force permissions on file received via sftp */ |
||||
+ permforce = 1; |
||||
+ permforcemode = strtol(optarg, &cp, 8); |
||||
+ if (permforcemode < 0 || permforcemode > 0777 || |
||||
+ *cp != '\0' || (permforcemode == 0 && |
||||
+ errno != 0)) |
||||
+ fatal("Invalid file mode \"%s\"", optarg); |
||||
+ break; |
||||
case 'h': |
||||
default: |
||||
sftp_server_usage(); |
@ -0,0 +1,214 @@
@@ -0,0 +1,214 @@
|
||||
diff -up openssh-6.6p1/channels.c.security openssh-6.6p1/channels.c |
||||
--- openssh-6.6p1/channels.c.security 2015-07-01 19:27:08.521162690 +0200 |
||||
+++ openssh-6.6p1/channels.c 2015-07-01 19:27:08.597162521 +0200 |
||||
@@ -151,6 +151,9 @@ static char *x11_saved_proto = NULL; |
||||
static char *x11_saved_data = NULL; |
||||
static u_int x11_saved_data_len = 0; |
||||
|
||||
+/* Deadline after which all X11 connections are refused */ |
||||
+static u_int x11_refuse_time; |
||||
+ |
||||
/* |
||||
* Fake X11 authentication data. This is what the server will be sending us; |
||||
* we should replace any occurrences of this by the real data. |
||||
@@ -894,6 +897,13 @@ x11_open_helper(Buffer *b) |
||||
u_char *ucp; |
||||
u_int proto_len, data_len; |
||||
|
||||
+ /* Is this being called after the refusal deadline? */ |
||||
+ if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) { |
||||
+ verbose("Rejected X11 connection after ForwardX11Timeout " |
||||
+ "expired"); |
||||
+ return -1; |
||||
+ } |
||||
+ |
||||
/* Check if the fixed size part of the packet is in buffer. */ |
||||
if (buffer_len(b) < 12) |
||||
return 0; |
||||
@@ -1457,6 +1467,12 @@ channel_set_reuseaddr(int fd) |
||||
error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); |
||||
} |
||||
|
||||
+void |
||||
+channel_set_x11_refuse_time(u_int refuse_time) |
||||
+{ |
||||
+ x11_refuse_time = refuse_time; |
||||
+} |
||||
+ |
||||
/* |
||||
* This socket is listening for connections to a forwarded TCP/IP port. |
||||
*/ |
||||
diff -up openssh-6.6p1/channels.h.security openssh-6.6p1/channels.h |
||||
--- openssh-6.6p1/channels.h.security 2015-07-01 19:27:08.597162521 +0200 |
||||
+++ openssh-6.6p1/channels.h 2015-07-01 19:43:32.900950560 +0200 |
||||
@@ -279,6 +279,7 @@ int permitopen_port(const char *); |
||||
|
||||
/* x11 forwarding */ |
||||
|
||||
+void channel_set_x11_refuse_time(u_int); |
||||
int x11_connect_display(void); |
||||
int x11_create_display_inet(int, int, int, u_int *, int **); |
||||
void x11_input_open(int, u_int32_t, void *); |
||||
diff -up openssh-6.6p1/clientloop.c.security openssh-6.6p1/clientloop.c |
||||
--- openssh-6.6p1/clientloop.c.security 2015-07-01 19:27:08.540162648 +0200 |
||||
+++ openssh-6.6p1/clientloop.c 2015-07-01 19:44:51.139761508 +0200 |
||||
@@ -164,7 +164,7 @@ static int connection_in; /* Connection |
||||
static int connection_out; /* Connection to server (output). */ |
||||
static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
||||
static int session_closed; /* In SSH2: login session closed. */ |
||||
-static int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ |
||||
+static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ |
||||
|
||||
static void client_init_dispatch(void); |
||||
int session_ident = -1; |
||||
@@ -302,7 +302,8 @@ client_x11_display_valid(const char *dis |
||||
return 1; |
||||
} |
||||
|
||||
-#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" |
||||
+#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" |
||||
+#define X11_TIMEOUT_SLACK 60 |
||||
void |
||||
client_x11_get_proto(const char *display, const char *xauth_path, |
||||
u_int trusted, u_int timeout, char **_proto, char **_data) |
||||
@@ -315,7 +316,7 @@ client_x11_get_proto(const char *display |
||||
int got_data = 0, generated = 0, do_unlink = 0, i; |
||||
char *xauthdir, *xauthfile; |
||||
struct stat st; |
||||
- u_int now; |
||||
+ u_int now, x11_timeout_real; |
||||
|
||||
xauthdir = xauthfile = NULL; |
||||
*_proto = proto; |
||||
@@ -348,6 +349,15 @@ client_x11_get_proto(const char *display |
||||
xauthdir = xmalloc(MAXPATHLEN); |
||||
xauthfile = xmalloc(MAXPATHLEN); |
||||
mktemp_proto(xauthdir, MAXPATHLEN); |
||||
+ /* |
||||
+ * The authentication cookie should briefly outlive |
||||
+ * ssh's willingness to forward X11 connections to |
||||
+ * avoid nasty fail-open behaviour in the X server. |
||||
+ */ |
||||
+ if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK) |
||||
+ x11_timeout_real = UINT_MAX; |
||||
+ else |
||||
+ x11_timeout_real = timeout + X11_TIMEOUT_SLACK; |
||||
if (mkdtemp(xauthdir) != NULL) { |
||||
do_unlink = 1; |
||||
snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", |
||||
@@ -355,17 +365,20 @@ client_x11_get_proto(const char *display |
||||
snprintf(cmd, sizeof(cmd), |
||||
"%s -f %s generate %s " SSH_X11_PROTO |
||||
" untrusted timeout %u 2>" _PATH_DEVNULL, |
||||
- xauth_path, xauthfile, display, timeout); |
||||
+ xauth_path, xauthfile, display, |
||||
+ x11_timeout_real); |
||||
debug2("x11_get_proto: %s", cmd); |
||||
- if (system(cmd) == 0) |
||||
- generated = 1; |
||||
if (x11_refuse_time == 0) { |
||||
now = monotime() + 1; |
||||
if (UINT_MAX - timeout < now) |
||||
x11_refuse_time = UINT_MAX; |
||||
else |
||||
x11_refuse_time = now + timeout; |
||||
+ channel_set_x11_refuse_time( |
||||
+ x11_refuse_time); |
||||
} |
||||
+ if (system(cmd) == 0) |
||||
+ generated = 1; |
||||
} |
||||
} |
||||
|
||||
@@ -1884,7 +1897,7 @@ client_request_x11(const char *request_t |
||||
"malicious server."); |
||||
return NULL; |
||||
} |
||||
- if (x11_refuse_time != 0 && monotime() >= x11_refuse_time) { |
||||
+ if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) { |
||||
verbose("Rejected X11 connection after ForwardX11Timeout " |
||||
"expired"); |
||||
return NULL; |
||||
diff -up openssh-6.6p1/ssh-agent.c.security openssh-6.6p1/ssh-agent.c |
||||
--- openssh-6.6p1/ssh-agent.c.security 2015-07-01 19:27:08.597162521 +0200 |
||||
+++ openssh-6.6p1/ssh-agent.c 2015-07-01 19:42:35.691088800 +0200 |
||||
@@ -64,6 +64,9 @@ |
||||
#include <time.h> |
||||
#include <string.h> |
||||
#include <unistd.h> |
||||
+#ifdef HAVE_UTIL_H |
||||
+#include <util.h> |
||||
+#endif |
||||
|
||||
#include "xmalloc.h" |
||||
#include "ssh.h" |
||||
@@ -129,8 +130,12 @@ char socket_name[MAXPATHLEN]; |
||||
char socket_dir[MAXPATHLEN]; |
||||
|
||||
/* locking */ |
||||
+#define LOCK_SIZE 32 |
||||
+#define LOCK_SALT_SIZE 16 |
||||
+#define LOCK_ROUNDS 1 |
||||
int locked = 0; |
||||
-char *lock_passwd = NULL; |
||||
+char lock_passwd[LOCK_SIZE]; |
||||
+char lock_salt[LOCK_SALT_SIZE]; |
||||
|
||||
extern char *__progname; |
||||
|
||||
@@ -548,22 +553,45 @@ send: |
||||
static void |
||||
process_lock_agent(SocketEntry *e, int lock) |
||||
{ |
||||
- int success = 0; |
||||
- char *passwd; |
||||
+ int success = 0, delay; |
||||
+ char *passwd, passwdhash[LOCK_SIZE]; |
||||
+ static u_int fail_count = 0; |
||||
+ size_t pwlen; |
||||
|
||||
passwd = buffer_get_string(&e->request, NULL); |
||||
- if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { |
||||
- locked = 0; |
||||
- explicit_bzero(lock_passwd, strlen(lock_passwd)); |
||||
- free(lock_passwd); |
||||
- lock_passwd = NULL; |
||||
- success = 1; |
||||
+ pwlen = strlen(passwd); |
||||
+ if (pwlen == 0) { |
||||
+ debug("empty password not supported"); |
||||
+ } else if (locked && !lock) { |
||||
+ if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt), |
||||
+ passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0) |
||||
+ fatal("bcrypt_pbkdf"); |
||||
+ if (timingsafe_bcmp(passwdhash, lock_passwd, LOCK_SIZE) == 0) { |
||||
+ debug("agent unlocked"); |
||||
+ locked = 0; |
||||
+ fail_count = 0; |
||||
+ explicit_bzero(lock_passwd, sizeof(lock_passwd)); |
||||
+ success = 1; |
||||
+ } else { |
||||
+ /* delay in 0.1s increments up to 10s */ |
||||
+ if (fail_count < 100) |
||||
+ fail_count++; |
||||
+ delay = 100000 * fail_count; |
||||
+ debug("unlock failed, delaying %0.1lf seconds", |
||||
+ (double)delay/1000000); |
||||
+ usleep(delay); |
||||
+ } |
||||
+ explicit_bzero(passwdhash, sizeof(passwdhash)); |
||||
} else if (!locked && lock) { |
||||
+ debug("agent locked"); |
||||
locked = 1; |
||||
- lock_passwd = xstrdup(passwd); |
||||
+ arc4random_buf(lock_salt, sizeof(lock_salt)); |
||||
+ if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt), |
||||
+ lock_passwd, sizeof(lock_passwd), LOCK_ROUNDS) < 0) |
||||
+ fatal("bcrypt_pbkdf"); |
||||
success = 1; |
||||
} |
||||
- explicit_bzero(passwd, strlen(passwd)); |
||||
+ explicit_bzero(passwd, pwlen); |
||||
free(passwd); |
||||
|
||||
buffer_put_int(&e->output, 1); |
@ -0,0 +1,98 @@
@@ -0,0 +1,98 @@
|
||||
commit 0e22b79bfde45a7cf7a2e51a68ec11c4285f3b31 |
||||
Author: Jakub Jelen <jjelen@redhat.com> |
||||
Date: Mon Nov 21 15:04:06 2016 +0100 |
||||
|
||||
systemd stuff |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index 2ffc369..162ce92 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -4265,6 +4265,30 @@ AC_ARG_WITH([kerberos5], |
||||
AC_SUBST([GSSLIBS]) |
||||
AC_SUBST([K5LIBS]) |
||||
|
||||
+# Check whether user wants systemd support |
||||
+SYSTEMD_MSG="no" |
||||
+AC_ARG_WITH(systemd, |
||||
+ [ --with-systemd Enable systemd support], |
||||
+ [ if test "x$withval" != "xno" ; then |
||||
+ AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no]) |
||||
+ if test "$PKGCONFIG" != "no"; then |
||||
+ AC_MSG_CHECKING([for libsystemd]) |
||||
+ if $PKGCONFIG --exists libsystemd; then |
||||
+ SYSTEMD_CFLAGS=`$PKGCONFIG --cflags libsystemd` |
||||
+ SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd` |
||||
+ CPPFLAGS="$CPPFLAGS $SYSTEMD_CFLAGS" |
||||
+ SSHDLIBS="$SSHDLIBS $SYSTEMD_LIBS" |
||||
+ AC_MSG_RESULT([yes]) |
||||
+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if you want systemd support.]) |
||||
+ SYSTEMD_MSG="yes" |
||||
+ else |
||||
+ AC_MSG_RESULT([no]) |
||||
+ fi |
||||
+ fi |
||||
+ fi ] |
||||
+) |
||||
+ |
||||
+ |
||||
# Looking for programs, paths and files |
||||
|
||||
PRIVSEP_PATH=/var/empty |
||||
@@ -5097,6 +5121,7 @@ echo " libedit support: $LIBEDIT_MSG" |
||||
echo " Solaris process contract support: $SPC_MSG" |
||||
echo " Solaris project support: $SP_MSG" |
||||
echo " Solaris privilege support: $SPP_MSG" |
||||
+echo " systemd support: $SYSTEMD_MSG" |
||||
echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" |
||||
echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" |
||||
echo " BSD Auth support: $BSD_AUTH_MSG" |
||||
diff --git a/contrib/sshd.service b/contrib/sshd.service |
||||
new file mode 100644 |
||||
index 0000000..e0d4923 |
||||
--- /dev/null |
||||
+++ b/contrib/sshd.service |
||||
@@ -0,0 +1,16 @@ |
||||
+[Unit] |
||||
+Description=OpenSSH server daemon |
||||
+Documentation=man:sshd(8) man:sshd_config(5) |
||||
+After=network.target |
||||
+ |
||||
+[Service] |
||||
+Type=notify |
||||
+ExecStart=/usr/sbin/sshd -D $OPTIONS |
||||
+ExecReload=/bin/kill -HUP $MAINPID |
||||
+KillMode=process |
||||
+Restart=on-failure |
||||
+RestartPreventExitStatus=255 |
||||
+ |
||||
+[Install] |
||||
+WantedBy=multi-user.target |
||||
+ |
||||
diff --git a/sshd.c b/sshd.c |
||||
index 816611c..b8b9d13 100644 |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -85,6 +85,10 @@ |
||||
#include <prot.h> |
||||
#endif |
||||
|
||||
+#ifdef HAVE_SYSTEMD |
||||
+#include <systemd/sd-daemon.h> |
||||
+#endif |
||||
+ |
||||
#include "xmalloc.h" |
||||
#include "ssh.h" |
||||
#include "ssh2.h" |
||||
@@ -1833,6 +1837,11 @@ main(int ac, char **av) |
||||
} |
||||
} |
||||
|
||||
+#ifdef HAVE_SYSTEMD |
||||
+ /* Signal systemd that we are ready to accept connections */ |
||||
+ sd_notify(0, "READY=1"); |
||||
+#endif |
||||
+ |
||||
/* Accept a connection and return in a forked child */ |
||||
server_accept_loop(&sock_in, &sock_out, |
||||
&newsock, config_s); |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
diff -up openssh-7.4p1/servconf.c.sshd-t openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.sshd-t 2017-02-09 10:19:56.859306131 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-09 10:22:07.895104402 +0100 |
||||
@@ -2337,7 +2337,7 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_string(sXAuthLocation, o->xauth_location); |
||||
dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); |
||||
dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); |
||||
- dump_cfg_string(sBanner, o->banner); |
||||
+ dump_cfg_string(sBanner, o->banner == NULL ? "none" : o->banner); |
||||
dump_cfg_string(sForceCommand, o->adm_forced_command); |
||||
dump_cfg_string(sChrootDirectory, o->chroot_directory); |
||||
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); |
||||
diff -up openssh-7.4p1/ssh.1.sshd-t openssh-7.4p1/ssh.1 |
||||
--- openssh-7.4p1/ssh.1.sshd-t 2017-02-09 10:19:56.823306172 +0100 |
||||
+++ openssh-7.4p1/ssh.1 2017-02-09 10:19:56.859306131 +0100 |
||||
@@ -512,7 +512,11 @@ For full details of the options listed b |
||||
.It GatewayPorts |
||||
.It GlobalKnownHostsFile |
||||
.It GSSAPIAuthentication |
||||
+.It GSSAPIKeyExchange |
||||
+.It GSSAPIClientIdentity |
||||
.It GSSAPIDelegateCredentials |
||||
+.It GSSAPIRenewalForcesRekey |
||||
+.It GSSAPITrustDns |
||||
.It HashKnownHosts |
||||
.It Host |
||||
.It HostbasedAuthentication |
@ -0,0 +1,214 @@
@@ -0,0 +1,214 @@
|
||||
diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c |
||||
--- openssh-7.4p1/channels.c.x11max 2017-02-09 12:49:04.690996627 +0100 |
||||
+++ openssh-7.4p1/channels.c 2017-02-09 12:49:04.744996547 +0100 |
||||
@@ -152,8 +152,8 @@ static int all_opens_permitted = 0; |
||||
|
||||
/* -- X11 forwarding */ |
||||
|
||||
-/* Maximum number of fake X11 displays to try. */ |
||||
-#define MAX_DISPLAYS 1000 |
||||
+/* Minimum port number for X11 forwarding */ |
||||
+#define X11_PORT_MIN 6000 |
||||
|
||||
/* Saved X11 local (client) display. */ |
||||
static char *x11_saved_display = NULL; |
||||
@@ -4228,7 +4228,8 @@ channel_send_window_changes(void) |
||||
*/ |
||||
int |
||||
x11_create_display_inet(int x11_display_offset, int x11_use_localhost, |
||||
- int single_connection, u_int *display_numberp, int **chanids) |
||||
+ int x11_max_displays, int single_connection, u_int *display_numberp, |
||||
+ int **chanids) |
||||
{ |
||||
Channel *nc = NULL; |
||||
int display_number, sock; |
||||
@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_ |
||||
if (chanids == NULL) |
||||
return -1; |
||||
|
||||
+ /* Try to bind ports starting at 6000+X11DisplayOffset */ |
||||
+ x11_max_displays = x11_max_displays + x11_display_offset; |
||||
+ |
||||
for (display_number = x11_display_offset; |
||||
- display_number < MAX_DISPLAYS; |
||||
+ display_number < x11_max_displays; |
||||
display_number++) { |
||||
- port = 6000 + display_number; |
||||
+ port = X11_PORT_MIN + display_number; |
||||
+ if (port < X11_PORT_MIN) /* overflow */ |
||||
+ break; |
||||
memset(&hints, 0, sizeof(hints)); |
||||
hints.ai_family = IPv4or6; |
||||
hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; |
||||
@@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_ |
||||
if (num_socks > 0) |
||||
break; |
||||
} |
||||
- if (display_number >= MAX_DISPLAYS) { |
||||
+ if (display_number >= x11_max_displays || port < X11_PORT_MIN ) { |
||||
error("Failed to allocate internet-domain X11 display socket."); |
||||
return -1; |
||||
} |
||||
@@ -4441,7 +4447,7 @@ x11_connect_display(void) |
||||
memset(&hints, 0, sizeof(hints)); |
||||
hints.ai_family = IPv4or6; |
||||
hints.ai_socktype = SOCK_STREAM; |
||||
- snprintf(strport, sizeof strport, "%u", 6000 + display_number); |
||||
+ snprintf(strport, sizeof strport, "%u", X11_PORT_MIN + display_number); |
||||
if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { |
||||
error("%.100s: unknown host. (%s)", buf, |
||||
ssh_gai_strerror(gaierr)); |
||||
@@ -4457,7 +4463,7 @@ x11_connect_display(void) |
||||
/* Connect it to the display. */ |
||||
if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { |
||||
debug2("connect %.100s port %u: %.100s", buf, |
||||
- 6000 + display_number, strerror(errno)); |
||||
+ X11_PORT_MIN + display_number, strerror(errno)); |
||||
close(sock); |
||||
continue; |
||||
} |
||||
@@ -4466,8 +4472,8 @@ x11_connect_display(void) |
||||
} |
||||
freeaddrinfo(aitop); |
||||
if (!ai) { |
||||
- error("connect %.100s port %u: %.100s", buf, 6000 + display_number, |
||||
- strerror(errno)); |
||||
+ error("connect %.100s port %u: %.100s", buf, |
||||
+ X11_PORT_MIN + display_number, strerror(errno)); |
||||
return -1; |
||||
} |
||||
set_nodelay(sock); |
||||
diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h |
||||
--- openssh-7.4p1/channels.h.x11max 2017-02-09 12:49:04.744996547 +0100 |
||||
+++ openssh-7.4p1/channels.h 2017-02-09 12:49:50.230929693 +0100 |
||||
@@ -293,7 +293,7 @@ int permitopen_port(const char *); |
||||
|
||||
void channel_set_x11_refuse_time(u_int); |
||||
int x11_connect_display(void); |
||||
-int x11_create_display_inet(int, int, int, u_int *, int **); |
||||
+int x11_create_display_inet(int, int, int, int, u_int *, int **); |
||||
int x11_input_open(int, u_int32_t, void *); |
||||
void x11_request_forwarding_with_spoofing(int, const char *, const char *, |
||||
const char *, int); |
||||
diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.x11max 2017-02-09 12:49:04.741996552 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-09 12:51:03.167822492 +0100 |
||||
@@ -94,6 +94,7 @@ initialize_server_options(ServerOptions |
||||
options->print_lastlog = -1; |
||||
options->x11_forwarding = -1; |
||||
options->x11_display_offset = -1; |
||||
+ options->x11_max_displays = -1; |
||||
options->x11_use_localhost = -1; |
||||
options->permit_tty = -1; |
||||
options->permit_user_rc = -1; |
||||
@@ -242,6 +243,8 @@ fill_default_server_options(ServerOption |
||||
options->x11_forwarding = 0; |
||||
if (options->x11_display_offset == -1) |
||||
options->x11_display_offset = 10; |
||||
+ if (options->x11_max_displays == -1) |
||||
+ options->x11_max_displays = DEFAULT_MAX_DISPLAYS; |
||||
if (options->x11_use_localhost == -1) |
||||
options->x11_use_localhost = 1; |
||||
if (options->xauth_location == NULL) |
||||
@@ -416,7 +419,7 @@ typedef enum { |
||||
sPasswordAuthentication, sKbdInteractiveAuthentication, |
||||
sListenAddress, sAddressFamily, |
||||
sPrintMotd, sPrintLastLog, sIgnoreRhosts, |
||||
- sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, |
||||
+ sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost, |
||||
sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, |
||||
sPermitUserEnvironment, sAllowTcpForwarding, sCompression, |
||||
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, |
||||
@@ -537,6 +540,7 @@ static struct { |
||||
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, |
||||
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL }, |
||||
{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, |
||||
+ { "x11maxdisplays", sX11MaxDisplays, SSHCFG_ALL }, |
||||
{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, |
||||
{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, |
||||
{ "strictmodes", sStrictModes, SSHCFG_GLOBAL }, |
||||
@@ -1313,6 +1317,10 @@ process_server_config_line(ServerOptions |
||||
*intptr = value; |
||||
break; |
||||
|
||||
+ case sX11MaxDisplays: |
||||
+ intptr = &options->x11_max_displays; |
||||
+ goto parse_int; |
||||
+ |
||||
case sX11UseLocalhost: |
||||
intptr = &options->x11_use_localhost; |
||||
goto parse_flag; |
||||
@@ -2060,6 +2068,7 @@ copy_set_server_options(ServerOptions *d |
||||
M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); |
||||
M_CP_INTOPT(x11_display_offset); |
||||
M_CP_INTOPT(x11_forwarding); |
||||
+ M_CP_INTOPT(x11_max_displays); |
||||
M_CP_INTOPT(x11_use_localhost); |
||||
M_CP_INTOPT(permit_tty); |
||||
M_CP_INTOPT(permit_user_rc); |
||||
@@ -2312,6 +2321,7 @@ dump_config(ServerOptions *o) |
||||
#endif |
||||
dump_cfg_int(sLoginGraceTime, o->login_grace_time); |
||||
dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); |
||||
+ dump_cfg_int(sX11MaxDisplays, o->x11_max_displays); |
||||
dump_cfg_int(sMaxAuthTries, o->max_authtries); |
||||
dump_cfg_int(sMaxSessions, o->max_sessions); |
||||
dump_cfg_int(sClientAliveInterval, o->client_alive_interval); |
||||
diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h |
||||
--- openssh-7.4p1/servconf.h.x11max 2017-02-09 12:49:04.741996552 +0100 |
||||
+++ openssh-7.4p1/servconf.h 2017-02-09 12:49:04.744996547 +0100 |
||||
@@ -55,6 +55,7 @@ |
||||
|
||||
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ |
||||
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ |
||||
+#define DEFAULT_MAX_DISPLAYS 1000 /* Maximum number of fake X11 displays to try. */ |
||||
|
||||
/* Magic name for internal sftp-server */ |
||||
#define INTERNAL_SFTP_NAME "internal-sftp" |
||||
@@ -85,6 +86,7 @@ typedef struct { |
||||
int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */ |
||||
int x11_display_offset; /* What DISPLAY number to start |
||||
* searching at */ |
||||
+ int x11_max_displays; /* Number of displays to search */ |
||||
int x11_use_localhost; /* If true, use localhost for fake X11 server. */ |
||||
char *xauth_location; /* Location of xauth program */ |
||||
int permit_tty; /* If false, deny pty allocation */ |
||||
diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c |
||||
--- openssh-7.4p1/session.c.x11max 2017-02-09 12:49:04.742996550 +0100 |
||||
+++ openssh-7.4p1/session.c 2017-02-09 12:49:04.745996546 +0100 |
||||
@@ -2502,8 +2502,9 @@ session_setup_x11fwd(Session *s) |
||||
return 0; |
||||
} |
||||
if (x11_create_display_inet(options.x11_display_offset, |
||||
- options.x11_use_localhost, s->single_connection, |
||||
- &s->display_number, &s->x11_chanids) == -1) { |
||||
+ options.x11_use_localhost, options.x11_max_displays, |
||||
+ s->single_connection, &s->display_number, |
||||
+ &s->x11_chanids) == -1) { |
||||
debug("x11_create_display_inet failed."); |
||||
return 0; |
||||
} |
||||
diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.x11max 2017-02-09 12:49:04.742996550 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2017-02-09 12:51:24.656790909 +0100 |
||||
@@ -1137,6 +1137,7 @@ Available keywords are |
||||
.Cm StreamLocalBindUnlink , |
||||
.Cm TrustedUserCAKeys , |
||||
.Cm X11DisplayOffset , |
||||
+.Cm X11MaxDisplays , |
||||
.Cm X11Forwarding |
||||
and |
||||
.Cm X11UseLocalHost . |
||||
@@ -1563,6 +1564,12 @@ Specifies the first display number avail |
||||
X11 forwarding. |
||||
This prevents sshd from interfering with real X11 servers. |
||||
The default is 10. |
||||
+.It Cm X11MaxDisplays |
||||
+Specifies the maximum number of displays available for |
||||
+.Xr sshd 8 Ns 's |
||||
+X11 forwarding. |
||||
+This prevents sshd from exhausting local ports. |
||||
+The default is 1000. |
||||
.It Cm X11Forwarding |
||||
Specifies whether X11 forwarding is permitted. |
||||
The argument must be |
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
diff -up openssh-7.4p1/mux.c.controlPath openssh-7.4p1/mux.c |
||||
--- openssh-7.4p1/mux.c.controlPath 2017-05-04 14:49:44.629247946 +0200 |
||||
+++ openssh-7.4p1/mux.c 2017-05-04 14:52:54.955109022 +0200 |
||||
@@ -1290,6 +1290,12 @@ muxserver_listen(void) |
||||
oerrno = errno; |
||||
umask(old_umask); |
||||
if (muxserver_sock < 0) { |
||||
+ if (oerrno == ENAMETOOLONG) { |
||||
+ /* the error is already logged from unix_listener() */ |
||||
+ error("ControlPath %s too long, " |
||||
+ "disabling multiplexing", options.control_path); |
||||
+ goto disable_mux_master; |
||||
+ } |
||||
if (oerrno == EINVAL || oerrno == EADDRINUSE) { |
||||
error("ControlSocket %s already exists, " |
||||
"disabling multiplexing", options.control_path); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
From ddd3d34e5c7979ca6f4a3a98a7d219a4ed3d98c2 Mon Sep 17 00:00:00 2001 |
||||
From: "djm@openbsd.org" <djm@openbsd.org> |
||||
Date: Fri, 30 Dec 2016 22:08:02 +0000 |
||||
Subject: [PATCH] upstream commit |
||||
|
||||
fix deadlock when keys/principals command produces a lot of |
||||
output and a key is matched early; bz#2655, patch from jboning AT gmail.com |
||||
|
||||
Upstream-ID: e19456429bf99087ea994432c16d00a642060afe |
||||
--- |
||||
auth2-pubkey.c | 8 +++++++- |
||||
1 file changed, 7 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/auth2-pubkey.c b/auth2-pubkey.c |
||||
index 20f3309e1..70c021589 100644 |
||||
--- a/auth2-pubkey.c |
||||
+++ b/auth2-pubkey.c |
||||
@@ -727,6 +727,9 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key) |
||||
|
||||
ok = process_principals(f, NULL, pw, cert); |
||||
|
||||
+ fclose(f); |
||||
+ f = NULL; |
||||
+ |
||||
if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0) |
||||
goto out; |
||||
|
||||
@@ -1050,6 +1053,9 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key) |
||||
|
||||
ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); |
||||
|
||||
+ fclose(f); |
||||
+ f = NULL; |
||||
+ |
||||
if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0) |
||||
goto out; |
||||
|
||||
|
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c |
||||
index 1320cda..2441329 100644 |
||||
--- a/ssh-agent.c |
||||
+++ b/ssh-agent.c |
||||
@@ -821,7 +821,7 @@ send: |
||||
static void |
||||
process_remove_smartcard_key(SocketEntry *e) |
||||
{ |
||||
- char *provider = NULL, *pin = NULL; |
||||
+ char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; |
||||
int r, version, success = 0; |
||||
Identity *id, *nxt; |
||||
Idtab *tab; |
||||
@@ -831,6 +831,13 @@ process_remove_smartcard_key(SocketEntry *e) |
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
||||
free(pin); |
||||
|
||||
+ if (realpath(provider, canonical_provider) == NULL) { |
||||
+ verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", |
||||
+ provider, strerror(errno)); |
||||
+ goto send; |
||||
+ } |
||||
+ |
||||
+ debug("%s: remove %.100s", __func__, canonical_provider); |
||||
for (version = 1; version < 3; version++) { |
||||
tab = idtab_lookup(version); |
||||
for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { |
||||
@@ -838,18 +845,19 @@ process_remove_smartcard_key(SocketEntry *e) |
||||
/* Skip file--based keys */ |
||||
if (id->provider == NULL) |
||||
continue; |
||||
- if (!strcmp(provider, id->provider)) { |
||||
+ if (!strcmp(canonical_provider, id->provider)) { |
||||
TAILQ_REMOVE(&tab->idlist, id, next); |
||||
free_identity(id); |
||||
tab->nentries--; |
||||
} |
||||
} |
||||
} |
||||
- if (pkcs11_del_provider(provider) == 0) |
||||
+ if (pkcs11_del_provider(canonical_provider) == 0) |
||||
success = 1; |
||||
else |
||||
error("process_remove_smartcard_key:" |
||||
" pkcs11_del_provider failed"); |
||||
+send: |
||||
free(provider); |
||||
send_status(e, success); |
||||
} |
||||
|
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
commit 0fb1a617a07b8df5de188dd5a0c8bf293d4bfc0e |
||||
Author: markus@openbsd.org <markus@openbsd.org> |
||||
Date: Sat Mar 11 13:07:35 2017 +0000 |
||||
|
||||
upstream commit |
||||
|
||||
Don't count the initial block twice when computing how |
||||
many bytes to discard for the work around for the attacks against CBC-mode. |
||||
ok djm@; report from Jean Paul, Kenny, Martin and Torben @ RHUL |
||||
|
||||
Upstream-ID: f445f509a4e0a7ba3b9c0dae7311cb42458dc1e2 |
||||
|
||||
diff --git a/packet.c b/packet.c |
||||
index 01e2d45..2f3a2ec 100644 |
||||
--- a/packet.c |
||||
+++ b/packet.c |
||||
@@ -1850,11 +1850,11 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) |
||||
if (r != SSH_ERR_MAC_INVALID) |
||||
goto out; |
||||
logit("Corrupted MAC on input."); |
||||
- if (need > PACKET_MAX_SIZE) |
||||
+ if (need + block_size > PACKET_MAX_SIZE) |
||||
return SSH_ERR_INTERNAL_ERROR; |
||||
return ssh_packet_start_discard(ssh, enc, mac, |
||||
sshbuf_len(state->incoming_packet), |
||||
- PACKET_MAX_SIZE - need); |
||||
+ PACKET_MAX_SIZE - need - block_size); |
||||
} |
||||
/* Remove MAC from input buffer */ |
||||
DBG(debug("MAC #%d ok", state->p_read.seqnr)); |
@ -0,0 +1,574 @@
@@ -0,0 +1,574 @@
|
||||
diff -up openssh-7.4p1/auth-pam.c.coverity openssh-7.4p1/auth-pam.c |
||||
diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c |
||||
--- openssh-7.4p1/channels.c.coverity 2017-02-09 14:58:32.786064600 +0100 |
||||
+++ openssh-7.4p1/channels.c 2017-02-09 15:01:28.869890219 +0100 |
||||
@@ -266,11 +266,11 @@ channel_register_fds(Channel *c, int rfd |
||||
channel_max_fd = MAXIMUM(channel_max_fd, wfd); |
||||
channel_max_fd = MAXIMUM(channel_max_fd, efd); |
||||
|
||||
- if (rfd != -1) |
||||
+ if (rfd >= 0) |
||||
fcntl(rfd, F_SETFD, FD_CLOEXEC); |
||||
- if (wfd != -1 && wfd != rfd) |
||||
+ if (wfd >= 0 && wfd != rfd) |
||||
fcntl(wfd, F_SETFD, FD_CLOEXEC); |
||||
- if (efd != -1 && efd != rfd && efd != wfd) |
||||
+ if (efd >= 0 && efd != rfd && efd != wfd) |
||||
fcntl(efd, F_SETFD, FD_CLOEXEC); |
||||
|
||||
c->rfd = rfd; |
||||
@@ -288,11 +288,11 @@ channel_register_fds(Channel *c, int rfd |
||||
|
||||
/* enable nonblocking mode */ |
||||
if (nonblock) { |
||||
- if (rfd != -1) |
||||
+ if (rfd >= 0) |
||||
set_nonblock(rfd); |
||||
- if (wfd != -1) |
||||
+ if (wfd >= 0) |
||||
set_nonblock(wfd); |
||||
- if (efd != -1) |
||||
+ if (efd >= 0) |
||||
set_nonblock(efd); |
||||
} |
||||
} |
||||
diff -up openssh-7.4p1/clientloop.c.coverity openssh-7.4p1/clientloop.c |
||||
diff -up openssh-7.4p1/key.c.coverity openssh-7.4p1/key.c |
||||
diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c |
||||
--- openssh-7.4p1/monitor.c.coverity 2017-02-09 14:58:32.793064593 +0100 |
||||
+++ openssh-7.4p1/monitor.c 2017-02-09 14:58:32.805064581 +0100 |
||||
@@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx |
||||
mm_get_keystate(pmonitor); |
||||
|
||||
/* Drain any buffered messages from the child */ |
||||
- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) |
||||
+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) |
||||
; |
||||
|
||||
close(pmonitor->m_sendfd); |
||||
diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c |
||||
--- openssh-7.4p1/monitor_wrap.c.coverity 2017-02-09 14:58:32.797064589 +0100 |
||||
+++ openssh-7.4p1/monitor_wrap.c 2017-02-09 14:58:32.805064581 +0100 |
||||
@@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, |
||||
if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || |
||||
(tmp2 = dup(pmonitor->m_recvfd)) == -1) { |
||||
error("%s: cannot allocate fds for pty", __func__); |
||||
- if (tmp1 > 0) |
||||
+ if (tmp1 >= 0) |
||||
close(tmp1); |
||||
- if (tmp2 > 0) |
||||
- close(tmp2); |
||||
+ /*DEAD CODE if (tmp2 >= 0) |
||||
+ close(tmp2);*/ |
||||
return 0; |
||||
} |
||||
close(tmp1); |
||||
diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c |
||||
--- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/openbsd-compat/bindresvport.c 2017-02-09 14:58:32.805064581 +0100 |
||||
@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr |
||||
struct sockaddr_in6 *in6; |
||||
u_int16_t *portp; |
||||
u_int16_t port; |
||||
- socklen_t salen; |
||||
+ socklen_t salen = sizeof(struct sockaddr_storage); |
||||
int i; |
||||
|
||||
if (sa == NULL) { |
||||
diff -up openssh-7.4p1/packet.c.coverity openssh-7.4p1/packet.c |
||||
diff -up openssh-7.4p1/progressmeter.c.coverity openssh-7.4p1/progressmeter.c |
||||
diff -up openssh-7.4p1/scp.c.coverity openssh-7.4p1/scp.c |
||||
--- openssh-7.4p1/scp.c.coverity 2017-02-09 14:58:32.761064625 +0100 |
||||
+++ openssh-7.4p1/scp.c 2017-02-09 14:58:38.590058852 +0100 |
||||
@@ -157,7 +157,7 @@ killchild(int signo) |
||||
{ |
||||
if (do_cmd_pid > 1) { |
||||
kill(do_cmd_pid, signo ? signo : SIGTERM); |
||||
- waitpid(do_cmd_pid, NULL, 0); |
||||
+ (void) waitpid(do_cmd_pid, NULL, 0); |
||||
} |
||||
|
||||
if (signo) |
||||
diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.coverity 2017-02-09 14:58:32.801064585 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-09 14:58:38.591058851 +0100 |
||||
@@ -1544,7 +1544,7 @@ process_server_config_line(ServerOptions |
||||
fatal("%s line %d: Missing subsystem name.", |
||||
filename, linenum); |
||||
if (!*activep) { |
||||
- arg = strdelim(&cp); |
||||
+ /*arg =*/ (void) strdelim(&cp); |
||||
break; |
||||
} |
||||
for (i = 0; i < options->num_subsystems; i++) |
||||
@@ -1635,8 +1635,9 @@ process_server_config_line(ServerOptions |
||||
if (*activep && *charptr == NULL) { |
||||
*charptr = tilde_expand_filename(arg, getuid()); |
||||
/* increase optional counter */ |
||||
- if (intptr != NULL) |
||||
- *intptr = *intptr + 1; |
||||
+ /* DEAD CODE intptr is still NULL ;) |
||||
+ if (intptr != NULL) |
||||
+ *intptr = *intptr + 1; */ |
||||
} |
||||
break; |
||||
|
||||
diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c |
||||
--- openssh-7.4p1/serverloop.c.coverity 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/serverloop.c 2017-02-09 14:58:38.592058850 +0100 |
||||
@@ -125,13 +125,13 @@ notify_setup(void) |
||||
static void |
||||
notify_parent(void) |
||||
{ |
||||
- if (notify_pipe[1] != -1) |
||||
+ if (notify_pipe[1] >= 0) |
||||
(void)write(notify_pipe[1], "", 1); |
||||
} |
||||
static void |
||||
notify_prepare(fd_set *readset) |
||||
{ |
||||
- if (notify_pipe[0] != -1) |
||||
+ if (notify_pipe[0] >= 0) |
||||
FD_SET(notify_pipe[0], readset); |
||||
} |
||||
static void |
||||
@@ -139,8 +139,8 @@ notify_done(fd_set *readset) |
||||
{ |
||||
char c; |
||||
|
||||
- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) |
||||
- while (read(notify_pipe[0], &c, 1) != -1) |
||||
+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) |
||||
+ while (read(notify_pipe[0], &c, 1) >= 0) |
||||
debug2("notify_done: reading"); |
||||
} |
||||
|
||||
@@ -518,7 +518,7 @@ server_request_tun(void) |
||||
} |
||||
|
||||
tun = packet_get_int(); |
||||
- if (forced_tun_device != -1) { |
||||
+ if (forced_tun_device >= 0) { |
||||
if (tun != SSH_TUNID_ANY && forced_tun_device != tun) |
||||
goto done; |
||||
tun = forced_tun_device; |
||||
diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c |
||||
--- openssh-7.4p1/sftp.c.coverity 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/sftp.c 2017-02-09 14:58:38.598058844 +0100 |
||||
@@ -224,7 +224,7 @@ killchild(int signo) |
||||
{ |
||||
if (sshpid > 1) { |
||||
kill(sshpid, SIGTERM); |
||||
- waitpid(sshpid, NULL, 0); |
||||
+ (void) waitpid(sshpid, NULL, 0); |
||||
} |
||||
|
||||
_exit(1); |
||||
diff -up openssh-7.4p1/sftp-client.c.coverity openssh-7.4p1/sftp-client.c |
||||
--- openssh-7.4p1/sftp-client.c.coverity 2017-02-09 14:58:38.596058846 +0100 |
||||
+++ openssh-7.4p1/sftp-client.c 2017-02-09 15:20:18.893624636 +0100 |
||||
@@ -973,7 +973,7 @@ do_symlink(struct sftp_conn *conn, const |
||||
} |
||||
|
||||
int |
||||
-do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len) |
||||
+do_fsync(struct sftp_conn *conn, const u_char *handle, u_int handle_len) |
||||
{ |
||||
struct sshbuf *msg; |
||||
u_int status, id; |
||||
--- openssh-7.4p1/sftp-client.h.coverity 2017-02-10 09:28:10.951155129 +0100 |
||||
+++ openssh-7.4p1/sftp-client.h 2017-02-10 09:27:28.685069870 +0100 |
||||
@@ -107,7 +107,7 @@ int do_hardlink(struct sftp_conn *, cons |
||||
int do_symlink(struct sftp_conn *, const char *, const char *); |
||||
|
||||
/* Call fsync() on open file 'handle' */ |
||||
-int do_fsync(struct sftp_conn *conn, u_char *, u_int); |
||||
+int do_fsync(struct sftp_conn *conn, const u_char *, u_int); |
||||
|
||||
/* |
||||
* Download 'remote_path' to 'local_path'. Preserve permissions and times |
||||
diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c |
||||
--- openssh-7.4p1/ssh-agent.c.coverity 2017-02-09 14:58:38.599058843 +0100 |
||||
+++ openssh-7.4p1/ssh-agent.c 2017-02-09 15:29:21.938917065 +0100 |
||||
@@ -1220,8 +1220,8 @@ main(int ac, char **av) |
||||
sanitise_stdfd(); |
||||
|
||||
/* drop */ |
||||
- setegid(getgid()); |
||||
- setgid(getgid()); |
||||
+ (void) setegid(getgid()); |
||||
+ (void) setgid(getgid()); |
||||
|
||||
platform_disable_tracing(0); /* strict=no */ |
||||
|
||||
diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c |
||||
--- openssh-7.4p1/sshd.c.coverity 2017-02-09 14:58:38.600058842 +0100 |
||||
+++ openssh-7.4p1/sshd.c 2017-02-09 15:30:33.403800831 +0100 |
||||
@@ -679,8 +679,10 @@ privsep_preauth(Authctxt *authctxt) |
||||
|
||||
privsep_preauth_child(); |
||||
setproctitle("%s", "[net]"); |
||||
- if (box != NULL) |
||||
+ if (box != NULL) { |
||||
ssh_sandbox_child(box); |
||||
+ free(box); |
||||
+ } |
||||
|
||||
return 0; |
||||
} |
||||
@@ -1382,6 +1384,9 @@ server_accept_loop(int *sock_in, int *so |
||||
if (num_listen_socks < 0) |
||||
break; |
||||
} |
||||
+ |
||||
+ if (fdset != NULL) |
||||
+ free(fdset); |
||||
} |
||||
|
||||
/* |
||||
diff --git a/auth-pam.c b/auth-pam.c |
||||
index e554ec4..bd16d80 100644 |
||||
--- a/auth-pam.c |
||||
+++ b/auth-pam.c |
||||
@@ -834,6 +834,8 @@ fake_password(const char *wire_password) |
||||
fatal("%s: password length too long: %zu", __func__, l); |
||||
|
||||
ret = malloc(l + 1); |
||||
+ if (ret == NULL) |
||||
+ return NULL; |
||||
for (i = 0; i < l; i++) |
||||
ret[i] = junk[i % (sizeof(junk) - 1)]; |
||||
ret[i] = '\0'; |
||||
diff --git a/clientloop.c b/clientloop.c |
||||
index c6a4138..9b00e12 100644 |
||||
--- a/clientloop.c |
||||
+++ b/clientloop.c |
||||
@@ -2290,7 +2290,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) |
||||
free(response); |
||||
response = read_passphrase("Accept updated hostkeys? " |
||||
"(yes/no): ", RP_ECHO); |
||||
- if (strcasecmp(response, "yes") == 0) |
||||
+ if (response != NULL && strcasecmp(response, "yes") == 0) |
||||
break; |
||||
else if (quit_pending || response == NULL || |
||||
strcasecmp(response, "no") == 0) { |
||||
diff --git a/digest-openssl.c b/digest-openssl.c |
||||
index 13b63c2..dfa9b8d 100644 |
||||
--- a/digest-openssl.c |
||||
+++ b/digest-openssl.c |
||||
@@ -158,7 +158,7 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) |
||||
const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); |
||||
u_int l = dlen; |
||||
|
||||
- if (dlen > UINT_MAX) |
||||
+ if (digest == NULL || dlen > UINT_MAX) |
||||
return SSH_ERR_INVALID_ARGUMENT; |
||||
if (dlen < digest->digest_len) /* No truncation allowed */ |
||||
return SSH_ERR_INVALID_ARGUMENT; |
||||
diff --git a/kex.c b/kex.c |
||||
index a30dabe..a8ac91f 100644 |
||||
--- a/kex.c |
||||
+++ b/kex.c |
||||
@@ -178,7 +178,7 @@ kex_names_valid(const char *names) |
||||
char * |
||||
kex_names_cat(const char *a, const char *b) |
||||
{ |
||||
- char *ret = NULL, *tmp = NULL, *cp, *p; |
||||
+ char *ret = NULL, *tmp = NULL, *cp, *p, *m; |
||||
size_t len; |
||||
|
||||
if (a == NULL || *a == '\0') |
||||
@@ -195,8 +195,10 @@ kex_names_cat(const char *a, const char *b) |
||||
} |
||||
strlcpy(ret, a, len); |
||||
for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { |
||||
- if (match_list(ret, p, NULL) != NULL) |
||||
+ if ((m = match_list(ret, p, NULL)) != NULL) { |
||||
+ free(m); |
||||
continue; /* Algorithm already present */ |
||||
+ } |
||||
if (strlcat(ret, ",", len) >= len || |
||||
strlcat(ret, p, len) >= len) { |
||||
free(tmp); |
||||
@@ -651,8 +653,10 @@ choose_enc(struct sshenc *enc, char *client, char *server) |
||||
#endif |
||||
return SSH_ERR_NO_CIPHER_ALG_MATCH; |
||||
} |
||||
- if ((enc->cipher = cipher_by_name(name)) == NULL) |
||||
+ if ((enc->cipher = cipher_by_name(name)) == NULL) { |
||||
+ free(name); |
||||
return SSH_ERR_INTERNAL_ERROR; |
||||
+ } |
||||
enc->name = name; |
||||
enc->enabled = 0; |
||||
enc->iv = NULL; |
||||
@@ -670,8 +674,10 @@ choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) |
||||
#endif |
||||
return SSH_ERR_NO_MAC_ALG_MATCH; |
||||
} |
||||
- if (mac_setup(mac, name) < 0) |
||||
+ if (mac_setup(mac, name) < 0) { |
||||
+ free(name); |
||||
return SSH_ERR_INTERNAL_ERROR; |
||||
+ } |
||||
/* truncate the key */ |
||||
if (ssh->compat & SSH_BUG_HMAC) |
||||
mac->key_len = 16; |
||||
@@ -695,6 +701,7 @@ choose_comp(struct sshcomp *comp, char *client, char *server) |
||||
} else if (strcmp(name, "none") == 0) { |
||||
comp->type = COMP_NONE; |
||||
} else { |
||||
+ free(name); |
||||
return SSH_ERR_INTERNAL_ERROR; |
||||
} |
||||
comp->name = name; |
||||
diff --git a/readconf.c b/readconf.c |
||||
index 3e7a5d8..acc1391 100644 |
||||
--- a/readconf.c |
||||
+++ b/readconf.c |
||||
@@ -1500,6 +1500,7 @@ parse_keytypes: |
||||
if (r == GLOB_NOMATCH) { |
||||
debug("%.200s line %d: include %s matched no " |
||||
"files",filename, linenum, arg2); |
||||
+ free(arg2); |
||||
continue; |
||||
} else if (r != 0 || gl.gl_pathc < 0) |
||||
fatal("%.200s line %d: glob failed for %s.", |
||||
diff --git a/servconf.c b/servconf.c |
||||
index 6ab1cb4..5f2464a 100644 |
||||
--- a/servconf.c |
||||
+++ b/servconf.c |
||||
@@ -2284,8 +2284,6 @@ dump_cfg_fmtint(ServerOpCodes code, int val) |
||||
static void |
||||
dump_cfg_string(ServerOpCodes code, const char *val) |
||||
{ |
||||
- if (val == NULL) |
||||
- return; |
||||
printf("%s %s\n", lookup_opcode_name(code), |
||||
val == NULL ? "none" : val); |
||||
} |
||||
diff --git a/sshconnect.c b/sshconnect.c |
||||
index 07f80cd..5d4b41b 100644 |
||||
--- a/sshconnect.c |
||||
+++ b/sshconnect.c |
||||
@@ -1533,6 +1533,7 @@ maybe_add_key_to_agent(char *authfile, Key *private, char *comment, |
||||
if (options.add_keys_to_agent == 2 && |
||||
!ask_permission("Add key %s (%s) to agent?", authfile, comment)) { |
||||
debug3("user denied adding this key"); |
||||
+ close(auth_sock); |
||||
return; |
||||
} |
||||
|
||||
@@ -1541,4 +1542,5 @@ maybe_add_key_to_agent(char *authfile, Key *private, char *comment, |
||||
debug("identity added to agent: %s", authfile); |
||||
else |
||||
debug("could not add identity to agent: %s (%d)", authfile, r); |
||||
+ close(auth_sock); |
||||
} |
||||
diff --git a/sshconnect2.c b/sshconnect2.c |
||||
index f31c24c..aecf765 100644 |
||||
--- a/sshconnect2.c |
||||
+++ b/sshconnect2.c |
||||
@@ -1061,6 +1061,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) |
||||
|
||||
if (key_to_blob(id->key, &blob, &bloblen) == 0) { |
||||
/* we cannot handle this key */ |
||||
+ free(blob); |
||||
debug3("sign_and_send_pubkey: cannot handle key"); |
||||
return 0; |
||||
} |
||||
@@ -1170,6 +1171,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id) |
||||
|
||||
if (key_to_blob(id->key, &blob, &bloblen) == 0) { |
||||
/* we cannot handle this key */ |
||||
+ free(blob); |
||||
debug3("send_pubkey_test: cannot handle key"); |
||||
return 0; |
||||
} |
||||
diff --git a/sshkey.c b/sshkey.c |
||||
index 85fd1bd..58c1051 100644 |
||||
--- a/sshkey.c |
||||
+++ b/sshkey.c |
||||
@@ -1375,8 +1375,6 @@ sshkey_read(struct sshkey *ret, char **cpp) |
||||
retval = 0; |
||||
/*XXXX*/ |
||||
sshkey_free(k); |
||||
- if (retval != 0) |
||||
- break; |
||||
break; |
||||
default: |
||||
return SSH_ERR_INVALID_ARGUMENT; |
||||
diff --git a/krl.c b/krl.c |
||||
index e271a19..69bec99 100644 |
||||
--- a/krl.c |
||||
+++ b/krl.c |
||||
@@ -1089,7 +1089,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, |
||||
break; |
||||
case KRL_SECTION_SIGNATURE: |
||||
/* Handled above, but still need to stay in synch */ |
||||
- sshbuf_reset(sect); |
||||
+ sshbuf_free(sect); |
||||
sect = NULL; |
||||
if ((r = sshbuf_skip_string(copy)) != 0) |
||||
goto out; |
||||
@@ -1288,7 +1288,8 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key) |
||||
debug2("%s: checking KRL %s", __func__, path); |
||||
r = ssh_krl_check_key(krl, key); |
||||
out: |
||||
- close(fd); |
||||
+ if (fd != -1) |
||||
+ close(fd); |
||||
sshbuf_free(krlbuf); |
||||
ssh_krl_free(krl); |
||||
if (r != 0) |
||||
diff --git a/readconf.c b/readconf.c |
||||
index acc1391..c4dff15 100644 |
||||
--- a/readconf.c |
||||
+++ b/readconf.c |
||||
@@ -1185,7 +1185,7 @@ parse_int: |
||||
value = cipher_number(arg); |
||||
if (value == -1) |
||||
fatal("%.200s line %d: Bad cipher '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (*activep && *intptr == -1) |
||||
*intptr = value; |
||||
break; |
||||
@@ -1196,7 +1196,7 @@ parse_int: |
||||
fatal("%.200s line %d: Missing argument.", filename, linenum); |
||||
if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) |
||||
fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (*activep && options->ciphers == NULL) |
||||
options->ciphers = xstrdup(arg); |
||||
break; |
||||
@@ -1207,7 +1207,7 @@ parse_int: |
||||
fatal("%.200s line %d: Missing argument.", filename, linenum); |
||||
if (!mac_valid(*arg == '+' ? arg + 1 : arg)) |
||||
fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (*activep && options->macs == NULL) |
||||
options->macs = xstrdup(arg); |
||||
break; |
||||
@@ -1220,7 +1220,7 @@ parse_int: |
||||
filename, linenum); |
||||
if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) |
||||
fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (*activep && options->kex_algorithms == NULL) |
||||
options->kex_algorithms = xstrdup(arg); |
||||
break; |
||||
@@ -1235,7 +1235,7 @@ parse_keytypes: |
||||
filename, linenum); |
||||
if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) |
||||
fatal("%s line %d: Bad key types '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (*activep && *charptr == NULL) |
||||
*charptr = xstrdup(arg); |
||||
break; |
||||
@@ -1248,7 +1248,7 @@ parse_keytypes: |
||||
value = proto_spec(arg); |
||||
if (value == SSH_PROTO_UNKNOWN) |
||||
fatal("%.200s line %d: Bad protocol spec '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (*activep && *intptr == SSH_PROTO_UNKNOWN) |
||||
*intptr = value; |
||||
break; |
||||
diff --git a/servconf.c b/servconf.c |
||||
index 5f2464a..4564494 100644 |
||||
--- a/servconf.c |
||||
+++ b/servconf.c |
||||
@@ -1217,7 +1217,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, |
||||
filename, linenum); |
||||
if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1)) |
||||
fatal("%s line %d: Bad key types '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (*activep && *charptr == NULL) |
||||
*charptr = xstrdup(arg); |
||||
break; |
||||
@@ -1476,7 +1476,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, |
||||
fatal("%s line %d: Missing argument.", filename, linenum); |
||||
if (!ciphers_valid(*arg == '+' ? arg + 1 : arg)) |
||||
fatal("%s line %d: Bad SSH2 cipher spec '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (options->ciphers == NULL) |
||||
options->ciphers = xstrdup(arg); |
||||
break; |
||||
@@ -1487,7 +1487,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, |
||||
fatal("%s line %d: Missing argument.", filename, linenum); |
||||
if (!mac_valid(*arg == '+' ? arg + 1 : arg)) |
||||
fatal("%s line %d: Bad SSH2 mac spec '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (options->macs == NULL) |
||||
options->macs = xstrdup(arg); |
||||
break; |
||||
@@ -1500,7 +1500,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, |
||||
filename, linenum); |
||||
if (!kex_names_valid(*arg == '+' ? arg + 1 : arg)) |
||||
fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", |
||||
- filename, linenum, arg ? arg : "<NONE>"); |
||||
+ filename, linenum, arg); |
||||
if (options->kex_algorithms == NULL) |
||||
options->kex_algorithms = xstrdup(arg); |
||||
break; |
||||
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c |
||||
index aaf712d..62a76b3 100644 |
||||
--- a/ssh-pkcs11.c |
||||
+++ b/ssh-pkcs11.c |
||||
@@ -536,8 +536,8 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, |
||||
X509_free(x509); |
||||
} |
||||
if (rsa && rsa->n && rsa->e && |
||||
- pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { |
||||
- key = sshkey_new(KEY_UNSPEC); |
||||
+ pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0 && |
||||
+ (key = sshkey_new(KEY_UNSPEC)) != NULL) { |
||||
key->rsa = rsa; |
||||
key->type = KEY_RSA; |
||||
key->flags |= SSHKEY_FLAG_EXT; |
||||
diff --git a/sshconnect1.c b/sshconnect1.c |
||||
index a045361..0e1a506 100644 |
||||
--- a/sshconnect1.c |
||||
+++ b/sshconnect1.c |
||||
@@ -520,7 +520,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr) |
||||
cookie[i] = packet_get_char(); |
||||
|
||||
/* Get the public key. */ |
||||
- server_key = key_new(KEY_RSA1); |
||||
+ if ((server_key = key_new(KEY_RSA1)) == NULL) |
||||
+ fatal("%s: key_new(KEY_RSA1) failed", __func__); |
||||
bits = packet_get_int(); |
||||
packet_get_bignum(server_key->rsa->e); |
||||
packet_get_bignum(server_key->rsa->n); |
||||
@@ -532,7 +533,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr) |
||||
logit("Warning: This may be due to an old implementation of ssh."); |
||||
} |
||||
/* Get the host key. */ |
||||
- host_key = key_new(KEY_RSA1); |
||||
+ if ((host_key = key_new(KEY_RSA1)) == NULL) |
||||
+ fatal("%s: key_new(KEY_RSA1) failed", __func__); |
||||
bits = packet_get_int(); |
||||
packet_get_bignum(host_key->rsa->e); |
||||
packet_get_bignum(host_key->rsa->n); |
||||
diff --git a/sshkey.c b/sshkey.c |
||||
index 58c1051..6afacb5 100644 |
||||
--- a/sshkey.c |
||||
+++ b/sshkey.c |
||||
@@ -1239,6 +1239,9 @@ sshkey_read(struct sshkey *ret, char **cpp) |
||||
u_long bits; |
||||
#endif /* WITH_SSH1 */ |
||||
|
||||
+ if (ret == NULL) |
||||
+ return SSH_ERR_INVALID_ARGUMENT; |
||||
+ |
||||
cp = *cpp; |
||||
|
||||
switch (ret->type) { |
@ -0,0 +1,250 @@
@@ -0,0 +1,250 @@
|
||||
diff -up openssh-6.8p1/Makefile.in.ctr-cavs openssh-6.8p1/Makefile.in |
||||
--- openssh-6.8p1/Makefile.in.ctr-cavs 2015-03-18 11:22:05.493289018 +0100 |
||||
+++ openssh-6.8p1/Makefile.in 2015-03-18 11:22:44.504196316 +0100 |
||||
@@ -28,6 +28,7 @@ SSH_KEYSIGN=$(libexecdir)/ssh-keysign |
||||
SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper |
||||
SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper |
||||
SSH_KEYCAT=$(libexecdir)/ssh-keycat |
||||
+CTR_CAVSTEST=$(libexecdir)/ctr-cavstest |
||||
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper |
||||
PRIVSEP_PATH=@PRIVSEP_PATH@ |
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ |
||||
@@ -66,7 +67,7 @@ EXEEXT=@EXEEXT@ |
||||
MANFMT=@MANFMT@ |
||||
INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ |
||||
|
||||
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) |
||||
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) |
||||
|
||||
LIBOPENSSH_OBJS=\ |
||||
ssh_api.o \ |
||||
@@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l |
||||
ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o |
||||
$(LD) -o $@ ssh-keycat.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(KEYCATLIBS) $(SSHLIBS) |
||||
|
||||
+ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o |
||||
+ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) |
||||
+ |
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o |
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) |
||||
|
||||
@@ -326,6 +330,7 @@ install-files: |
||||
$(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ |
||||
fi |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) |
||||
+ $(INSTALL) -m 0755 $(STRIP_OPT) ctr-cavstest$(EXEEXT) $(DESTDIR)$(libexecdir)/ctr-cavstest$(EXEEXT) |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) |
||||
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 |
||||
diff -up openssh-6.8p1/ctr-cavstest.c.ctr-cavs openssh-6.8p1/ctr-cavstest.c |
||||
--- openssh-6.8p1/ctr-cavstest.c.ctr-cavs 2015-03-18 11:22:05.521288952 +0100 |
||||
+++ openssh-6.8p1/ctr-cavstest.c 2015-03-18 11:22:05.521288952 +0100 |
||||
@@ -0,0 +1,208 @@ |
||||
+/* |
||||
+ * |
||||
+ * invocation (all of the following are equal): |
||||
+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 |
||||
+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 --iv 00000000000000000000000000000000 |
||||
+ * echo -n a6deca405eef2e8e4609abf3c3ccf4a6 | ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt |
||||
+ */ |
||||
+ |
||||
+#include "includes.h" |
||||
+ |
||||
+#include <sys/types.h> |
||||
+#include <sys/param.h> |
||||
+#include <stdarg.h> |
||||
+#include <stdio.h> |
||||
+#include <stdlib.h> |
||||
+#include <string.h> |
||||
+#include <ctype.h> |
||||
+ |
||||
+#include "xmalloc.h" |
||||
+#include "log.h" |
||||
+#include "cipher.h" |
||||
+ |
||||
+/* compatibility with old or broken OpenSSL versions */ |
||||
+#include "openbsd-compat/openssl-compat.h" |
||||
+ |
||||
+void usage(void) { |
||||
+ fprintf(stderr, "Usage: ctr-cavstest --algo <ssh-crypto-algorithm>\n" |
||||
+ " --key <hexadecimal-key> --mode <encrypt|decrypt>\n" |
||||
+ " [--iv <hexadecimal-iv>] --data <hexadecimal-data>\n\n" |
||||
+ "Hexadecimal output is printed to stdout.\n" |
||||
+ "Hexadecimal input data can be alternatively read from stdin.\n"); |
||||
+ exit(1); |
||||
+} |
||||
+ |
||||
+void *fromhex(char *hex, size_t *len) |
||||
+{ |
||||
+ unsigned char *bin; |
||||
+ char *p; |
||||
+ size_t n = 0; |
||||
+ int shift = 4; |
||||
+ unsigned char out = 0; |
||||
+ unsigned char *optr; |
||||
+ |
||||
+ bin = xmalloc(strlen(hex)/2); |
||||
+ optr = bin; |
||||
+ |
||||
+ for (p = hex; *p != '\0'; ++p) { |
||||
+ unsigned char c; |
||||
+ |
||||
+ c = *p; |
||||
+ if (isspace(c)) |
||||
+ continue; |
||||
+ |
||||
+ if (c >= '0' && c <= '9') { |
||||
+ c = c - '0'; |
||||
+ } else if (c >= 'A' && c <= 'F') { |
||||
+ c = c - 'A' + 10; |
||||
+ } else if (c >= 'a' && c <= 'f') { |
||||
+ c = c - 'a' + 10; |
||||
+ } else { |
||||
+ /* truncate on nonhex cipher */ |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ out |= c << shift; |
||||
+ shift = (shift + 4) % 8; |
||||
+ |
||||
+ if (shift) { |
||||
+ *(optr++) = out; |
||||
+ out = 0; |
||||
+ ++n; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ *len = n; |
||||
+ return bin; |
||||
+} |
||||
+ |
||||
+#define READ_CHUNK 4096 |
||||
+#define MAX_READ_SIZE 1024*1024*100 |
||||
+char *read_stdin(void) |
||||
+{ |
||||
+ char *buf; |
||||
+ size_t n, total = 0; |
||||
+ |
||||
+ buf = xmalloc(READ_CHUNK); |
||||
+ |
||||
+ do { |
||||
+ n = fread(buf + total, 1, READ_CHUNK, stdin); |
||||
+ if (n < READ_CHUNK) /* terminate on short read */ |
||||
+ break; |
||||
+ |
||||
+ total += n; |
||||
+ buf = xreallocarray(buf, total + READ_CHUNK, 1); |
||||
+ } while(total < MAX_READ_SIZE); |
||||
+ return buf; |
||||
+} |
||||
+ |
||||
+int main (int argc, char *argv[]) |
||||
+{ |
||||
+ |
||||
+ const struct sshcipher *c; |
||||
+ struct sshcipher_ctx *cc; |
||||
+ char *algo = "aes128-ctr"; |
||||
+ char *hexkey = NULL; |
||||
+ char *hexiv = "00000000000000000000000000000000"; |
||||
+ char *hexdata = NULL; |
||||
+ char *p; |
||||
+ int i; |
||||
+ int encrypt = 1; |
||||
+ void *key; |
||||
+ size_t keylen; |
||||
+ void *iv; |
||||
+ size_t ivlen; |
||||
+ void *data; |
||||
+ size_t datalen; |
||||
+ void *outdata; |
||||
+ |
||||
+ for (i = 1; i < argc; ++i) { |
||||
+ if (strcmp(argv[i], "--algo") == 0) { |
||||
+ algo = argv[++i]; |
||||
+ } else if (strcmp(argv[i], "--key") == 0) { |
||||
+ hexkey = argv[++i]; |
||||
+ } else if (strcmp(argv[i], "--mode") == 0) { |
||||
+ ++i; |
||||
+ if (argv[i] == NULL) { |
||||
+ usage(); |
||||
+ } |
||||
+ if (strncmp(argv[i], "enc", 3) == 0) { |
||||
+ encrypt = 1; |
||||
+ } else if (strncmp(argv[i], "dec", 3) == 0) { |
||||
+ encrypt = 0; |
||||
+ } else { |
||||
+ usage(); |
||||
+ } |
||||
+ } else if (strcmp(argv[i], "--iv") == 0) { |
||||
+ hexiv = argv[++i]; |
||||
+ } else if (strcmp(argv[i], "--data") == 0) { |
||||
+ hexdata = argv[++i]; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (hexkey == NULL || algo == NULL) { |
||||
+ usage(); |
||||
+ } |
||||
+ |
||||
+ SSLeay_add_all_algorithms(); |
||||
+ |
||||
+ c = cipher_by_name(algo); |
||||
+ if (c == NULL) { |
||||
+ fprintf(stderr, "Error: unknown algorithm\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ if (hexdata == NULL) { |
||||
+ hexdata = read_stdin(); |
||||
+ } else { |
||||
+ hexdata = xstrdup(hexdata); |
||||
+ } |
||||
+ |
||||
+ key = fromhex(hexkey, &keylen); |
||||
+ |
||||
+ if (keylen != 16 && keylen != 24 && keylen == 32) { |
||||
+ fprintf(stderr, "Error: unsupported key length\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ iv = fromhex(hexiv, &ivlen); |
||||
+ |
||||
+ if (ivlen != 16) { |
||||
+ fprintf(stderr, "Error: unsupported iv length\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ data = fromhex(hexdata, &datalen); |
||||
+ |
||||
+ if (data == NULL || datalen == 0) { |
||||
+ fprintf(stderr, "Error: no data to encrypt/decrypt\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ cipher_init(&cc, c, key, keylen, iv, ivlen, encrypt); |
||||
+ |
||||
+ free(key); |
||||
+ free(iv); |
||||
+ |
||||
+ outdata = malloc(datalen); |
||||
+ if(outdata == NULL) { |
||||
+ fprintf(stderr, "Error: memory allocation failure\n"); |
||||
+ return 2; |
||||
+ } |
||||
+ |
||||
+ cipher_crypt(cc, 0, outdata, data, datalen, 0, 0); |
||||
+ |
||||
+ free(data); |
||||
+ |
||||
+ cipher_free(cc); |
||||
+ |
||||
+ for (p = outdata; datalen > 0; ++p, --datalen) { |
||||
+ printf("%02X", (unsigned char)*p); |
||||
+ } |
||||
+ |
||||
+ free(outdata); |
||||
+ |
||||
+ printf("\n"); |
||||
+ return 0; |
||||
+} |
||||
+ |
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
diff -up openssh-7.4p1/configure.ac.tcp_wrappers openssh-7.4p1/configure.ac |
||||
--- openssh-7.4p1/configure.ac.tcp_wrappers 2016-12-23 15:36:38.745411192 +0100 |
||||
+++ openssh-7.4p1/configure.ac 2016-12-23 15:36:38.777411197 +0100 |
||||
@@ -1491,6 +1491,62 @@ AC_ARG_WITH([skey], |
||||
] |
||||
) |
||||
|
||||
+# Check whether user wants TCP wrappers support |
||||
+TCPW_MSG="no" |
||||
+AC_ARG_WITH([tcp-wrappers], |
||||
+ [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)], |
||||
+ [ |
||||
+ if test "x$withval" != "xno" ; then |
||||
+ saved_LIBS="$LIBS" |
||||
+ saved_LDFLAGS="$LDFLAGS" |
||||
+ saved_CPPFLAGS="$CPPFLAGS" |
||||
+ if test -n "${withval}" && \ |
||||
+ test "x${withval}" != "xyes"; then |
||||
+ if test -d "${withval}/lib"; then |
||||
+ if test -n "${need_dash_r}"; then |
||||
+ LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" |
||||
+ else |
||||
+ LDFLAGS="-L${withval}/lib ${LDFLAGS}" |
||||
+ fi |
||||
+ else |
||||
+ if test -n "${need_dash_r}"; then |
||||
+ LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}" |
||||
+ else |
||||
+ LDFLAGS="-L${withval} ${LDFLAGS}" |
||||
+ fi |
||||
+ fi |
||||
+ if test -d "${withval}/include"; then |
||||
+ CPPFLAGS="-I${withval}/include ${CPPFLAGS}" |
||||
+ else |
||||
+ CPPFLAGS="-I${withval} ${CPPFLAGS}" |
||||
+ fi |
||||
+ fi |
||||
+ LIBS="-lwrap $LIBS" |
||||
+ AC_MSG_CHECKING([for libwrap]) |
||||
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ |
||||
+#include <sys/types.h> |
||||
+#include <sys/socket.h> |
||||
+#include <netinet/in.h> |
||||
+#include <tcpd.h> |
||||
+int deny_severity = 0, allow_severity = 0; |
||||
+ ]], [[ |
||||
+ hosts_access(0); |
||||
+ ]])], [ |
||||
+ AC_MSG_RESULT([yes]) |
||||
+ AC_DEFINE([LIBWRAP], [1], |
||||
+ [Define if you want |
||||
+ TCP Wrappers support]) |
||||
+ SSHDLIBS="$SSHDLIBS -lwrap" |
||||
+ TCPW_MSG="yes" |
||||
+ ], [ |
||||
+ AC_MSG_ERROR([*** libwrap missing]) |
||||
+ |
||||
+ ]) |
||||
+ LIBS="$saved_LIBS" |
||||
+ fi |
||||
+ ] |
||||
+) |
||||
+ |
||||
# Check whether user wants to use ldns |
||||
LDNS_MSG="no" |
||||
AC_ARG_WITH(ldns, |
||||
@@ -5214,6 +5270,7 @@ echo " KerberosV support |
||||
echo " SELinux support: $SELINUX_MSG" |
||||
echo " Smartcard support: $SCARD_MSG" |
||||
echo " S/KEY support: $SKEY_MSG" |
||||
+echo " TCP Wrappers support: $TCPW_MSG" |
||||
echo " MD5 password support: $MD5_MSG" |
||||
echo " libedit support: $LIBEDIT_MSG" |
||||
echo " Solaris process contract support: $SPC_MSG" |
||||
diff -up openssh-7.4p1/sshd.8.tcp_wrappers openssh-7.4p1/sshd.8 |
||||
--- openssh-7.4p1/sshd.8.tcp_wrappers 2016-12-23 15:36:38.759411194 +0100 |
||||
+++ openssh-7.4p1/sshd.8 2016-12-23 15:36:38.778411197 +0100 |
||||
@@ -836,6 +836,12 @@ the user's home directory becomes access |
||||
This file should be writable only by the user, and need not be |
||||
readable by anyone else. |
||||
.Pp |
||||
+.It Pa /etc/hosts.allow |
||||
+.It Pa /etc/hosts.deny |
||||
+Access controls that should be enforced by tcp-wrappers are defined here. |
||||
+Further details are described in |
||||
+.Xr hosts_access 5 . |
||||
+.Pp |
||||
.It Pa /etc/hosts.equiv |
||||
This file is for host-based authentication (see |
||||
.Xr ssh 1 ) . |
||||
@@ -960,6 +966,7 @@ IPv6 address can be used everywhere wher |
||||
.Xr ssh-keygen 1 , |
||||
.Xr ssh-keyscan 1 , |
||||
.Xr chroot 2 , |
||||
+.Xr hosts_access 5 , |
||||
.Xr login.conf 5 , |
||||
.Xr moduli 5 , |
||||
.Xr sshd_config 5 , |
||||
diff -up openssh-7.4p1/sshd.c.tcp_wrappers openssh-7.4p1/sshd.c |
||||
--- openssh-7.4p1/sshd.c.tcp_wrappers 2016-12-23 15:36:38.772411196 +0100 |
||||
+++ openssh-7.4p1/sshd.c 2016-12-23 15:37:15.032417028 +0100 |
||||
@@ -123,6 +123,13 @@ |
||||
#include "version.h" |
||||
#include "ssherr.h" |
||||
|
||||
+#ifdef LIBWRAP |
||||
+#include <tcpd.h> |
||||
+#include <syslog.h> |
||||
+int allow_severity; |
||||
+int deny_severity; |
||||
+#endif /* LIBWRAP */ |
||||
+ |
||||
/* Re-exec fds */ |
||||
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) |
||||
#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) |
||||
@@ -2012,6 +2019,24 @@ main(int ac, char **av) |
||||
#ifdef SSH_AUDIT_EVENTS |
||||
audit_connection_from(remote_ip, remote_port); |
||||
#endif |
||||
+#ifdef LIBWRAP |
||||
+ allow_severity = options.log_facility|LOG_INFO; |
||||
+ deny_severity = options.log_facility|LOG_WARNING; |
||||
+ /* Check whether logins are denied from this host. */ |
||||
+ if (packet_connection_is_on_socket()) { |
||||
+ struct request_info req; |
||||
+ |
||||
+ request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); |
||||
+ fromhost(&req); |
||||
+ |
||||
+ if (!hosts_access(&req)) { |
||||
+ debug("Connection refused by tcp wrapper"); |
||||
+ refuse(&req); |
||||
+ /* NOTREACHED */ |
||||
+ fatal("libwrap refuse returns"); |
||||
+ } |
||||
+ } |
||||
+#endif /* LIBWRAP */ |
||||
|
||||
/* Log the connection. */ |
||||
laddr = get_local_ipaddr(sock_in); |
@ -0,0 +1,517 @@
@@ -0,0 +1,517 @@
|
||||
diff -up openssh-7.4p1/auth2.c.expose-pam openssh-7.4p1/auth2.c |
||||
--- openssh-7.4p1/auth2.c.expose-pam 2016-12-23 15:40:26.768447868 +0100 |
||||
+++ openssh-7.4p1/auth2.c 2016-12-23 15:40:26.818447876 +0100 |
||||
@@ -310,6 +310,7 @@ userauth_finish(Authctxt *authctxt, int |
||||
const char *submethod) |
||||
{ |
||||
char *methods; |
||||
+ char *prev_auth_details; |
||||
int partial = 0; |
||||
|
||||
if (!authctxt->valid && authenticated) |
||||
@@ -340,6 +341,18 @@ userauth_finish(Authctxt *authctxt, int |
||||
if (authctxt->postponed) |
||||
return; |
||||
|
||||
+ if (authenticated || partial) { |
||||
+ prev_auth_details = authctxt->auth_details; |
||||
+ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", |
||||
+ prev_auth_details ? prev_auth_details : "", |
||||
+ prev_auth_details ? ", " : "", method, |
||||
+ authctxt->last_details ? ": " : "", |
||||
+ authctxt->last_details ? authctxt->last_details : ""); |
||||
+ free(prev_auth_details); |
||||
+ } |
||||
+ free(authctxt->last_details); |
||||
+ authctxt->last_details = NULL; |
||||
+ |
||||
#ifdef USE_PAM |
||||
if (options.use_pam && authenticated) { |
||||
if (!PRIVSEP(do_pam_account())) { |
||||
diff -up openssh-7.4p1/auth2-gss.c.expose-pam openssh-7.4p1/auth2-gss.c |
||||
--- openssh-7.4p1/auth2-gss.c.expose-pam 2016-12-23 15:40:26.769447868 +0100 |
||||
+++ openssh-7.4p1/auth2-gss.c 2016-12-23 15:40:26.818447876 +0100 |
||||
@@ -276,6 +276,9 @@ input_gssapi_exchange_complete(int type, |
||||
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, |
||||
authctxt->pw)); |
||||
|
||||
+ if (authenticated) |
||||
+ authctxt->last_details = ssh_gssapi_get_displayname(); |
||||
+ |
||||
authctxt->postponed = 0; |
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); |
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); |
||||
@@ -322,6 +325,9 @@ input_gssapi_mic(int type, u_int32_t ple |
||||
else |
||||
logit("GSSAPI MIC check failed"); |
||||
|
||||
+ if (authenticated) |
||||
+ authctxt->last_details = ssh_gssapi_get_displayname(); |
||||
+ |
||||
buffer_free(&b); |
||||
if (micuser != authctxt->user) |
||||
free(micuser); |
||||
diff -up openssh-7.4p1/auth2-hostbased.c.expose-pam openssh-7.4p1/auth2-hostbased.c |
||||
--- openssh-7.4p1/auth2-hostbased.c.expose-pam 2016-12-23 15:40:26.731447862 +0100 |
||||
+++ openssh-7.4p1/auth2-hostbased.c 2016-12-23 15:40:26.818447876 +0100 |
||||
@@ -60,7 +60,7 @@ userauth_hostbased(Authctxt *authctxt) |
||||
{ |
||||
Buffer b; |
||||
Key *key = NULL; |
||||
- char *pkalg, *cuser, *chost, *service; |
||||
+ char *pkalg, *cuser, *chost, *service, *pubkey; |
||||
u_char *pkblob, *sig; |
||||
u_int alen, blen, slen; |
||||
int pktype; |
||||
@@ -140,15 +140,21 @@ userauth_hostbased(Authctxt *authctxt) |
||||
buffer_dump(&b); |
||||
#endif |
||||
|
||||
- pubkey_auth_info(authctxt, key, |
||||
- "client user \"%.100s\", client host \"%.100s\"", cuser, chost); |
||||
+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); |
||||
+ auth_info(authctxt, |
||||
+ "%s, client user \"%.100s\", client host \"%.100s\"", |
||||
+ pubkey, 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), |
||||
- buffer_len(&b))) == 1) |
||||
+ buffer_len(&b))) == 1) { |
||||
authenticated = 1; |
||||
+ authctxt->last_details = pubkey; |
||||
+ } else { |
||||
+ free(pubkey); |
||||
+ } |
||||
|
||||
buffer_free(&b); |
||||
done: |
||||
diff -up openssh-7.4p1/auth2-pubkey.c.expose-pam openssh-7.4p1/auth2-pubkey.c |
||||
--- openssh-7.4p1/auth2-pubkey.c.expose-pam 2016-12-23 15:40:26.746447864 +0100 |
||||
+++ openssh-7.4p1/auth2-pubkey.c 2016-12-23 15:40:26.819447876 +0100 |
||||
@@ -79,7 +79,7 @@ userauth_pubkey(Authctxt *authctxt) |
||||
{ |
||||
Buffer b; |
||||
Key *key = NULL; |
||||
- char *pkalg, *userstyle, *fp = NULL; |
||||
+ char *pkalg, *userstyle, *pubkey, *fp = NULL; |
||||
u_char *pkblob, *sig; |
||||
u_int alen, blen, slen; |
||||
int have_sig, pktype; |
||||
@@ -177,7 +177,8 @@ userauth_pubkey(Authctxt *authctxt) |
||||
#ifdef DEBUG_PK |
||||
buffer_dump(&b); |
||||
#endif |
||||
- pubkey_auth_info(authctxt, key, NULL); |
||||
+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); |
||||
+ auth_info(authctxt, "%s", pubkey); |
||||
|
||||
/* test for correct signature */ |
||||
authenticated = 0; |
||||
@@ -185,9 +186,12 @@ userauth_pubkey(Authctxt *authctxt) |
||||
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), |
||||
buffer_len(&b))) == 1) { |
||||
authenticated = 1; |
||||
+ authctxt->last_details = pubkey; |
||||
/* Record the successful key to prevent reuse */ |
||||
auth2_record_userkey(authctxt, key); |
||||
key = NULL; /* Don't free below */ |
||||
+ } else { |
||||
+ free(pubkey); |
||||
} |
||||
buffer_free(&b); |
||||
free(sig); |
||||
@@ -228,7 +232,7 @@ done: |
||||
void |
||||
pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) |
||||
{ |
||||
- char *fp, *extra; |
||||
+ char *extra, *pubkey; |
||||
va_list ap; |
||||
int i; |
||||
|
||||
@@ -238,27 +242,13 @@ pubkey_auth_info(Authctxt *authctxt, con |
||||
i = vasprintf(&extra, fmt, ap); |
||||
va_end(ap); |
||||
if (i < 0 || extra == NULL) |
||||
- fatal("%s: vasprintf failed", __func__); |
||||
+ fatal("%s: vasprintf failed", __func__); |
||||
} |
||||
|
||||
- if (key_is_cert(key)) { |
||||
- fp = sshkey_fingerprint(key->cert->signature_key, |
||||
- options.fingerprint_hash, SSH_FP_DEFAULT); |
||||
- 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 == NULL ? "(null)" : fp, |
||||
- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
||||
- free(fp); |
||||
- } else { |
||||
- fp = sshkey_fingerprint(key, options.fingerprint_hash, |
||||
- SSH_FP_DEFAULT); |
||||
- auth_info(authctxt, "%s %s%s%s", key_type(key), |
||||
- fp == NULL ? "(null)" : fp, |
||||
- extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
||||
- free(fp); |
||||
- } |
||||
+ pubkey = sshkey_format_oneline(key, options.fingerprint_hash); |
||||
+ auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ", |
||||
+ extra == NULL ? "" : extra); |
||||
+ free(pubkey); |
||||
free(extra); |
||||
} |
||||
|
||||
diff -up openssh-7.4p1/auth.h.expose-pam openssh-7.4p1/auth.h |
||||
--- openssh-7.4p1/auth.h.expose-pam 2016-12-23 15:40:26.782447870 +0100 |
||||
+++ openssh-7.4p1/auth.h 2016-12-23 15:40:26.819447876 +0100 |
||||
@@ -84,6 +84,9 @@ struct Authctxt { |
||||
|
||||
struct sshkey **prev_userkeys; |
||||
u_int nprev_userkeys; |
||||
+ |
||||
+ char *last_details; |
||||
+ char *auth_details; |
||||
}; |
||||
/* |
||||
* Every authentication method has to handle authentication requests for |
||||
diff -up openssh-7.4p1/auth-pam.c.expose-pam openssh-7.4p1/auth-pam.c |
||||
--- openssh-7.4p1/auth-pam.c.expose-pam 2016-12-23 15:40:26.731447862 +0100 |
||||
+++ openssh-7.4p1/auth-pam.c 2016-12-23 15:40:26.819447876 +0100 |
||||
@@ -688,6 +688,11 @@ sshpam_init_ctx(Authctxt *authctxt) |
||||
return (NULL); |
||||
} |
||||
|
||||
+ /* Notify PAM about any already successful auth methods */ |
||||
+ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMONLY && |
||||
+ authctxt->auth_details) |
||||
+ do_pam_putenv("SSH_USER_AUTH", authctxt->auth_details); |
||||
+ |
||||
ctxt = xcalloc(1, sizeof *ctxt); |
||||
|
||||
/* Start the authentication thread */ |
||||
diff -up openssh-7.4p1/gss-serv.c.expose-pam openssh-7.4p1/gss-serv.c |
||||
--- openssh-7.4p1/gss-serv.c.expose-pam 2016-12-23 15:40:26.808447874 +0100 |
||||
+++ openssh-7.4p1/gss-serv.c 2016-12-23 15:40:26.819447876 +0100 |
||||
@@ -441,6 +441,16 @@ ssh_gssapi_do_child(char ***envp, u_int |
||||
} |
||||
|
||||
/* Privileged */ |
||||
+char* |
||||
+ssh_gssapi_get_displayname(void) |
||||
+{ |
||||
+ if (gssapi_client.displayname.length != 0 && |
||||
+ gssapi_client.displayname.value != NULL) |
||||
+ return strdup((char *)gssapi_client.displayname.value); |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+/* Privileged */ |
||||
int |
||||
ssh_gssapi_userok(char *user, struct passwd *pw) |
||||
{ |
||||
diff -up openssh-7.4p1/monitor.c.expose-pam openssh-7.4p1/monitor.c |
||||
--- openssh-7.4p1/monitor.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 |
||||
+++ openssh-7.4p1/monitor.c 2016-12-23 15:41:16.473455863 +0100 |
||||
@@ -300,6 +300,7 @@ monitor_child_preauth(Authctxt *_authctx |
||||
{ |
||||
struct mon_table *ent; |
||||
int authenticated = 0, partial = 0; |
||||
+ char *prev_auth_details; |
||||
|
||||
debug3("preauth child monitor started"); |
||||
|
||||
@@ -330,6 +331,18 @@ monitor_child_preauth(Authctxt *_authctx |
||||
auth_submethod = NULL; |
||||
authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); |
||||
|
||||
+ if (authenticated) { |
||||
+ prev_auth_details = authctxt->auth_details; |
||||
+ xasprintf(&authctxt->auth_details, "%s%s%s%s%s", |
||||
+ prev_auth_details ? prev_auth_details : "", |
||||
+ prev_auth_details ? ", " : "", auth_method, |
||||
+ authctxt->last_details ? ": " : "", |
||||
+ authctxt->last_details ? authctxt->last_details : ""); |
||||
+ free(prev_auth_details); |
||||
+ } |
||||
+ free(authctxt->last_details); |
||||
+ authctxt->last_details = NULL; |
||||
+ |
||||
/* Special handling for multiple required authentications */ |
||||
if (options.num_auth_methods != 0) { |
||||
if (authenticated && |
||||
@@ -1417,6 +1430,10 @@ mm_answer_keyverify(int sock, Buffer *m) |
||||
debug3("%s: key %p signature %s", |
||||
__func__, key, (verified == 1) ? "verified" : "unverified"); |
||||
|
||||
+ if (verified == 1) |
||||
+ authctxt->last_details = sshkey_format_oneline(key, |
||||
+ options.fingerprint_hash); |
||||
+ |
||||
/* If auth was successful then record key to ensure it isn't reused */ |
||||
if (verified == 1 && key_blobtype == MM_USERKEY) |
||||
auth2_record_userkey(authctxt, key); |
||||
@@ -1860,6 +1877,9 @@ mm_answer_gss_userok(int sock, Buffer *m |
||||
|
||||
auth_method = "gssapi-with-mic"; |
||||
|
||||
+ if (authenticated) |
||||
+ authctxt->last_details = ssh_gssapi_get_displayname(); |
||||
+ |
||||
/* Monitor loop will terminate if authenticated */ |
||||
return (authenticated); |
||||
} |
||||
diff -up openssh-7.4p1/servconf.c.expose-pam openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.expose-pam 2016-12-23 15:40:26.810447875 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2016-12-23 15:44:04.691482920 +0100 |
||||
@@ -171,6 +171,7 @@ initialize_server_options(ServerOptions |
||||
options->version_addendum = NULL; |
||||
options->use_kuserok = -1; |
||||
options->enable_k5users = -1; |
||||
+ options->expose_auth_methods = -1; |
||||
options->fingerprint_hash = -1; |
||||
options->disable_forwarding = -1; |
||||
} |
||||
@@ -354,6 +355,8 @@ fill_default_server_options(ServerOption |
||||
options->use_kuserok = 1; |
||||
if (options->enable_k5users == -1) |
||||
options->enable_k5users = 0; |
||||
+ if (options->expose_auth_methods == -1) |
||||
+ options->expose_auth_methods = EXPOSE_AUTHMETH_NEVER; |
||||
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) |
||||
options->fwd_opts.streamlocal_bind_mask = 0177; |
||||
if (options->fwd_opts.streamlocal_bind_unlink == -1) |
||||
@@ -439,6 +442,7 @@ typedef enum { |
||||
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, |
||||
sStreamLocalBindMask, sStreamLocalBindUnlink, |
||||
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, |
||||
+ sExposeAuthenticationMethods, |
||||
sDeprecated, sIgnore, sUnsupported |
||||
} ServerOpCodes; |
||||
|
||||
@@ -595,6 +599,7 @@ static struct { |
||||
{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, |
||||
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, |
||||
{ "disableforwarding", sDisableForwarding, SSHCFG_ALL }, |
||||
+ { "exposeauthenticationmethods", sExposeAuthenticationMethods, SSHCFG_ALL }, |
||||
{ NULL, sBadOption, 0 } |
||||
}; |
||||
|
||||
@@ -984,6 +989,12 @@ static const struct multistate multistat |
||||
{ "local", FORWARD_LOCAL }, |
||||
{ NULL, -1 } |
||||
}; |
||||
+static const struct multistate multistate_exposeauthmeth[] = { |
||||
+ { "never", EXPOSE_AUTHMETH_NEVER }, |
||||
+ { "pam-only", EXPOSE_AUTHMETH_PAMONLY }, |
||||
+ { "pam-and-env", EXPOSE_AUTHMETH_PAMENV }, |
||||
+ { NULL, -1} |
||||
+}; |
||||
|
||||
int |
||||
process_server_config_line(ServerOptions *options, char *line, |
||||
@@ -1902,6 +1913,11 @@ process_server_config_line(ServerOptions |
||||
options->fingerprint_hash = value; |
||||
break; |
||||
|
||||
+ case sExposeAuthenticationMethods: |
||||
+ intptr = &options->expose_auth_methods; |
||||
+ multistate_ptr = multistate_exposeauthmeth; |
||||
+ goto parse_multistate; |
||||
+ |
||||
case sDeprecated: |
||||
case sIgnore: |
||||
case sUnsupported: |
||||
@@ -2060,6 +2076,7 @@ copy_set_server_options(ServerOptions *d |
||||
M_CP_INTOPT(enable_k5users); |
||||
M_CP_INTOPT(rekey_limit); |
||||
M_CP_INTOPT(rekey_interval); |
||||
+ M_CP_INTOPT(expose_auth_methods); |
||||
|
||||
/* |
||||
* The bind_mask is a mode_t that may be unsigned, so we can't use |
||||
@@ -2176,6 +2193,8 @@ fmt_intarg(ServerOpCodes code, int val) |
||||
return fmt_multistate_int(val, multistate_tcpfwd); |
||||
case sFingerprintHash: |
||||
return ssh_digest_alg_name(val); |
||||
+ case sExposeAuthenticationMethods: |
||||
+ return fmt_multistate_int(val, multistate_exposeauthmeth); |
||||
default: |
||||
switch (val) { |
||||
case 0: |
||||
@@ -2356,6 +2375,7 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); |
||||
dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); |
||||
dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users); |
||||
+ dump_cfg_fmtint(sExposeAuthenticationMethods, o->expose_auth_methods); |
||||
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); |
||||
|
||||
/* string arguments */ |
||||
diff -up openssh-7.4p1/servconf.h.expose-pam openssh-7.4p1/servconf.h |
||||
--- openssh-7.4p1/servconf.h.expose-pam 2016-12-23 15:40:26.810447875 +0100 |
||||
+++ openssh-7.4p1/servconf.h 2016-12-23 15:40:26.821447876 +0100 |
||||
@@ -48,6 +48,11 @@ |
||||
#define FORWARD_LOCAL (1<<1) |
||||
#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) |
||||
|
||||
+/* Expose AuthenticationMethods */ |
||||
+#define EXPOSE_AUTHMETH_NEVER 0 |
||||
+#define EXPOSE_AUTHMETH_PAMONLY 1 |
||||
+#define EXPOSE_AUTHMETH_PAMENV 2 |
||||
+ |
||||
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ |
||||
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ |
||||
|
||||
@@ -195,6 +200,8 @@ typedef struct { |
||||
char *auth_methods[MAX_AUTH_METHODS]; |
||||
|
||||
int fingerprint_hash; |
||||
+ |
||||
+ int expose_auth_methods; /* EXPOSE_AUTHMETH_* above */ |
||||
} ServerOptions; |
||||
|
||||
/* Information about the incoming connection as used by Match */ |
||||
diff -up openssh-7.4p1/session.c.expose-pam openssh-7.4p1/session.c |
||||
--- openssh-7.4p1/session.c.expose-pam 2016-12-23 15:40:26.794447872 +0100 |
||||
+++ openssh-7.4p1/session.c 2016-12-23 15:40:26.821447876 +0100 |
||||
@@ -997,6 +997,12 @@ copy_environment(char **source, char *** |
||||
} |
||||
*var_val++ = '\0'; |
||||
|
||||
+ if (options.expose_auth_methods < EXPOSE_AUTHMETH_PAMENV && |
||||
+ strcmp(var_name, "SSH_USER_AUTH") == 0) { |
||||
+ free(var_name); |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
debug3("Copy environment: %s=%s", var_name, var_val); |
||||
child_set_env(env, envsize, var_name, var_val); |
||||
|
||||
@@ -1173,6 +1179,11 @@ do_setup_env(Session *s, const char *she |
||||
} |
||||
#endif /* USE_PAM */ |
||||
|
||||
+ if (options.expose_auth_methods >= EXPOSE_AUTHMETH_PAMENV && |
||||
+ s->authctxt->auth_details) |
||||
+ child_set_env(&env, &envsize, "SSH_USER_AUTH", |
||||
+ s->authctxt->auth_details); |
||||
+ |
||||
if (auth_sock_name != NULL) |
||||
child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, |
||||
auth_sock_name); |
||||
@@ -2561,6 +2572,9 @@ do_cleanup(Authctxt *authctxt) |
||||
if (authctxt == NULL) |
||||
return; |
||||
|
||||
+ free(authctxt->auth_details); |
||||
+ authctxt->auth_details = NULL; |
||||
+ |
||||
#ifdef USE_PAM |
||||
if (options.use_pam) { |
||||
sshpam_cleanup(); |
||||
diff -up openssh-7.4p1/ssh.1.expose-pam openssh-7.4p1/ssh.1 |
||||
--- openssh-7.4p1/ssh.1.expose-pam 2016-12-23 15:40:26.810447875 +0100 |
||||
+++ openssh-7.4p1/ssh.1 2016-12-23 15:40:26.822447877 +0100 |
||||
@@ -1421,6 +1421,10 @@ server IP address, and server port numbe |
||||
This variable contains the original command line if a forced command |
||||
is executed. |
||||
It can be used to extract the original arguments. |
||||
+.It Ev SSH_USER_AUTH |
||||
+This variable contains, for SSH2 only, a comma-separated list of authentication |
||||
+methods that were successfuly used to authenticate. When possible, these |
||||
+methods are extended with detailed information on the credential used. |
||||
.It Ev SSH_TTY |
||||
This is set to the name of the tty (path to the device) associated |
||||
with the current shell or command. |
||||
diff -up openssh-7.4p1/sshd_config.5.expose-pam openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.expose-pam 2016-12-23 15:40:26.822447877 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2016-12-23 15:45:22.411495421 +0100 |
||||
@@ -570,6 +570,21 @@ Disables all forwarding features, includ |
||||
TCP and StreamLocal. |
||||
This option overrides all other forwarding-related options and may |
||||
simplify restricted configurations. |
||||
+.It Cm ExposeAuthenticationMethods |
||||
+When using SSH2, this option controls the exposure of the list of |
||||
+successful authentication methods to PAM during the authentication |
||||
+and to the shell environment via the |
||||
+.Cm SSH_USER_AUTH |
||||
+variable. See the description of this variable for more details. |
||||
+Valid options are: |
||||
+.Cm never |
||||
+(Do not expose successful authentication methods), |
||||
+.Cm pam-only |
||||
+(Only expose them to PAM during authentication, not afterwards), |
||||
+.Cm pam-and-env |
||||
+(Expose them to PAM and keep them in the shell environment). |
||||
+The default is |
||||
+.Cm never . |
||||
.It Cm FingerprintHash |
||||
Specifies the hash algorithm used when logging key fingerprints. |
||||
Valid options are: |
||||
diff -up openssh-7.4p1/ssh-gss.h.expose-pam openssh-7.4p1/ssh-gss.h |
||||
--- openssh-7.4p1/ssh-gss.h.expose-pam 2016-12-23 15:40:26.811447875 +0100 |
||||
+++ openssh-7.4p1/ssh-gss.h 2016-12-23 15:40:26.823447877 +0100 |
||||
@@ -159,6 +159,7 @@ int ssh_gssapi_server_check_mech(Gssctxt |
||||
const char *); |
||||
OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); |
||||
int ssh_gssapi_userok(char *name, struct passwd *); |
||||
+char* ssh_gssapi_get_displayname(void); |
||||
OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); |
||||
void ssh_gssapi_do_child(char ***, u_int *); |
||||
void ssh_gssapi_cleanup_creds(void); |
||||
diff -up openssh-7.4p1/sshkey.c.expose-pam openssh-7.4p1/sshkey.c |
||||
--- openssh-7.4p1/sshkey.c.expose-pam 2016-12-23 15:40:26.777447869 +0100 |
||||
+++ openssh-7.4p1/sshkey.c 2016-12-23 15:40:26.823447877 +0100 |
||||
@@ -57,6 +57,7 @@ |
||||
#define SSHKEY_INTERNAL |
||||
#include "sshkey.h" |
||||
#include "match.h" |
||||
+#include "xmalloc.h" |
||||
|
||||
/* openssh private key file format */ |
||||
#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" |
||||
@@ -1191,6 +1192,30 @@ sshkey_fingerprint(const struct sshkey * |
||||
return retval; |
||||
} |
||||
|
||||
+char * |
||||
+sshkey_format_oneline(const struct sshkey *key, int dgst_alg) |
||||
+{ |
||||
+ char *fp, *result; |
||||
+ |
||||
+ if (sshkey_is_cert(key)) { |
||||
+ fp = sshkey_fingerprint(key->cert->signature_key, dgst_alg, |
||||
+ SSH_FP_DEFAULT); |
||||
+ xasprintf(&result, "%s ID %s (serial %llu) CA %s %s", |
||||
+ sshkey_type(key), key->cert->key_id, |
||||
+ (unsigned long long)key->cert->serial, |
||||
+ sshkey_type(key->cert->signature_key), |
||||
+ fp == NULL ? "(null)" : fp); |
||||
+ free(fp); |
||||
+ } else { |
||||
+ fp = sshkey_fingerprint(key, dgst_alg, SSH_FP_DEFAULT); |
||||
+ xasprintf(&result, "%s %s", sshkey_type(key), |
||||
+ fp == NULL ? "(null)" : fp); |
||||
+ free(fp); |
||||
+ } |
||||
+ |
||||
+ return result; |
||||
+} |
||||
+ |
||||
#ifdef WITH_SSH1 |
||||
/* |
||||
* Reads a multiple-precision integer in decimal from the buffer, and advances |
||||
diff -up openssh-7.4p1/sshkey.h.expose-pam openssh-7.4p1/sshkey.h |
||||
--- openssh-7.4p1/sshkey.h.expose-pam 2016-12-23 15:40:26.777447869 +0100 |
||||
+++ openssh-7.4p1/sshkey.h 2016-12-23 15:40:26.823447877 +0100 |
||||
@@ -124,6 +124,7 @@ char *sshkey_fingerprint(const struct s |
||||
int, enum sshkey_fp_rep); |
||||
int sshkey_fingerprint_raw(const struct sshkey *k, |
||||
int, u_char **retp, size_t *lenp); |
||||
+char *sshkey_format_oneline(const struct sshkey *k, int dgst_alg); |
||||
const char *sshkey_type(const struct sshkey *); |
||||
const char *sshkey_cert_type(const struct sshkey *); |
||||
int sshkey_write(const struct sshkey *, FILE *); |
@ -0,0 +1,806 @@
@@ -0,0 +1,806 @@
|
||||
diff -up openssh-7.4p1/cipher.c.fips openssh-7.4p1/cipher.c |
||||
--- openssh-7.4p1/cipher.c.fips 2017-02-09 14:53:47.174347449 +0100 |
||||
+++ openssh-7.4p1/cipher.c 2017-02-09 14:53:47.182347441 +0100 |
||||
@@ -39,6 +39,8 @@ |
||||
|
||||
#include <sys/types.h> |
||||
|
||||
+#include <openssl/fips.h> |
||||
+ |
||||
#include <string.h> |
||||
#include <stdarg.h> |
||||
#include <stdio.h> |
||||
@@ -116,6 +118,20 @@ static const struct sshcipher ciphers[] |
||||
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } |
||||
}; |
||||
|
||||
+static const struct sshcipher fips_ciphers[] = { |
||||
+ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, |
||||
+ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, |
||||
+ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc }, |
||||
+ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc }, |
||||
+ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, |
||||
+ { "rijndael-cbc@lysator.liu.se", |
||||
+ SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, |
||||
+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, |
||||
+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, |
||||
+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, |
||||
+ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } |
||||
+}; |
||||
+ |
||||
/*--*/ |
||||
|
||||
/* Returns a comma-separated list of supported ciphers. */ |
||||
@@ -126,7 +142,7 @@ cipher_alg_list(char sep, int auth_only) |
||||
size_t nlen, rlen = 0; |
||||
const struct sshcipher *c; |
||||
|
||||
- for (c = ciphers; c->name != NULL; c++) { |
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) { |
||||
if (c->number != SSH_CIPHER_SSH2) |
||||
continue; |
||||
if (auth_only && c->auth_len == 0) |
||||
@@ -222,7 +238,7 @@ const struct sshcipher * |
||||
cipher_by_name(const char *name) |
||||
{ |
||||
const struct sshcipher *c; |
||||
- for (c = ciphers; c->name != NULL; c++) |
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) |
||||
if (strcmp(c->name, name) == 0) |
||||
return c; |
||||
return NULL; |
||||
@@ -232,7 +248,7 @@ const struct sshcipher * |
||||
cipher_by_number(int id) |
||||
{ |
||||
const struct sshcipher *c; |
||||
- for (c = ciphers; c->name != NULL; c++) |
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) |
||||
if (c->number == id) |
||||
return c; |
||||
return NULL; |
||||
@@ -273,7 +289,7 @@ cipher_number(const char *name) |
||||
const struct sshcipher *c; |
||||
if (name == NULL) |
||||
return -1; |
||||
- for (c = ciphers; c->name != NULL; c++) |
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) |
||||
if (strcasecmp(c->name, name) == 0) |
||||
return c->number; |
||||
return -1; |
||||
diff -up openssh-7.4p1/cipher-ctr.c.fips openssh-7.4p1/cipher-ctr.c |
||||
--- openssh-7.4p1/cipher-ctr.c.fips 2017-02-09 14:53:47.125347498 +0100 |
||||
+++ openssh-7.4p1/cipher-ctr.c 2017-02-09 14:53:47.182347441 +0100 |
||||
@@ -179,7 +179,8 @@ evp_aes_128_ctr(void) |
||||
aes_ctr.do_cipher = ssh_aes_ctr; |
||||
#ifndef SSH_OLD_EVP |
||||
aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | |
||||
- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; |
||||
+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV | |
||||
+ EVP_CIPH_FLAG_FIPS; |
||||
#endif |
||||
return (&aes_ctr); |
||||
} |
||||
diff -up openssh-7.4p1/clientloop.c.fips openssh-7.4p1/clientloop.c |
||||
--- openssh-7.4p1/clientloop.c.fips 2017-05-30 19:10:26.537505598 +0200 |
||||
+++ openssh-7.4p1/clientloop.c 2017-05-30 19:10:26.571505583 +0200 |
||||
@@ -2452,7 +2452,7 @@ client_input_hostkeys(void) |
||||
/* Check that the key is accepted in HostkeyAlgorithms */ |
||||
if (match_pattern_list(sshkey_ssh_name(key), |
||||
options.hostkeyalgorithms ? options.hostkeyalgorithms : |
||||
- KEX_DEFAULT_PK_ALG, 0) != 1) { |
||||
+ (FIPS_mode() ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), 0) != 1) { |
||||
debug3("%s: %s key not permitted by HostkeyAlgorithms", |
||||
__func__, sshkey_ssh_name(key)); |
||||
continue; |
||||
diff -up openssh-7.4p1/dh.h.fips openssh-7.4p1/dh.h |
||||
--- openssh-7.4p1/dh.h.fips 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/dh.h 2017-02-09 14:53:47.182347441 +0100 |
||||
@@ -51,6 +51,7 @@ u_int dh_estimate(int); |
||||
* Miniumum increased in light of DH precomputation attacks. |
||||
*/ |
||||
#define DH_GRP_MIN 1024 |
||||
+#define DH_GRP_MIN_FIPS 2048 |
||||
#define DH_GRP_MAX 8192 |
||||
|
||||
/* |
||||
diff -up openssh-7.4p1/entropy.c.fips openssh-7.4p1/entropy.c |
||||
--- openssh-7.4p1/entropy.c.fips 2017-02-09 14:53:47.116347507 +0100 |
||||
+++ openssh-7.4p1/entropy.c 2017-02-09 14:53:47.182347441 +0100 |
||||
@@ -217,6 +217,9 @@ seed_rng(void) |
||||
fatal("OpenSSL version mismatch. Built against %lx, you " |
||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); |
||||
|
||||
+ /* clean the PRNG status when exiting the program */ |
||||
+ atexit(RAND_cleanup); |
||||
+ |
||||
#ifndef OPENSSL_PRNG_ONLY |
||||
if (RAND_status() == 1) { |
||||
debug3("RNG is ready, skipping seeding"); |
||||
diff -up openssh-7.4p1/kex.c.fips openssh-7.4p1/kex.c |
||||
--- openssh-7.4p1/kex.c.fips 2017-02-09 14:53:47.174347449 +0100 |
||||
+++ openssh-7.4p1/kex.c 2017-02-09 14:53:47.183347440 +0100 |
||||
@@ -35,6 +35,7 @@ |
||||
#ifdef WITH_OPENSSL |
||||
#include <openssl/crypto.h> |
||||
#include <openssl/dh.h> |
||||
+#include <openssl/fips.h> |
||||
#endif |
||||
|
||||
#include "ssh2.h" |
||||
@@ -124,6 +125,28 @@ static const struct kexalg kexalgs[] = { |
||||
{ NULL, -1, -1, -1}, |
||||
}; |
||||
|
||||
+static const struct kexalg kexalgs_fips[] = { |
||||
+ { KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, |
||||
+ { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, |
||||
+ { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, |
||||
+ { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 }, |
||||
+ { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, |
||||
+#ifdef HAVE_EVP_SHA256 |
||||
+ { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, |
||||
+#endif |
||||
+#ifdef OPENSSL_HAS_ECC |
||||
+ { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, |
||||
+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, |
||||
+ { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, |
||||
+ SSH_DIGEST_SHA384 }, |
||||
+# ifdef OPENSSL_HAS_NISTP521 |
||||
+ { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, |
||||
+ SSH_DIGEST_SHA512 }, |
||||
+# endif |
||||
+#endif |
||||
+ { NULL, -1, -1, -1}, |
||||
+}; |
||||
+ |
||||
char * |
||||
kex_alg_list(char sep) |
||||
{ |
||||
@@ -151,7 +169,7 @@ kex_alg_by_name(const char *name) |
||||
{ |
||||
const struct kexalg *k; |
||||
|
||||
- for (k = kexalgs; k->name != NULL; k++) { |
||||
+ for (k = (FIPS_mode() ? kexalgs_fips : kexalgs); k->name != NULL; k++) { |
||||
if (strcmp(k->name, name) == 0) |
||||
return k; |
||||
#ifdef GSSAPI |
||||
@@ -177,7 +195,10 @@ kex_names_valid(const char *names) |
||||
for ((p = strsep(&cp, ",")); p && *p != '\0'; |
||||
(p = strsep(&cp, ","))) { |
||||
if (kex_alg_by_name(p) == NULL) { |
||||
- error("Unsupported KEX algorithm \"%.100s\"", p); |
||||
+ if (FIPS_mode()) |
||||
+ error("\"%.100s\" is not allowed in FIPS mode", p); |
||||
+ else |
||||
+ error("Unsupported KEX algorithm \"%.100s\"", p); |
||||
free(s); |
||||
return 0; |
||||
} |
||||
diff -up openssh-7.4p1/kexgexc.c.fips openssh-7.4p1/kexgexc.c |
||||
--- openssh-7.4p1/kexgexc.c.fips 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/kexgexc.c 2017-02-09 14:53:47.183347440 +0100 |
||||
@@ -28,6 +28,7 @@ |
||||
|
||||
#ifdef WITH_OPENSSL |
||||
|
||||
+#include <openssl/fips.h> |
||||
#include <sys/types.h> |
||||
|
||||
#include <openssl/dh.h> |
||||
@@ -63,7 +64,7 @@ kexgex_client(struct ssh *ssh) |
||||
|
||||
nbits = dh_estimate(kex->dh_need * 8); |
||||
|
||||
- kex->min = DH_GRP_MIN; |
||||
+ kex->min = FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN; |
||||
kex->max = DH_GRP_MAX; |
||||
kex->nbits = nbits; |
||||
if (datafellows & SSH_BUG_DHGEX_LARGE) |
||||
diff -up openssh-7.4p1/kexgexs.c.fips openssh-7.4p1/kexgexs.c |
||||
--- openssh-7.4p1/kexgexs.c.fips 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/kexgexs.c 2017-02-09 14:53:47.183347440 +0100 |
||||
@@ -83,9 +83,9 @@ input_kex_dh_gex_request(int type, u_int |
||||
kex->nbits = nbits; |
||||
kex->min = min; |
||||
kex->max = max; |
||||
- min = MAXIMUM(DH_GRP_MIN, min); |
||||
+ min = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, min); |
||||
max = MINIMUM(DH_GRP_MAX, max); |
||||
- nbits = MAXIMUM(DH_GRP_MIN, nbits); |
||||
+ nbits = MAXIMUM(FIPS_mode() ? DH_GRP_MIN_FIPS : DH_GRP_MIN, nbits); |
||||
nbits = MINIMUM(DH_GRP_MAX, nbits); |
||||
|
||||
if (kex->max < kex->min || kex->nbits < kex->min || |
||||
diff -up openssh-7.4p1/mac.c.fips openssh-7.4p1/mac.c |
||||
--- openssh-7.4p1/mac.c.fips 2017-02-09 14:53:47.175347448 +0100 |
||||
+++ openssh-7.4p1/mac.c 2017-02-09 14:53:47.183347440 +0100 |
||||
@@ -27,6 +27,8 @@ |
||||
|
||||
#include <sys/types.h> |
||||
|
||||
+#include <openssl/fips.h> |
||||
+ |
||||
#include <string.h> |
||||
#include <stdio.h> |
||||
|
||||
@@ -54,7 +56,7 @@ struct macalg { |
||||
int etm; /* Encrypt-then-MAC */ |
||||
}; |
||||
|
||||
-static const struct macalg macs[] = { |
||||
+static const struct macalg all_macs[] = { |
||||
/* Encrypt-and-MAC (encrypt-and-authenticate) variants */ |
||||
{ "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, |
||||
{ "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, |
||||
@@ -89,6 +91,24 @@ static const struct macalg macs[] = { |
||||
{ NULL, 0, 0, 0, 0, 0, 0 } |
||||
}; |
||||
|
||||
+static const struct macalg fips_macs[] = { |
||||
+ /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ |
||||
+ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, |
||||
+#ifdef HAVE_EVP_SHA256 |
||||
+ { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 }, |
||||
+ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, |
||||
+#endif |
||||
+ |
||||
+ /* Encrypt-then-MAC variants */ |
||||
+ { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, |
||||
+#ifdef HAVE_EVP_SHA256 |
||||
+ { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 }, |
||||
+ { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 }, |
||||
+#endif |
||||
+ |
||||
+ { NULL, 0, 0, 0, 0, 0, 0 } |
||||
+}; |
||||
+ |
||||
/* Returns a list of supported MACs separated by the specified char. */ |
||||
char * |
||||
mac_alg_list(char sep) |
||||
@@ -97,7 +117,7 @@ mac_alg_list(char sep) |
||||
size_t nlen, rlen = 0; |
||||
const struct macalg *m; |
||||
|
||||
- for (m = macs; m->name != NULL; m++) { |
||||
+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { |
||||
if (ret != NULL) |
||||
ret[rlen++] = sep; |
||||
nlen = strlen(m->name); |
||||
@@ -136,7 +156,7 @@ mac_setup(struct sshmac *mac, char *name |
||||
{ |
||||
const struct macalg *m; |
||||
|
||||
- for (m = macs; m->name != NULL; m++) { |
||||
+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) { |
||||
if (strcmp(name, m->name) != 0) |
||||
continue; |
||||
if (mac != NULL) |
||||
diff -up openssh-7.4p1/Makefile.in.fips openssh-7.4p1/Makefile.in |
||||
--- openssh-7.4p1/Makefile.in.fips 2017-02-09 14:53:47.175347448 +0100 |
||||
+++ openssh-7.4p1/Makefile.in 2017-02-09 14:53:47.184347440 +0100 |
||||
@@ -168,25 +168,25 @@ libssh.a: $(LIBSSH_OBJS) |
||||
$(RANLIB) $@ |
||||
|
||||
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) |
||||
- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) |
||||
+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(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 -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) |
||||
|
||||
scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o |
||||
$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
|
||||
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o |
||||
- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o |
||||
- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o |
||||
- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o |
||||
- $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) |
||||
|
||||
ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o |
||||
$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) |
||||
@@ -205,7 +205,7 @@ ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a |
||||
$(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o |
||||
- $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) |
||||
+ $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) |
||||
|
||||
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o |
||||
$(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
diff -up openssh-7.4p1/myproposal.h.fips openssh-7.4p1/myproposal.h |
||||
--- openssh-7.4p1/myproposal.h.fips 2017-05-30 19:10:26.535505599 +0200 |
||||
+++ openssh-7.4p1/myproposal.h 2017-05-30 19:10:26.574505582 +0200 |
||||
@@ -119,6 +119,14 @@ |
||||
"ssh-rsa," \ |
||||
"ssh-dss" |
||||
|
||||
+#define KEX_FIPS_PK_ALG \ |
||||
+ HOSTKEY_ECDSA_CERT_METHODS \ |
||||
+ "ssh-rsa-cert-v01@openssh.com," \ |
||||
+ HOSTKEY_ECDSA_METHODS \ |
||||
+ "rsa-sha2-512," \ |
||||
+ "rsa-sha2-256," \ |
||||
+ "ssh-rsa" |
||||
+ |
||||
/* the actual algorithms */ |
||||
|
||||
#define KEX_CLIENT_ENCRYPT \ |
||||
@@ -144,6 +152,37 @@ |
||||
|
||||
#define KEX_CLIENT_MAC KEX_SERVER_MAC |
||||
|
||||
+#define KEX_FIPS_ENCRYPT \ |
||||
+ "aes128-ctr,aes192-ctr,aes256-ctr," \ |
||||
+ "aes128-cbc,3des-cbc," \ |
||||
+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" |
||||
+#ifdef HAVE_EVP_SHA256 |
||||
+# define KEX_DEFAULT_KEX_FIPS \ |
||||
+ KEX_ECDH_METHODS \ |
||||
+ KEX_SHA2_METHODS \ |
||||
+ "diffie-hellman-group14-sha256" |
||||
+# define KEX_FIPS_MAC \ |
||||
+ "hmac-sha1," \ |
||||
+ "hmac-sha2-256," \ |
||||
+ "hmac-sha2-512," \ |
||||
+ "hmac-sha1-etm@openssh.com," \ |
||||
+ "hmac-sha2-256-etm@openssh.com," \ |
||||
+ "hmac-sha2-512-etm@openssh.com" |
||||
+#else |
||||
+# ifdef OPENSSL_HAS_NISTP521 |
||||
+# define KEX_DEFAULT_KEX_FIPS \ |
||||
+ "ecdh-sha2-nistp256," \ |
||||
+ "ecdh-sha2-nistp384," \ |
||||
+ "ecdh-sha2-nistp521" |
||||
+# else |
||||
+# define KEX_DEFAULT_KEX_FIPS \ |
||||
+ "ecdh-sha2-nistp256," \ |
||||
+ "ecdh-sha2-nistp384" |
||||
+# endif |
||||
+#define KEX_FIPS_MAC \ |
||||
+ "hmac-sha1" |
||||
+#endif |
||||
+ |
||||
#else /* WITH_OPENSSL */ |
||||
|
||||
#define KEX_SERVER_KEX \ |
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.fips openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.fips 2017-02-09 14:53:47.184347440 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c 2017-02-09 14:55:25.123250447 +0100 |
||||
@@ -102,7 +102,8 @@ pamsshagentauth_check_authkeys_file(FILE |
||||
found_key = 1; |
||||
logit("matching key found: file/command %s, line %lu", file, |
||||
linenum); |
||||
- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); |
||||
+ fp = sshkey_fingerprint(found, FIPS_mode() ? SSH_DIGEST_SHA1 : SSH_DIGEST_MD5, |
||||
+ SSH_FP_HEX); |
||||
logit("Found matching %s key: %s", |
||||
key_type(found), fp); |
||||
free(fp); |
||||
diff -up openssh-7.4p1/readconf.c.fips openssh-7.4p1/readconf.c |
||||
--- openssh-7.4p1/readconf.c.fips 2017-02-09 14:53:47.185347438 +0100 |
||||
+++ openssh-7.4p1/readconf.c 2017-02-09 14:56:24.840191308 +0100 |
||||
@@ -2104,12 +2104,17 @@ fill_default_options(Options * options) |
||||
} |
||||
if (options->update_hostkeys == -1) |
||||
options->update_hostkeys = 0; |
||||
- if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || |
||||
- kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 || |
||||
- kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 || |
||||
- kex_assemble_names(KEX_DEFAULT_PK_ALG, |
||||
+ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT |
||||
+ : KEX_CLIENT_ENCRYPT), &options->ciphers) != 0 || |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC |
||||
+ : KEX_CLIENT_MAC), &options->macs) != 0 || |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS |
||||
+ : KEX_CLIENT_KEX), &options->kex_algorithms) != 0 || |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG), |
||||
&options->hostbased_key_types) != 0 || |
||||
- kex_assemble_names(KEX_DEFAULT_PK_ALG, |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG), |
||||
&options->pubkey_key_types) != 0) |
||||
fatal("%s: kex_assemble_names failed", __func__); |
||||
|
||||
@@ -2559,7 +2564,8 @@ dump_client_config(Options *o, const cha |
||||
char buf[8]; |
||||
|
||||
/* This is normally prepared in ssh_kex2 */ |
||||
- if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) |
||||
+ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG), &o->hostkeyalgorithms) != 0) |
||||
fatal("%s: kex_assemble_names failed", __func__); |
||||
|
||||
/* Most interesting options first: user, host, port */ |
||||
diff -up openssh-7.4p1/sandbox-seccomp-filter.c.fips openssh-7.4p1/sandbox-seccomp-filter.c |
||||
--- openssh-7.4p1/sandbox-seccomp-filter.c.fips 2017-02-09 14:53:47.177347446 +0100 |
||||
+++ openssh-7.4p1/sandbox-seccomp-filter.c 2017-02-09 14:53:47.185347438 +0100 |
||||
@@ -118,6 +118,9 @@ static const struct sock_filter preauth_ |
||||
#ifdef __NR_open |
||||
SC_DENY(open, EACCES), |
||||
#endif |
||||
+#ifdef __NR_socket |
||||
+ SC_DENY(socket, EACCES), |
||||
+#endif |
||||
#ifdef __NR_openat |
||||
SC_DENY(openat, EACCES), |
||||
#endif |
||||
diff -up openssh-7.4p1/servconf.c.fips openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.fips 2017-06-07 13:07:28.403983349 +0200 |
||||
+++ openssh-7.4p1/servconf.c 2017-06-07 13:09:46.710997099 +0200 |
||||
@@ -185,14 +185,20 @@ option_clear_or_none(const char *o) |
||||
static void |
||||
assemble_algorithms(ServerOptions *o) |
||||
{ |
||||
- if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || |
||||
- kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || |
||||
- kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || |
||||
- kex_assemble_names(KEX_DEFAULT_PK_ALG, |
||||
+ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_ENCRYPT |
||||
+ : KEX_SERVER_ENCRYPT), &o->ciphers) != 0 || |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_MAC |
||||
+ : KEX_SERVER_MAC), &o->macs) != 0 || |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_DEFAULT_KEX_FIPS |
||||
+ : KEX_SERVER_KEX), &o->kex_algorithms) != 0 || |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG), |
||||
&o->hostkeyalgorithms) != 0 || |
||||
- kex_assemble_names(KEX_DEFAULT_PK_ALG, |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG), |
||||
&o->hostbased_key_types) != 0 || |
||||
- kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) |
||||
+ kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG), &o->pubkey_key_types) != 0) |
||||
fatal("kex_assemble_names failed"); |
||||
} |
||||
|
||||
@@ -2390,8 +2396,10 @@ dump_config(ServerOptions *o) |
||||
/* string arguments */ |
||||
dump_cfg_string(sPidFile, o->pid_file); |
||||
dump_cfg_string(sXAuthLocation, o->xauth_location); |
||||
- dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); |
||||
- dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); |
||||
+ dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : FIPS_mode() |
||||
+ ? KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT); |
||||
+ dump_cfg_string(sMacs, o->macs ? o->macs : FIPS_mode() |
||||
+ ? KEX_FIPS_MAC : KEX_SERVER_MAC); |
||||
dump_cfg_string(sBanner, o->banner == NULL ? "none" : o->banner); |
||||
dump_cfg_string(sForceCommand, o->adm_forced_command); |
||||
dump_cfg_string(sChrootDirectory, o->chroot_directory); |
||||
@@ -2406,14 +2414,17 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command); |
||||
dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user); |
||||
dump_cfg_string(sHostKeyAgent, o->host_key_agent); |
||||
- dump_cfg_string(sKexAlgorithms, |
||||
- o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); |
||||
+ dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : |
||||
+ FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX); |
||||
dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? |
||||
- o->hostbased_key_types : KEX_DEFAULT_PK_ALG); |
||||
+ o->hostbased_key_types : (FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG)); |
||||
dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ? |
||||
- o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); |
||||
+ o->hostkeyalgorithms : (FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG)); |
||||
dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? |
||||
- o->pubkey_key_types : KEX_DEFAULT_PK_ALG); |
||||
+ o->pubkey_key_types : (FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG)); |
||||
|
||||
/* string arguments requiring a lookup */ |
||||
dump_cfg_string(sLogLevel, log_level_name(o->log_level)); |
||||
diff -up openssh-7.4p1/ssh.c.fips openssh-7.4p1/ssh.c |
||||
--- openssh-7.4p1/ssh.c.fips 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/ssh.c 2017-02-09 14:53:47.185347438 +0100 |
||||
@@ -76,6 +76,8 @@ |
||||
#include <openssl/evp.h> |
||||
#include <openssl/err.h> |
||||
#endif |
||||
+#include <openssl/fips.h> |
||||
+#include <fipscheck.h> |
||||
#include "openbsd-compat/openssl-compat.h" |
||||
#include "openbsd-compat/sys-queue.h" |
||||
|
||||
@@ -530,6 +532,14 @@ main(int ac, char **av) |
||||
sanitise_stdfd(); |
||||
|
||||
__progname = ssh_get_progname(av[0]); |
||||
+ SSLeay_add_all_algorithms(); |
||||
+ if (access("/etc/system-fips", F_OK) == 0) |
||||
+ if (! FIPSCHECK_verify(NULL, NULL)){ |
||||
+ if (FIPS_mode()) |
||||
+ fatal("FIPS integrity verification test failed."); |
||||
+ else |
||||
+ logit("FIPS integrity verification test failed."); |
||||
+ } |
||||
|
||||
#ifndef HAVE_SETPROCTITLE |
||||
/* Prepare for later setproctitle emulation */ |
||||
@@ -609,6 +619,9 @@ main(int ac, char **av) |
||||
"ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { |
||||
switch (opt) { |
||||
case '1': |
||||
+ if (FIPS_mode()) { |
||||
+ fatal("Protocol 1 not allowed in the FIPS mode."); |
||||
+ } |
||||
options.protocol = SSH_PROTO_1; |
||||
break; |
||||
case '2': |
||||
@@ -964,7 +977,6 @@ main(int ac, char **av) |
||||
host_arg = xstrdup(host); |
||||
|
||||
#ifdef WITH_OPENSSL |
||||
- OpenSSL_add_all_algorithms(); |
||||
ERR_load_crypto_strings(); |
||||
#endif |
||||
|
||||
@@ -1175,6 +1187,10 @@ main(int ac, char **av) |
||||
|
||||
seed_rng(); |
||||
|
||||
+ if (FIPS_mode()) { |
||||
+ logit("FIPS mode initialized"); |
||||
+ } |
||||
+ |
||||
if (options.user == NULL) |
||||
options.user = xstrdup(pw->pw_name); |
||||
|
||||
@@ -1263,6 +1279,12 @@ main(int ac, char **av) |
||||
|
||||
timeout_ms = options.connection_timeout * 1000; |
||||
|
||||
+ if (FIPS_mode()) { |
||||
+ options.protocol &= SSH_PROTO_2; |
||||
+ if (options.protocol == 0) |
||||
+ fatal("Protocol 2 disabled by configuration but required in the FIPS mode."); |
||||
+ } |
||||
+ |
||||
/* Open a connection to the remote host. */ |
||||
if (ssh_connect(host, addrs, &hostaddr, options.port, |
||||
options.address_family, options.connection_attempts, |
||||
diff -up openssh-7.4p1/sshconnect2.c.fips openssh-7.4p1/sshconnect2.c |
||||
--- openssh-7.4p1/sshconnect2.c.fips 2017-02-09 14:53:47.162347461 +0100 |
||||
+++ openssh-7.4p1/sshconnect2.c 2017-02-09 14:53:47.186347437 +0100 |
||||
@@ -44,6 +44,8 @@ |
||||
#include <vis.h> |
||||
#endif |
||||
|
||||
+#include <openssl/fips.h> |
||||
+ |
||||
#include "openbsd-compat/sys-queue.h" |
||||
|
||||
#include "xmalloc.h" |
||||
@@ -117,7 +119,8 @@ order_hostkeyalgs(char *host, struct soc |
||||
for (i = 0; i < options.num_system_hostfiles; i++) |
||||
load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); |
||||
|
||||
- oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); |
||||
+ oavail = avail = xstrdup((FIPS_mode() |
||||
+ ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG)); |
||||
maxlen = strlen(avail) + 1; |
||||
first = xmalloc(maxlen); |
||||
last = xmalloc(maxlen); |
||||
@@ -172,21 +175,26 @@ ssh_kex2(char *host, struct sockaddr *ho |
||||
|
||||
#ifdef GSSAPI |
||||
if (options.gss_keyex) { |
||||
- /* Add the GSSAPI mechanisms currently supported on this |
||||
- * client to the key exchange algorithm proposal */ |
||||
- orig = options.kex_algorithms; |
||||
- |
||||
- if (options.gss_trust_dns) |
||||
- gss_host = (char *)get_canonical_hostname(active_state, 1); |
||||
- else |
||||
- gss_host = host; |
||||
- |
||||
- gss = ssh_gssapi_client_mechanisms(gss_host, |
||||
- options.gss_client_identity, options.gss_kex_algorithms); |
||||
- if (gss) { |
||||
- debug("Offering GSSAPI proposal: %s", gss); |
||||
- xasprintf(&options.kex_algorithms, |
||||
- "%s,%s", gss, orig); |
||||
+ if (FIPS_mode()) { |
||||
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); |
||||
+ options.gss_keyex = 0; |
||||
+ } else { |
||||
+ /* Add the GSSAPI mechanisms currently supported on this |
||||
+ * client to the key exchange algorithm proposal */ |
||||
+ orig = options.kex_algorithms; |
||||
+ |
||||
+ if (options.gss_trust_dns) |
||||
+ gss_host = (char *)get_canonical_hostname(active_state, 1); |
||||
+ else |
||||
+ gss_host = host; |
||||
+ |
||||
+ gss = ssh_gssapi_client_mechanisms(gss_host, |
||||
+ options.gss_client_identity, options.gss_kex_algorithms); |
||||
+ if (gss) { |
||||
+ debug("Offering GSSAPI proposal: %s", gss); |
||||
+ xasprintf(&options.kex_algorithms, |
||||
+ "%s,%s", gss, orig); |
||||
+ } |
||||
} |
||||
} |
||||
#endif |
||||
@@ -204,14 +212,16 @@ ssh_kex2(char *host, struct sockaddr *ho |
||||
myproposal[PROPOSAL_MAC_ALGS_CTOS] = |
||||
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; |
||||
if (options.hostkeyalgorithms != NULL) { |
||||
- if (kex_assemble_names(KEX_DEFAULT_PK_ALG, |
||||
+ if (kex_assemble_names((FIPS_mode() ? KEX_FIPS_PK_ALG |
||||
+ : KEX_DEFAULT_PK_ALG), |
||||
&options.hostkeyalgorithms) != 0) |
||||
fatal("%s: kex_assemble_namelist", __func__); |
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = |
||||
compat_pkalg_proposal(options.hostkeyalgorithms); |
||||
} else { |
||||
/* Enforce default */ |
||||
- options.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); |
||||
+ options.hostkeyalgorithms = xstrdup((FIPS_mode() |
||||
+ ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG)); |
||||
/* Prefer algorithms that we already have keys for */ |
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = |
||||
compat_pkalg_proposal( |
||||
diff -up openssh-7.4p1/sshd.c.fips openssh-7.4p1/sshd.c |
||||
--- openssh-7.4p1/sshd.c.fips 2017-02-09 14:53:47.178347445 +0100 |
||||
+++ openssh-7.4p1/sshd.c 2017-02-09 14:53:47.186347437 +0100 |
||||
@@ -66,6 +66,7 @@ |
||||
#include <grp.h> |
||||
#include <pwd.h> |
||||
#include <signal.h> |
||||
+#include <syslog.h> |
||||
#include <stdarg.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
@@ -77,6 +78,8 @@ |
||||
#include <openssl/dh.h> |
||||
#include <openssl/bn.h> |
||||
#include <openssl/rand.h> |
||||
+#include <openssl/fips.h> |
||||
+#include <fipscheck.h> |
||||
#include "openbsd-compat/openssl-compat.h" |
||||
#endif |
||||
|
||||
@@ -1471,6 +1474,18 @@ main(int ac, char **av) |
||||
#endif |
||||
__progname = ssh_get_progname(av[0]); |
||||
|
||||
+ SSLeay_add_all_algorithms(); |
||||
+ if (access("/etc/system-fips", F_OK) == 0) |
||||
+ if (! FIPSCHECK_verify(NULL, NULL)) { |
||||
+ openlog(__progname, LOG_PID, LOG_AUTHPRIV); |
||||
+ if (FIPS_mode()) { |
||||
+ syslog(LOG_CRIT, "FIPS integrity verification test failed."); |
||||
+ cleanup_exit(255); |
||||
+ } |
||||
+ else |
||||
+ syslog(LOG_INFO, "FIPS integrity verification test failed."); |
||||
+ closelog(); |
||||
+ } |
||||
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ |
||||
saved_argc = ac; |
||||
rexec_argc = ac; |
||||
@@ -1619,7 +1634,7 @@ main(int ac, char **av) |
||||
else |
||||
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); |
||||
|
||||
-#ifdef WITH_OPENSSL |
||||
+#if 0 /* FIPS */ |
||||
OpenSSL_add_all_algorithms(); |
||||
#endif |
||||
|
||||
@@ -1928,6 +1943,10 @@ main(int ac, char **av) |
||||
/* Reinitialize the log (because of the fork above). */ |
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr); |
||||
|
||||
+ if (FIPS_mode()) { |
||||
+ logit("FIPS mode initialized"); |
||||
+ } |
||||
+ |
||||
/* Chdir to the root directory so that the current disk can be |
||||
unmounted if desired. */ |
||||
if (chdir("/") == -1) |
||||
@@ -2282,10 +2301,14 @@ do_ssh2_kex(void) |
||||
if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) |
||||
orig = NULL; |
||||
|
||||
- if (options.gss_keyex) |
||||
- gss = ssh_gssapi_server_mechanisms(); |
||||
- else |
||||
- gss = NULL; |
||||
+ if (options.gss_keyex) { |
||||
+ if (FIPS_mode()) { |
||||
+ logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode"); |
||||
+ options.gss_keyex = 0; |
||||
+ } else { |
||||
+ gss = ssh_gssapi_server_mechanisms(); |
||||
+ } |
||||
+ } |
||||
|
||||
if (gss && orig) |
||||
xasprintf(&newstr, "%s,%s", gss, orig); |
||||
diff -up openssh-7.4p1/sshkey.c.fips openssh-7.4p1/sshkey.c |
||||
--- openssh-7.4p1/sshkey.c.fips 2017-02-09 14:53:47.179347444 +0100 |
||||
+++ openssh-7.4p1/sshkey.c 2017-02-09 14:58:02.117094971 +0100 |
||||
@@ -34,6 +34,7 @@ |
||||
#include <openssl/evp.h> |
||||
#include <openssl/err.h> |
||||
#include <openssl/pem.h> |
||||
+#include <openssl/fips.h> |
||||
#endif |
||||
|
||||
#include "crypto_api.h" |
||||
@@ -57,6 +58,7 @@ |
||||
#include "sshkey.h" |
||||
#include "match.h" |
||||
#include "xmalloc.h" |
||||
+#include "log.h" |
||||
|
||||
/* openssh private key file format */ |
||||
#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" |
||||
@@ -1555,6 +1557,8 @@ rsa_generate_private_key(u_int bits, RSA |
||||
} |
||||
if (!BN_set_word(f4, RSA_F4) || |
||||
!RSA_generate_key_ex(private, bits, f4, NULL)) { |
||||
+ if (FIPS_mode()) |
||||
+ logit("%s: the key length might be unsupported by FIPS mode approved key generation method", __func__); |
||||
ret = SSH_ERR_LIBCRYPTO_ERROR; |
||||
goto out; |
||||
} |
||||
@@ -3921,8 +3925,11 @@ sshkey_parse_private_fileblob_type(struc |
||||
switch (type) { |
||||
#ifdef WITH_SSH1 |
||||
case KEY_RSA1: |
||||
- return sshkey_parse_private_rsa1(blob, passphrase, |
||||
- keyp, commentp); |
||||
+ if (! FIPS_mode()) |
||||
+ return sshkey_parse_private_rsa1(blob, passphrase, |
||||
+ keyp, commentp); |
||||
+ error("%s: cannot parse rsa1 key in FIPS mode", __func__); |
||||
+ return SSH_ERR_KEY_TYPE_UNKNOWN; |
||||
#endif /* WITH_SSH1 */ |
||||
#ifdef WITH_OPENSSL |
||||
case KEY_DSA: |
||||
@@ -3961,8 +3968,9 @@ sshkey_parse_private_fileblob(struct ssh |
||||
#ifdef WITH_SSH1 |
||||
/* it's a SSH v1 key if the public key part is readable */ |
||||
if (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) { |
||||
- return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1, |
||||
- passphrase, keyp, commentp); |
||||
+ if (!FIPS_mode()) |
||||
+ return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1, |
||||
+ passphrase, keyp, commentp); |
||||
} |
||||
#endif /* WITH_SSH1 */ |
||||
return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, |
||||
diff -up openssh-7.4p1/ssh-keygen.c.fips openssh-7.4p1/ssh-keygen.c |
||||
--- openssh-7.4p1/ssh-keygen.c.fips 2017-05-22 13:50:06.731776762 +0200 |
||||
+++ openssh-7.4p1/ssh-keygen.c 2017-05-22 13:50:11.843773909 +0200 |
||||
@@ -215,6 +215,12 @@ type_bits_valid(int type, const char *na |
||||
OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; |
||||
if (*bitsp > maxbits) |
||||
fatal("key bits exceeds maximum %d", maxbits); |
||||
+ if (FIPS_mode()) { |
||||
+ if (type == KEY_DSA) |
||||
+ fatal("DSA keys are not allowed in FIPS mode"); |
||||
+ if (type == KEY_ED25519) |
||||
+ fatal("ED25519 keys are not allowed in FIPS mode"); |
||||
+ } |
||||
if (type == KEY_DSA && *bitsp != 1024) |
||||
fatal("DSA keys must be 1024 bits"); |
||||
else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024) |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
From 13bd2e2d622d01dc85d22b94520a5b243d006049 Mon Sep 17 00:00:00 2001 |
||||
From: "djm@openbsd.org" <djm@openbsd.org> |
||||
Date: Fri, 6 Jan 2017 03:45:41 +0000 |
||||
Subject: [PATCH] upstream commit |
||||
|
||||
sshd_config is documented to set |
||||
GSSAPIStrictAcceptorCheck=yes by default, so actually make it do this. |
||||
bz#2637 ok dtucker |
||||
|
||||
Upstream-ID: 99ef8ac51f17f0f7aec166cb2e34228d4d72a665 |
||||
--- |
||||
servconf.c | 4 ++-- |
||||
1 file changed, 2 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/servconf.c b/servconf.c |
||||
index 795ddbab7..c9105a592 100644 |
||||
--- a/servconf.c |
||||
+++ b/servconf.c |
||||
@@ -270,7 +270,7 @@ fill_default_server_options(ServerOptions *options) |
||||
if (options->gss_cleanup_creds == -1) |
||||
options->gss_cleanup_creds = 1; |
||||
if (options->gss_strict_acceptor == -1) |
||||
- options->gss_strict_acceptor = 0; |
||||
+ options->gss_strict_acceptor = 1; |
||||
if (options->gss_store_rekey == -1) |
||||
options->gss_store_rekey = 0; |
||||
if (options->password_authentication == -1) |
||||
|
@ -0,0 +1,410 @@
@@ -0,0 +1,410 @@
|
||||
diff -up openssh-7.4p1/gss-genr.c.gsskexalg openssh-7.4p1/gss-genr.c |
||||
--- openssh-7.4p1/gss-genr.c.gsskexalg 2017-02-09 10:46:50.417893132 +0100 |
||||
+++ openssh-7.4p1/gss-genr.c 2017-02-09 10:46:50.448893107 +0100 |
||||
@@ -77,7 +77,8 @@ ssh_gssapi_oid_table_ok() { |
||||
*/ |
||||
|
||||
char * |
||||
-ssh_gssapi_client_mechanisms(const char *host, const char *client) { |
||||
+ssh_gssapi_client_mechanisms(const char *host, const char *client, |
||||
+ const char *kex) { |
||||
gss_OID_set gss_supported; |
||||
OM_uint32 min_status; |
||||
|
||||
@@ -85,12 +86,12 @@ ssh_gssapi_client_mechanisms(const char |
||||
return NULL; |
||||
|
||||
return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, |
||||
- host, client)); |
||||
+ host, client, kex)); |
||||
} |
||||
|
||||
char * |
||||
ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, |
||||
- const char *host, const char *client) { |
||||
+ const char *host, const char *client, const char *kex) { |
||||
Buffer buf; |
||||
size_t i; |
||||
int oidpos, enclen; |
||||
@@ -99,6 +100,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
||||
char deroid[2]; |
||||
const EVP_MD *evp_md = EVP_md5(); |
||||
EVP_MD_CTX md; |
||||
+ char *s, *cp, *p; |
||||
|
||||
if (gss_enc2oid != NULL) { |
||||
for (i = 0; gss_enc2oid[i].encoded != NULL; i++) |
||||
@@ -112,6 +114,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
||||
buffer_init(&buf); |
||||
|
||||
oidpos = 0; |
||||
+ s = cp = strdup(kex); |
||||
for (i = 0; i < gss_supported->count; i++) { |
||||
if (gss_supported->elements[i].length < 128 && |
||||
(*check)(NULL, &(gss_supported->elements[i]), host, client)) { |
||||
@@ -130,26 +133,22 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup |
||||
enclen = __b64_ntop(digest, EVP_MD_size(evp_md), |
||||
encoded, EVP_MD_size(evp_md) * 2); |
||||
|
||||
- if (oidpos != 0) |
||||
- buffer_put_char(&buf, ','); |
||||
- |
||||
- buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, |
||||
- sizeof(KEX_GSS_GEX_SHA1_ID) - 1); |
||||
- buffer_append(&buf, encoded, enclen); |
||||
- buffer_put_char(&buf, ','); |
||||
- buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, |
||||
- sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); |
||||
- buffer_append(&buf, encoded, enclen); |
||||
- buffer_put_char(&buf, ','); |
||||
- buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, |
||||
- sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); |
||||
- buffer_append(&buf, encoded, enclen); |
||||
+ cp = strncpy(s, kex, strlen(kex)); |
||||
+ for ((p = strsep(&cp, ",")); p && *p != '\0'; |
||||
+ (p = strsep(&cp, ","))) { |
||||
+ if (buffer_len(&buf) != 0) |
||||
+ buffer_put_char(&buf, ','); |
||||
+ buffer_append(&buf, p, |
||||
+ strlen(p)); |
||||
+ buffer_append(&buf, encoded, enclen); |
||||
+ } |
||||
|
||||
gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); |
||||
gss_enc2oid[oidpos].encoded = encoded; |
||||
oidpos++; |
||||
} |
||||
} |
||||
+ free(s); |
||||
gss_enc2oid[oidpos].oid = NULL; |
||||
gss_enc2oid[oidpos].encoded = NULL; |
||||
|
||||
diff -up openssh-7.4p1/gss-serv.c.gsskexalg openssh-7.4p1/gss-serv.c |
||||
--- openssh-7.4p1/gss-serv.c.gsskexalg 2017-02-09 10:46:50.449893106 +0100 |
||||
+++ openssh-7.4p1/gss-serv.c 2017-02-09 10:55:12.189422901 +0100 |
||||
@@ -149,7 +149,7 @@ ssh_gssapi_server_mechanisms() { |
||||
if (supported_oids == NULL) |
||||
ssh_gssapi_prepare_supported_oids(); |
||||
return (ssh_gssapi_kex_mechs(supported_oids, |
||||
- &ssh_gssapi_server_check_mech, NULL, NULL)); |
||||
+ &ssh_gssapi_server_check_mech, NULL, NULL, options.gss_kex_algorithms)); |
||||
} |
||||
|
||||
/* Unprivileged */ |
||||
diff -up openssh-7.4p1/kex.c.gsskexalg openssh-7.4p1/kex.c |
||||
--- openssh-7.4p1/kex.c.gsskexalg 2017-02-09 10:46:50.449893106 +0100 |
||||
+++ openssh-7.4p1/kex.c 2017-02-09 10:55:44.008393539 +0100 |
||||
@@ -248,6 +248,29 @@ kex_assemble_names(const char *def, char |
||||
return 0; |
||||
} |
||||
|
||||
+/* Validate GSS KEX method name list */ |
||||
+int |
||||
+gss_kex_names_valid(const char *names) |
||||
+{ |
||||
+ char *s, *cp, *p; |
||||
+ |
||||
+ if (names == NULL || *names == '\0') |
||||
+ return 0; |
||||
+ s = cp = strdup(names); |
||||
+ for ((p = strsep(&cp, ",")); p && *p != '\0'; |
||||
+ (p = strsep(&cp, ","))) { |
||||
+ if (strncmp(p, "gss-", 4) != 0 |
||||
+ || kex_alg_by_name(p) == NULL) { |
||||
+ error("Unsupported KEX algorithm \"%.100s\"", p); |
||||
+ free(s); |
||||
+ return 0; |
||||
+ } |
||||
+ } |
||||
+ debug3("gss kex names ok: [%s]", names); |
||||
+ free(s); |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
/* put algorithm proposal into buffer */ |
||||
int |
||||
kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) |
||||
diff -up openssh-7.4p1/kex.h.gsskexalg openssh-7.4p1/kex.h |
||||
--- openssh-7.4p1/kex.h.gsskexalg 2017-02-09 10:46:50.452893104 +0100 |
||||
+++ openssh-7.4p1/kex.h 2017-02-09 11:02:35.313012903 +0100 |
||||
@@ -179,6 +179,7 @@ struct kex { |
||||
char *kex_alg_list(char); |
||||
char *kex_names_cat(const char *, const char *); |
||||
int kex_assemble_names(const char *, char **); |
||||
+int gss_kex_names_valid(const char *); |
||||
|
||||
int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); |
||||
int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); |
||||
diff -up openssh-7.4p1/readconf.c.gsskexalg openssh-7.4p1/readconf.c |
||||
--- openssh-7.4p1/readconf.c.gsskexalg 2017-02-09 10:46:50.420893129 +0100 |
||||
+++ openssh-7.4p1/readconf.c 2017-02-09 10:56:06.759372540 +0100 |
||||
@@ -64,6 +64,7 @@ |
||||
#include "uidswap.h" |
||||
#include "myproposal.h" |
||||
#include "digest.h" |
||||
+#include "ssh-gss.h" |
||||
|
||||
/* Format of the configuration file: |
||||
|
||||
@@ -161,7 +162,7 @@ typedef enum { |
||||
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, |
||||
oAddressFamily, oGssAuthentication, oGssDelegateCreds, |
||||
oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, |
||||
- oGssServerIdentity, |
||||
+ oGssServerIdentity, oGssKexAlgorithms, |
||||
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, |
||||
oSendEnv, oControlPath, oControlMaster, oControlPersist, |
||||
oHashKnownHosts, |
||||
@@ -213,6 +214,7 @@ static struct { |
||||
{ "gssapiclientidentity", oGssClientIdentity }, |
||||
{ "gssapiserveridentity", oGssServerIdentity }, |
||||
{ "gssapirenewalforcesrekey", oGssRenewalRekey }, |
||||
+ { "gssapikexalgorithms", oGssKexAlgorithms }, |
||||
#else |
||||
{ "gssapiauthentication", oUnsupported }, |
||||
{ "gssapikeyexchange", oUnsupported }, |
||||
@@ -220,6 +222,7 @@ static struct { |
||||
{ "gssapitrustdns", oUnsupported }, |
||||
{ "gssapiclientidentity", oUnsupported }, |
||||
{ "gssapirenewalforcesrekey", oUnsupported }, |
||||
+ { "gssapikexalgorithms", oUnsupported }, |
||||
#endif |
||||
{ "fallbacktorsh", oDeprecated }, |
||||
{ "usersh", oDeprecated }, |
||||
@@ -996,6 +999,18 @@ parse_time: |
||||
intptr = &options->gss_renewal_rekey; |
||||
goto parse_flag; |
||||
|
||||
+ case oGssKexAlgorithms: |
||||
+ arg = strdelim(&s); |
||||
+ if (!arg || *arg == '\0') |
||||
+ fatal("%.200s line %d: Missing argument.", |
||||
+ filename, linenum); |
||||
+ if (!gss_kex_names_valid(arg)) |
||||
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", |
||||
+ filename, linenum, arg ? arg : "<NONE>"); |
||||
+ if (*activep && options->gss_kex_algorithms == NULL) |
||||
+ options->gss_kex_algorithms = strdup(arg); |
||||
+ break; |
||||
+ |
||||
case oBatchMode: |
||||
intptr = &options->batch_mode; |
||||
goto parse_flag; |
||||
@@ -1813,6 +1828,7 @@ initialize_options(Options * options) |
||||
options->gss_renewal_rekey = -1; |
||||
options->gss_client_identity = NULL; |
||||
options->gss_server_identity = NULL; |
||||
+ options->gss_kex_algorithms = NULL; |
||||
options->password_authentication = -1; |
||||
options->kbd_interactive_authentication = -1; |
||||
options->kbd_interactive_devices = NULL; |
||||
@@ -1964,6 +1980,10 @@ fill_default_options(Options * options) |
||||
options->gss_trust_dns = 0; |
||||
if (options->gss_renewal_rekey == -1) |
||||
options->gss_renewal_rekey = 0; |
||||
+#ifdef GSSAPI |
||||
+ if (options->gss_kex_algorithms == NULL) |
||||
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); |
||||
+#endif |
||||
if (options->password_authentication == -1) |
||||
options->password_authentication = 1; |
||||
if (options->kbd_interactive_authentication == -1) |
||||
diff -up openssh-7.4p1/readconf.h.gsskexalg openssh-7.4p1/readconf.h |
||||
--- openssh-7.4p1/readconf.h.gsskexalg 2017-02-09 10:46:50.420893129 +0100 |
||||
+++ openssh-7.4p1/readconf.h 2017-02-09 10:46:50.450893106 +0100 |
||||
@@ -51,6 +51,7 @@ typedef struct { |
||||
int gss_renewal_rekey; /* Credential renewal forces rekey */ |
||||
char *gss_client_identity; /* Principal to initiate GSSAPI with */ |
||||
char *gss_server_identity; /* GSSAPI target principal */ |
||||
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ |
||||
int password_authentication; /* Try password |
||||
* authentication. */ |
||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ |
||||
diff -up openssh-7.4p1/servconf.c.gsskexalg openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.gsskexalg 2017-02-09 10:46:50.446893109 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-09 10:57:15.784309297 +0100 |
||||
@@ -57,6 +57,7 @@ |
||||
#include "auth.h" |
||||
#include "myproposal.h" |
||||
#include "digest.h" |
||||
+#include "ssh-gss.h" |
||||
|
||||
static void add_listen_addr(ServerOptions *, char *, int); |
||||
static void add_one_listen_addr(ServerOptions *, char *, int); |
||||
@@ -117,6 +117,7 @@ initialize_server_options(ServerOptions |
||||
options->gss_cleanup_creds = -1; |
||||
options->gss_strict_acceptor = -1; |
||||
options->gss_store_rekey = -1; |
||||
+ options->gss_kex_algorithms = NULL; |
||||
options->password_authentication = -1; |
||||
options->kbd_interactive_authentication = -1; |
||||
options->challenge_response_authentication = -1; |
||||
@@ -280,6 +281,10 @@ fill_default_server_options(ServerOption |
||||
options->gss_strict_acceptor = 1; |
||||
if (options->gss_store_rekey == -1) |
||||
options->gss_store_rekey = 0; |
||||
+#ifdef GSSAPI |
||||
+ if (options->gss_kex_algorithms == NULL) |
||||
+ options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); |
||||
+#endif |
||||
if (options->password_authentication == -1) |
||||
options->password_authentication = 1; |
||||
if (options->kbd_interactive_authentication == -1) |
||||
@@ -422,7 +425,7 @@ typedef enum { |
||||
sHostKeyAlgorithms, |
||||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |
||||
sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor, |
||||
- sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel, |
||||
+ sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel, |
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
||||
sUsePrivilegeSeparation, sAllowAgentForwarding, |
||||
sHostCertificate, |
||||
@@ -501,6 +504,7 @@ static struct { |
||||
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, |
||||
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, |
||||
{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL }, |
||||
+ { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, |
||||
#else |
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL }, |
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, |
||||
@@ -508,6 +512,7 @@ static struct { |
||||
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapienablek5users", sUnsupported, SSHCFG_ALL }, |
||||
+ { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, |
||||
#endif |
||||
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, |
||||
@@ -1249,6 +1254,18 @@ process_server_config_line(ServerOptions |
||||
intptr = &options->gss_store_rekey; |
||||
goto parse_flag; |
||||
|
||||
+ case sGssKexAlgorithms: |
||||
+ arg = strdelim(&cp); |
||||
+ if (!arg || *arg == '\0') |
||||
+ fatal("%.200s line %d: Missing argument.", |
||||
+ filename, linenum); |
||||
+ if (!gss_kex_names_valid(arg)) |
||||
+ fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", |
||||
+ filename, linenum, arg ? arg : "<NONE>"); |
||||
+ if (*activep && options->gss_kex_algorithms == NULL) |
||||
+ options->gss_kex_algorithms = strdup(arg); |
||||
+ break; |
||||
+ |
||||
case sPasswordAuthentication: |
||||
intptr = &options->password_authentication; |
||||
goto parse_flag; |
||||
@@ -2304,6 +2321,7 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); |
||||
dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); |
||||
dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); |
||||
+ dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); |
||||
#endif |
||||
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); |
||||
dump_cfg_fmtint(sKbdInteractiveAuthentication, |
||||
diff -up openssh-7.4p1/servconf.h.gsskexalg openssh-7.4p1/servconf.h |
||||
--- openssh-7.4p1/servconf.h.gsskexalg 2017-02-09 10:46:50.450893106 +0100 |
||||
+++ openssh-7.4p1/servconf.h 2017-02-09 10:57:33.717292870 +0100 |
||||
@@ -116,6 +116,7 @@ typedef struct { |
||||
int gss_cleanup_creds; /* If true, destroy cred cache on logout */ |
||||
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ |
||||
int gss_store_rekey; |
||||
+ char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ |
||||
int password_authentication; /* If true, permit password |
||||
* authentication. */ |
||||
int kbd_interactive_authentication; /* If true, permit */ |
||||
diff -up openssh-7.4p1/ssh.1.gsskexalg openssh-7.4p1/ssh.1 |
||||
--- openssh-7.4p1/ssh.1.gsskexalg 2017-02-09 10:46:50.443893111 +0100 |
||||
+++ openssh-7.4p1/ssh.1 2017-02-09 10:46:50.451893105 +0100 |
||||
@@ -517,6 +517,7 @@ For full details of the options listed b |
||||
.It GSSAPIDelegateCredentials |
||||
.It GSSAPIRenewalForcesRekey |
||||
.It GSSAPITrustDns |
||||
+.It GSSAPIKexAlgorithms |
||||
.It HashKnownHosts |
||||
.It Host |
||||
.It HostbasedAuthentication |
||||
diff -up openssh-7.4p1/ssh_config.5.gsskexalg openssh-7.4p1/ssh_config.5 |
||||
--- openssh-7.4p1/ssh_config.5.gsskexalg 2017-02-09 10:46:50.452893104 +0100 |
||||
+++ openssh-7.4p1/ssh_config.5 2017-02-09 11:00:39.053122745 +0100 |
||||
@@ -782,6 +782,18 @@ the name of the host being connected to. |
||||
command line will be passed untouched to the GSSAPI library. |
||||
The default is |
||||
.Dq no . |
||||
+.It Cm GSSAPIKexAlgorithms |
||||
+The list of key exchange algorithms that are offered for GSSAPI |
||||
+key exchange. Possible values are |
||||
+.Bd -literal -offset 3n |
||||
+gss-gex-sha1-, |
||||
+gss-group1-sha1-, |
||||
+gss-group14-sha1- |
||||
+.Ed |
||||
+.Pp |
||||
+The default is |
||||
+.Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- . |
||||
+This option only applies to protocol version 2 connections using GSSAPI. |
||||
.It Cm HashKnownHosts |
||||
Indicates that |
||||
.Xr ssh 1 |
||||
diff -up openssh-7.4p1/sshconnect2.c.gsskexalg openssh-7.4p1/sshconnect2.c |
||||
--- openssh-7.4p1/sshconnect2.c.gsskexalg 2017-02-09 10:46:50.451893105 +0100 |
||||
+++ openssh-7.4p1/sshconnect2.c 2017-02-09 10:58:08.533260973 +0100 |
||||
@@ -181,7 +181,8 @@ ssh_kex2(char *host, struct sockaddr *ho |
||||
else |
||||
gss_host = host; |
||||
|
||||
- gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity); |
||||
+ gss = ssh_gssapi_client_mechanisms(gss_host, |
||||
+ options.gss_client_identity, options.gss_kex_algorithms); |
||||
if (gss) { |
||||
debug("Offering GSSAPI proposal: %s", gss); |
||||
xasprintf(&options.kex_algorithms, |
||||
diff -up openssh-7.4p1/sshd_config.5.gsskexalg openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.gsskexalg 2017-02-09 10:46:50.452893104 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2017-02-09 11:01:55.141050861 +0100 |
||||
@@ -666,6 +666,18 @@ Controls whether the user's GSSAPI crede |
||||
successful connection rekeying. This option can be used to accepted renewed |
||||
or updated credentials from a compatible client. The default is |
||||
.Dq no . |
||||
+.It Cm GSSAPIKexAlgorithms |
||||
+The list of key exchange algorithms that are accepted by GSSAPI |
||||
+key exchange. Possible values are |
||||
+.Bd -literal -offset 3n |
||||
+gss-gex-sha1-, |
||||
+gss-group1-sha1-, |
||||
+gss-group14-sha1- |
||||
+.Ed |
||||
+.Pp |
||||
+The default is |
||||
+.Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- . |
||||
+This option only applies to protocol version 2 connections using GSSAPI. |
||||
.It Cm HostbasedAcceptedKeyTypes |
||||
Specifies the key types that will be accepted for hostbased authentication |
||||
as a comma-separated pattern list. |
||||
diff -up openssh-7.4p1/ssh-gss.h.gsskexalg openssh-7.4p1/ssh-gss.h |
||||
--- openssh-7.4p1/ssh-gss.h.gsskexalg 2017-02-09 10:46:50.425893125 +0100 |
||||
+++ openssh-7.4p1/ssh-gss.h 2017-02-09 10:46:50.451893105 +0100 |
||||
@@ -76,6 +76,11 @@ extern char **k5users_allowed_cmds; |
||||
#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" |
||||
#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" |
||||
|
||||
+#define GSS_KEX_DEFAULT_KEX \ |
||||
+ KEX_GSS_GEX_SHA1_ID "," \ |
||||
+ KEX_GSS_GRP1_SHA1_ID "," \ |
||||
+ KEX_GSS_GRP14_SHA1_ID |
||||
+ |
||||
typedef struct { |
||||
char *filename; |
||||
char *envvar; |
||||
@@ -147,9 +152,9 @@ int ssh_gssapi_credentials_updated(Gssct |
||||
/* In the server */ |
||||
typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, |
||||
const char *); |
||||
-char *ssh_gssapi_client_mechanisms(const char *, const char *); |
||||
+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); |
||||
char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, |
||||
- const char *); |
||||
+ const char *, const char *); |
||||
gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); |
||||
int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, |
||||
const char *); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,611 @@
@@ -0,0 +1,611 @@
|
||||
diff -up openssh-6.8p1/Makefile.in.kdf-cavs openssh-6.8p1/Makefile.in |
||||
--- openssh-6.8p1/Makefile.in.kdf-cavs 2015-03-18 11:23:46.346049359 +0100 |
||||
+++ openssh-6.8p1/Makefile.in 2015-03-18 11:24:20.395968445 +0100 |
||||
@@ -29,6 +29,7 @@ SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-h |
||||
SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper |
||||
SSH_KEYCAT=$(libexecdir)/ssh-keycat |
||||
CTR_CAVSTEST=$(libexecdir)/ctr-cavstest |
||||
+SSH_CAVS=$(libexecdir)/ssh-cavs |
||||
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper |
||||
PRIVSEP_PATH=@PRIVSEP_PATH@ |
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ |
||||
@@ -67,7 +68,7 @@ EXEEXT=@EXEEXT@ |
||||
MANFMT=@MANFMT@ |
||||
INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@ |
||||
|
||||
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) |
||||
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT) ctr-cavstest$(EXEEXT) ssh-cavs$(EXEEXT) |
||||
|
||||
LIBOPENSSH_OBJS=\ |
||||
ssh_api.o \ |
||||
@@ -198,6 +199,9 @@ ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHD |
||||
ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o |
||||
$(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) |
||||
|
||||
+ssh-cavs$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-cavs.o |
||||
+ $(LD) -o $@ ssh-cavs.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) |
||||
+ |
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o |
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) |
||||
|
||||
@@ -331,6 +335,8 @@ install-files: |
||||
fi |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT) |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ctr-cavstest$(EXEEXT) $(DESTDIR)$(libexecdir)/ctr-cavstest$(EXEEXT) |
||||
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-cavs$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-cavs$(EXEEXT) |
||||
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-cavs_driver.pl $(DESTDIR)$(libexecdir)/ssh-cavs_driver.pl |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) |
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) |
||||
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 |
||||
diff -up openssh-6.8p1/ssh-cavs.c.kdf-cavs openssh-6.8p1/ssh-cavs.c |
||||
--- openssh-6.8p1/ssh-cavs.c.kdf-cavs 2015-03-18 11:23:46.348049354 +0100 |
||||
+++ openssh-6.8p1/ssh-cavs.c 2015-03-18 11:23:46.348049354 +0100 |
||||
@@ -0,0 +1,380 @@ |
||||
+/* |
||||
+ * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de> |
||||
+ * |
||||
+ * 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, and the entire permission notice in its entirety, |
||||
+ * including the disclaimer of warranties. |
||||
+ * 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. |
||||
+ * 3. The name of the author may not be used to endorse or promote |
||||
+ * products derived from this software without specific prior |
||||
+ * written permission. |
||||
+ * |
||||
+ * ALTERNATIVELY, this product may be distributed under the terms of |
||||
+ * the GNU General Public License, in which case the provisions of the GPL2 |
||||
+ * are required INSTEAD OF the above restrictions. (This clause is |
||||
+ * necessary due to a potential bad interaction between the GPL and |
||||
+ * the restrictions contained in a BSD-style copyright.) |
||||
+ * |
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
||||
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF |
||||
+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH |
||||
+ * DAMAGE. |
||||
+ */ |
||||
+ |
||||
+#include "includes.h" |
||||
+ |
||||
+#include <stdio.h> |
||||
+#include <stdlib.h> |
||||
+#include <errno.h> |
||||
+#include <sys/types.h> |
||||
+#include <string.h> |
||||
+ |
||||
+#include <openssl/bn.h> |
||||
+ |
||||
+#include "xmalloc.h" |
||||
+#include "buffer.h" |
||||
+#include "key.h" |
||||
+#include "cipher.h" |
||||
+#include "kex.h" |
||||
+#include "packet.h" |
||||
+ |
||||
+static int bin_char(unsigned char hex) |
||||
+{ |
||||
+ if (48 <= hex && 57 >= hex) |
||||
+ return (hex - 48); |
||||
+ if (65 <= hex && 70 >= hex) |
||||
+ return (hex - 55); |
||||
+ if (97 <= hex && 102 >= hex) |
||||
+ return (hex - 87); |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+/* |
||||
+ * Convert hex representation into binary string |
||||
+ * @hex input buffer with hex representation |
||||
+ * @hexlen length of hex |
||||
+ * @bin output buffer with binary data |
||||
+ * @binlen length of already allocated bin buffer (should be at least |
||||
+ * half of hexlen -- if not, only a fraction of hexlen is converted) |
||||
+ */ |
||||
+static void hex2bin(const char *hex, size_t hexlen, |
||||
+ unsigned char *bin, size_t binlen) |
||||
+{ |
||||
+ size_t i = 0; |
||||
+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen; |
||||
+ |
||||
+ for (i = 0; i < chars; i++) { |
||||
+ bin[i] = bin_char(hex[(i*2)]) << 4; |
||||
+ bin[i] |= bin_char(hex[((i*2)+1)]); |
||||
+ } |
||||
+} |
||||
+ |
||||
+/* |
||||
+ * Allocate sufficient space for binary representation of hex |
||||
+ * and convert hex into bin |
||||
+ * |
||||
+ * Caller must free bin |
||||
+ * @hex input buffer with hex representation |
||||
+ * @hexlen length of hex |
||||
+ * @bin return value holding the pointer to the newly allocated buffer |
||||
+ * @binlen return value holding the allocated size of bin |
||||
+ * |
||||
+ * return: 0 on success, !0 otherwise |
||||
+ */ |
||||
+static int hex2bin_alloc(const char *hex, size_t hexlen, |
||||
+ unsigned char **bin, size_t *binlen) |
||||
+{ |
||||
+ unsigned char *out = NULL; |
||||
+ size_t outlen = 0; |
||||
+ |
||||
+ if (!hexlen) |
||||
+ return -EINVAL; |
||||
+ |
||||
+ outlen = (hexlen + 1) / 2; |
||||
+ |
||||
+ out = calloc(1, outlen); |
||||
+ if (!out) |
||||
+ return -errno; |
||||
+ |
||||
+ hex2bin(hex, hexlen, out, outlen); |
||||
+ *bin = out; |
||||
+ *binlen = outlen; |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+static char hex_char_map_l[] = { '0', '1', '2', '3', '4', '5', '6', '7', |
||||
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; |
||||
+static char hex_char_map_u[] = { '0', '1', '2', '3', '4', '5', '6', '7', |
||||
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; |
||||
+static char hex_char(unsigned int bin, int u) |
||||
+{ |
||||
+ if (bin < sizeof(hex_char_map_l)) |
||||
+ return (u) ? hex_char_map_u[bin] : hex_char_map_l[bin]; |
||||
+ return 'X'; |
||||
+} |
||||
+ |
||||
+/* |
||||
+ * Convert binary string into hex representation |
||||
+ * @bin input buffer with binary data |
||||
+ * @binlen length of bin |
||||
+ * @hex output buffer to store hex data |
||||
+ * @hexlen length of already allocated hex buffer (should be at least |
||||
+ * twice binlen -- if not, only a fraction of binlen is converted) |
||||
+ * @u case of hex characters (0=>lower case, 1=>upper case) |
||||
+ */ |
||||
+static void bin2hex(const unsigned char *bin, size_t binlen, |
||||
+ char *hex, size_t hexlen, int u) |
||||
+{ |
||||
+ size_t i = 0; |
||||
+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen; |
||||
+ |
||||
+ for (i = 0; i < chars; i++) { |
||||
+ hex[(i*2)] = hex_char((bin[i] >> 4), u); |
||||
+ hex[((i*2)+1)] = hex_char((bin[i] & 0x0f), u); |
||||
+ } |
||||
+} |
||||
+ |
||||
+struct kdf_cavs { |
||||
+ unsigned char *K; |
||||
+ size_t Klen; |
||||
+ unsigned char *H; |
||||
+ size_t Hlen; |
||||
+ unsigned char *session_id; |
||||
+ size_t session_id_len; |
||||
+ |
||||
+ unsigned int iv_len; |
||||
+ unsigned int ek_len; |
||||
+ unsigned int ik_len; |
||||
+}; |
||||
+ |
||||
+static int sshkdf_cavs(struct kdf_cavs *test) |
||||
+{ |
||||
+ int ret = 0; |
||||
+ struct kex kex; |
||||
+ BIGNUM *Kbn = NULL; |
||||
+ int mode = 0; |
||||
+ struct newkeys *ctoskeys; |
||||
+ struct newkeys *stockeys; |
||||
+ struct ssh *ssh = NULL; |
||||
+ |
||||
+#define HEXOUTLEN 500 |
||||
+ char hex[HEXOUTLEN]; |
||||
+ |
||||
+ memset(&kex, 0, sizeof(struct kex)); |
||||
+ |
||||
+ Kbn = BN_new(); |
||||
+ BN_bin2bn(test->K, test->Klen, Kbn); |
||||
+ if (!Kbn) { |
||||
+ printf("cannot convert K into BIGNUM\n"); |
||||
+ ret = 1; |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ kex.session_id = test->session_id; |
||||
+ kex.session_id_len = test->session_id_len; |
||||
+ |
||||
+ /* setup kex */ |
||||
+ |
||||
+ /* select the right hash based on struct ssh_digest digests */ |
||||
+ switch (test->ik_len) { |
||||
+ case 20: |
||||
+ kex.hash_alg = 2; |
||||
+ break; |
||||
+ case 32: |
||||
+ kex.hash_alg = 3; |
||||
+ break; |
||||
+ case 48: |
||||
+ kex.hash_alg = 4; |
||||
+ break; |
||||
+ case 64: |
||||
+ kex.hash_alg = 5; |
||||
+ break; |
||||
+ default: |
||||
+ printf("Wrong hash type %u\n", test->ik_len); |
||||
+ ret = 1; |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ /* implement choose_enc */ |
||||
+ for (mode = 0; mode < 2; mode++) { |
||||
+ kex.newkeys[mode] = calloc(1, sizeof(struct newkeys)); |
||||
+ if (!kex.newkeys[mode]) { |
||||
+ printf("allocation of newkeys failed\n"); |
||||
+ ret = 1; |
||||
+ goto out; |
||||
+ } |
||||
+ kex.newkeys[mode]->enc.iv_len = test->iv_len; |
||||
+ kex.newkeys[mode]->enc.key_len = test->ek_len; |
||||
+ kex.newkeys[mode]->enc.block_size = (test->iv_len == 64) ? 8 : 16; |
||||
+ kex.newkeys[mode]->mac.key_len = test->ik_len; |
||||
+ } |
||||
+ |
||||
+ /* implement kex_choose_conf */ |
||||
+ kex.we_need = kex.newkeys[0]->enc.key_len; |
||||
+ if (kex.we_need < kex.newkeys[0]->enc.block_size) |
||||
+ kex.we_need = kex.newkeys[0]->enc.block_size; |
||||
+ if (kex.we_need < kex.newkeys[0]->enc.iv_len) |
||||
+ kex.we_need = kex.newkeys[0]->enc.iv_len; |
||||
+ if (kex.we_need < kex.newkeys[0]->mac.key_len) |
||||
+ kex.we_need = kex.newkeys[0]->mac.key_len; |
||||
+ |
||||
+ /* MODE_OUT (1) -> server to client |
||||
+ * MODE_IN (0) -> client to server */ |
||||
+ kex.server = 1; |
||||
+ |
||||
+ /* do it */ |
||||
+ if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL){ |
||||
+ printf("Allocation error\n"); |
||||
+ goto out; |
||||
+ } |
||||
+ ssh->kex = &kex; |
||||
+ kex_derive_keys_bn(ssh, test->H, test->Hlen, Kbn); |
||||
+ |
||||
+ ctoskeys = kex.newkeys[0]; |
||||
+ stockeys = kex.newkeys[1]; |
||||
+ |
||||
+ /* get data */ |
||||
+ memset(hex, 0, HEXOUTLEN); |
||||
+ bin2hex(ctoskeys->enc.iv, (size_t)ctoskeys->enc.iv_len, |
||||
+ hex, HEXOUTLEN, 0); |
||||
+ printf("Initial IV (client to server) = %s\n", hex); |
||||
+ memset(hex, 0, HEXOUTLEN); |
||||
+ bin2hex(stockeys->enc.iv, (size_t)stockeys->enc.iv_len, |
||||
+ hex, HEXOUTLEN, 0); |
||||
+ printf("Initial IV (server to client) = %s\n", hex); |
||||
+ |
||||
+ memset(hex, 0, HEXOUTLEN); |
||||
+ bin2hex(ctoskeys->enc.key, (size_t)ctoskeys->enc.key_len, |
||||
+ hex, HEXOUTLEN, 0); |
||||
+ printf("Encryption key (client to server) = %s\n", hex); |
||||
+ memset(hex, 0, HEXOUTLEN); |
||||
+ bin2hex(stockeys->enc.key, (size_t)stockeys->enc.key_len, |
||||
+ hex, HEXOUTLEN, 0); |
||||
+ printf("Encryption key (server to client) = %s\n", hex); |
||||
+ |
||||
+ memset(hex, 0, HEXOUTLEN); |
||||
+ bin2hex(ctoskeys->mac.key, (size_t)ctoskeys->mac.key_len, |
||||
+ hex, HEXOUTLEN, 0); |
||||
+ printf("Integrity key (client to server) = %s\n", hex); |
||||
+ memset(hex, 0, HEXOUTLEN); |
||||
+ bin2hex(stockeys->mac.key, (size_t)stockeys->mac.key_len, |
||||
+ hex, HEXOUTLEN, 0); |
||||
+ printf("Integrity key (server to client) = %s\n", hex); |
||||
+ |
||||
+out: |
||||
+ if (Kbn) |
||||
+ BN_free(Kbn); |
||||
+ if (kex.newkeys[0]) |
||||
+ free(kex.newkeys[0]); |
||||
+ if (kex.newkeys[1]) |
||||
+ free(kex.newkeys[1]); |
||||
+ if (ssh) |
||||
+ ssh_packet_close(ssh); |
||||
+ return ret; |
||||
+} |
||||
+ |
||||
+static void usage(void) |
||||
+{ |
||||
+ fprintf(stderr, "\nOpenSSH KDF CAVS Test\n\n"); |
||||
+ fprintf(stderr, "Usage:\n"); |
||||
+ fprintf(stderr, "\t-K\tShared secret string\n"); |
||||
+ fprintf(stderr, "\t-H\tHash string\n"); |
||||
+ fprintf(stderr, "\t-s\tSession ID string\n"); |
||||
+ fprintf(stderr, "\t-i\tIV length to be generated\n"); |
||||
+ fprintf(stderr, "\t-e\tEncryption key length to be generated\n"); |
||||
+ fprintf(stderr, "\t-m\tMAC key length to be generated\n"); |
||||
+} |
||||
+ |
||||
+/* |
||||
+ * Test command example: |
||||
+ * ./ssh-cavs -K 0055d50f2d163cc07cd8a93cc7c3430c30ce786b572c01ad29fec7597000cf8618d664e2ec3dcbc8bb7a1a7eb7ef67f61cdaf291625da879186ac0a5cb27af571b59612d6a6e0627344d846271959fda61c78354aa498773d59762f8ca2d0215ec590d8633de921f920d41e47b3de6ab9a3d0869e1c826d0e4adebf8e3fb646a15dea20a410b44e969f4b791ed6a67f13f1b74234004d5fa5e87eff7abc32d49bbdf44d7b0107e8f10609233b7e2b7eff74a4daf25641de7553975dac6ac1e5117df6f6dbaa1c263d23a6c3e5a3d7d49ae8a828c1e333ac3f85fbbf57b5c1a45be45e43a7be1a4707eac779b8285522d1f531fe23f890fd38a004339932b93eda4 -H d3ab91a850febb417a25d892ec48ed5952c7a5de -s d3ab91a850febb417a25d892ec48ed5952c7a5de -i 8 -e 24 -m 20 |
||||
+ * |
||||
+ * Initial IV (client to server) = 4bb320d1679dfd3a |
||||
+ * Initial IV (server to client) = 43dea6fdf263a308 |
||||
+ * Encryption key (client to server) = 13048cc600b9d3cf9095aa6cf8e2ff9cf1c54ca0520c89ed |
||||
+ * Encryption key (server to client) = 1e483c5134e901aa11fc4e0a524e7ec7b75556148a222bb0 |
||||
+ * Integrity key (client to server) = ecef63a092b0dcc585bdc757e01b2740af57d640 |
||||
+ * Integrity key (server to client) = 7424b05f3c44a72b4ebd281fb71f9cbe7b64d479 |
||||
+ */ |
||||
+int main(int argc, char *argv[]) |
||||
+{ |
||||
+ struct kdf_cavs test; |
||||
+ int ret = 1; |
||||
+ int opt = 0; |
||||
+ |
||||
+ memset(&test, 0, sizeof(struct kdf_cavs)); |
||||
+ while((opt = getopt(argc, argv, "K:H:s:i:e:m:")) != -1) |
||||
+ { |
||||
+ size_t len = 0; |
||||
+ switch(opt) |
||||
+ { |
||||
+ /* |
||||
+ * CAVS K is MPINT |
||||
+ * we want a hex (i.e. the caller must ensure the |
||||
+ * following transformations already happened): |
||||
+ * 1. cut off first four bytes |
||||
+ * 2. if most significant bit of value is |
||||
+ * 1, prepend 0 byte |
||||
+ */ |
||||
+ case 'K': |
||||
+ len = strlen(optarg); |
||||
+ ret = hex2bin_alloc(optarg, len, |
||||
+ &test.K, &test.Klen); |
||||
+ if (ret) |
||||
+ goto out; |
||||
+ break; |
||||
+ case 'H': |
||||
+ len = strlen(optarg); |
||||
+ ret = hex2bin_alloc(optarg, len, |
||||
+ &test.H, &test.Hlen); |
||||
+ if (ret) |
||||
+ goto out; |
||||
+ break; |
||||
+ case 's': |
||||
+ len = strlen(optarg); |
||||
+ ret = hex2bin_alloc(optarg, len, |
||||
+ &test.session_id, |
||||
+ &test.session_id_len); |
||||
+ if (ret) |
||||
+ goto out; |
||||
+ break; |
||||
+ case 'i': |
||||
+ test.iv_len = strtoul(optarg, NULL, 10); |
||||
+ break; |
||||
+ case 'e': |
||||
+ test.ek_len = strtoul(optarg, NULL, 10); |
||||
+ break; |
||||
+ case 'm': |
||||
+ test.ik_len = strtoul(optarg, NULL, 10); |
||||
+ break; |
||||
+ default: |
||||
+ usage(); |
||||
+ goto out; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ ret = sshkdf_cavs(&test); |
||||
+ |
||||
+out: |
||||
+ if (test.session_id) |
||||
+ free(test.session_id); |
||||
+ if (test.K) |
||||
+ free(test.K); |
||||
+ if (test.H) |
||||
+ free(test.H); |
||||
+ return ret; |
||||
+ |
||||
+} |
||||
diff -up openssh-6.8p1/ssh-cavs_driver.pl.kdf-cavs openssh-6.8p1/ssh-cavs_driver.pl |
||||
--- openssh-6.8p1/ssh-cavs_driver.pl.kdf-cavs 2015-03-18 11:23:46.348049354 +0100 |
||||
+++ openssh-6.8p1/ssh-cavs_driver.pl 2015-03-18 11:23:46.348049354 +0100 |
||||
@@ -0,0 +1,184 @@ |
||||
+#!/usr/bin/env perl |
||||
+# |
||||
+# CAVS test driver for OpenSSH |
||||
+# |
||||
+# Copyright (C) 2015, Stephan Mueller <smueller@chronox.de> |
||||
+# |
||||
+# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
+# of this software and associated documentation files (the "Software"), to deal |
||||
+# in the Software without restriction, including without limitation the rights |
||||
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
+# copies of the Software, and to permit persons to whom the Software is |
||||
+# furnished to do so, subject to the following conditions: |
||||
+# |
||||
+# The above copyright notice and this permission notice shall be included in |
||||
+# all copies or substantial portions of the Software. |
||||
+# |
||||
+# NO WARRANTY |
||||
+# |
||||
+# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
||||
+# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
||||
+# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
||||
+# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
||||
+# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
||||
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
||||
+# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
||||
+# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
||||
+# REPAIR OR CORRECTION. |
||||
+# |
||||
+# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
||||
+# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
||||
+# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
||||
+# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
||||
+# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
||||
+# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
||||
+# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
||||
+# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
||||
+# POSSIBILITY OF SUCH DAMAGES. |
||||
+# |
||||
+use strict; |
||||
+use warnings; |
||||
+use IPC::Open2; |
||||
+ |
||||
+# Executing a program by feeding STDIN and retrieving |
||||
+# STDOUT |
||||
+# $1: data string to be piped to the app on STDIN |
||||
+# rest: program and args |
||||
+# returns: STDOUT of program as string |
||||
+sub pipe_through_program($@) { |
||||
+ my $in = shift; |
||||
+ my @args = @_; |
||||
+ |
||||
+ my ($CO, $CI); |
||||
+ my $pid = open2($CO, $CI, @args); |
||||
+ |
||||
+ my $out = ""; |
||||
+ my $len = length($in); |
||||
+ my $first = 1; |
||||
+ while (1) { |
||||
+ my $rin = ""; |
||||
+ my $win = ""; |
||||
+ # Output of prog is FD that we read |
||||
+ vec($rin,fileno($CO),1) = 1; |
||||
+ # Input of prog is FD that we write |
||||
+ # check for $first is needed because we can have NULL input |
||||
+ # that is to be written to the app |
||||
+ if ( $len > 0 || $first) { |
||||
+ (vec($win,fileno($CI),1) = 1); |
||||
+ $first=0; |
||||
+ } |
||||
+ # Let us wait for 100ms |
||||
+ my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1); |
||||
+ if ( $wout ) { |
||||
+ my $written = syswrite($CI, $in, $len); |
||||
+ die "broken pipe" if !defined $written; |
||||
+ $len -= $written; |
||||
+ substr($in, 0, $written) = ""; |
||||
+ if ($len <= 0) { |
||||
+ close $CI or die "broken pipe: $!"; |
||||
+ } |
||||
+ } |
||||
+ if ( $rout ) { |
||||
+ my $tmp_out = ""; |
||||
+ my $bytes_read = sysread($CO, $tmp_out, 4096); |
||||
+ $out .= $tmp_out; |
||||
+ last if ($bytes_read == 0); |
||||
+ } |
||||
+ } |
||||
+ close $CO or die "broken pipe: $!"; |
||||
+ waitpid $pid, 0; |
||||
+ |
||||
+ return $out; |
||||
+} |
||||
+ |
||||
+# Parser of CAVS test vector file |
||||
+# $1: Test vector file |
||||
+# $2: Output file for test results |
||||
+# return: nothing |
||||
+sub parse($$) { |
||||
+ my $infile = shift; |
||||
+ my $outfile = shift; |
||||
+ |
||||
+ my $out = ""; |
||||
+ |
||||
+ my $K = ""; |
||||
+ my $H = ""; |
||||
+ my $session_id = ""; |
||||
+ my $ivlen = 0; |
||||
+ my $eklen = ""; |
||||
+ my $iklen = ""; |
||||
+ |
||||
+ open(IN, "<$infile"); |
||||
+ while(<IN>) { |
||||
+ |
||||
+ my $line = $_; |
||||
+ chomp($line); |
||||
+ $line =~ s/\r//; |
||||
+ |
||||
+ if ($line =~ /\[SHA-1\]/) { |
||||
+ $iklen = 20; |
||||
+ } elsif ($line =~ /\[SHA-256\]/) { |
||||
+ $iklen = 32; |
||||
+ } elsif ($line =~ /\[SHA-384\]/) { |
||||
+ $iklen = 48; |
||||
+ } elsif ($line =~ /\[SHA-512\]/) { |
||||
+ $iklen = 64; |
||||
+ } elsif ($line =~ /^\[IV length\s*=\s*(.*)\]/) { |
||||
+ $ivlen = $1; |
||||
+ $ivlen = $ivlen / 8; |
||||
+ } elsif ($line =~ /^\[encryption key length\s*=\s*(.*)\]/) { |
||||
+ $eklen = $1; |
||||
+ $eklen = $eklen / 8; |
||||
+ } elsif ($line =~ /^K\s*=\s*(.*)/) { |
||||
+ $K = $1; |
||||
+ $K = substr($K, 8); |
||||
+ $K = "00" . $K; |
||||
+ } elsif ($line =~ /^H\s*=\s*(.*)/) { |
||||
+ $H = $1; |
||||
+ } elsif ($line =~ /^session_id\s*=\s*(.*)/) { |
||||
+ $session_id = $1; |
||||
+ } |
||||
+ $out .= $line . "\n"; |
||||
+ |
||||
+ if ($K ne "" && $H ne "" && $session_id ne "" && |
||||
+ $ivlen ne "" && $eklen ne "" && $iklen > 0) { |
||||
+ $out .= pipe_through_program("", "./ssh-cavs -H $H -K $K -s $session_id -i $ivlen -e $eklen -m $iklen"); |
||||
+ |
||||
+ $K = ""; |
||||
+ $H = ""; |
||||
+ $session_id = ""; |
||||
+ } |
||||
+ } |
||||
+ close IN; |
||||
+ $out =~ s/\n/\r\n/g; # make it a dos file |
||||
+ open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?"; |
||||
+ print OUT $out; |
||||
+ close OUT; |
||||
+} |
||||
+ |
||||
+############################################################ |
||||
+# |
||||
+# let us pretend to be C :-) |
||||
+sub main() { |
||||
+ |
||||
+ my $infile=$ARGV[0]; |
||||
+ die "Error: Test vector file $infile not found" if (! -f $infile); |
||||
+ |
||||
+ my $outfile = $infile; |
||||
+ # let us add .rsp regardless whether we could strip .req |
||||
+ $outfile =~ s/\.req$//; |
||||
+ $outfile .= ".rsp"; |
||||
+ if (-f $outfile) { |
||||
+ die "Output file $outfile could not be removed: $?" |
||||
+ unless unlink($outfile); |
||||
+ } |
||||
+ print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n"; |
||||
+ |
||||
+ # Do the job |
||||
+ parse($infile, $outfile); |
||||
+} |
||||
+ |
||||
+########################################### |
||||
+# Call it |
||||
+main(); |
||||
+1; |
@ -0,0 +1,288 @@
@@ -0,0 +1,288 @@
|
||||
diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c |
||||
--- openssh-7.4p1/auth-krb5.c.kuserok 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/auth-krb5.c 2017-02-09 09:20:00.958084311 +0100 |
||||
@@ -54,6 +54,21 @@ |
||||
|
||||
extern ServerOptions options; |
||||
|
||||
+int |
||||
+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client, |
||||
+ int k5login_exists) |
||||
+{ |
||||
+ if (options.use_kuserok || !k5login_exists) |
||||
+ return krb5_kuserok(krb5_ctx, krb5_user, client); |
||||
+ else { |
||||
+ char kuser[65]; |
||||
+ |
||||
+ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) |
||||
+ return 0; |
||||
+ return strcmp(kuser, client) == 0; |
||||
+ } |
||||
+} |
||||
+ |
||||
static int |
||||
krb5_init(void *context) |
||||
{ |
||||
@@ -157,8 +172,9 @@ auth_krb5_password(Authctxt *authctxt, c |
||||
if (problem) |
||||
goto out; |
||||
|
||||
- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, |
||||
- authctxt->pw->pw_name)) { |
||||
+ /* Use !options.use_kuserok here to make ssh_krb5_kuserok() not |
||||
+ * depend on the existance of .k5login */ |
||||
+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name, !options.use_kuserok)) { |
||||
problem = -1; |
||||
goto out; |
||||
} |
||||
diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c |
||||
--- openssh-7.4p1/gss-serv-krb5.c.kuserok 2017-02-09 09:20:00.955084317 +0100 |
||||
+++ openssh-7.4p1/gss-serv-krb5.c 2017-02-09 09:20:00.958084311 +0100 |
||||
@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr |
||||
int); |
||||
|
||||
static krb5_context krb_context = NULL; |
||||
+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *, int); |
||||
|
||||
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */ |
||||
|
||||
@@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void) |
||||
* Returns true if the user is OK to log in, otherwise returns 0 |
||||
*/ |
||||
|
||||
+/* The purpose of the function is to find out if a Kerberos principal is |
||||
+ * allowed to log in as the given local user. This is a general problem with |
||||
+ * Kerberized services because by design the Kerberos principals are |
||||
+ * completely independent from the local user names. This is one of the |
||||
+ * reasons why Kerberos is working well on different operating systems like |
||||
+ * Windows and UNIX/Linux. Nevertheless a relationship between a Kerberos |
||||
+ * principal and a local user name must be established because otherwise every |
||||
+ * access would be granted for every principal with a valid ticket. |
||||
+ * |
||||
+ * Since it is a general issue libkrb5 provides some functions for |
||||
+ * applications to find out about the relationship between the Kerberos |
||||
+ * principal and a local user name. They are krb5_kuserok() and |
||||
+ * krb5_aname_to_localname(). |
||||
+ * |
||||
+ * krb5_kuserok() can be used to "Determine if a principal is authorized to |
||||
+ * log in as a local user" (from the MIT Kerberos documentation of this |
||||
+ * function). Which is exactly what we are looking for and should be the |
||||
+ * preferred choice. It accepts the Kerberos principal and a local user name |
||||
+ * and let libkrb5 or its plugins determine if they relate to each other or |
||||
+ * not. |
||||
+ * |
||||
+ * krb5_aname_to_localname() can use used to "Convert a principal name to a |
||||
+ * local name" (from the MIT Kerberos documentation of this function). It |
||||
+ * accepts a Kerberos principle and returns a local name and it is up to the |
||||
+ * application to do any additional checks. There are two issues using |
||||
+ * krb5_aname_to_localname(). First, since POSIX user names are case |
||||
+ * sensitive, the calling application in general has no other choice than |
||||
+ * doing a case-sensitive string comparison between the name returned by |
||||
+ * krb5_aname_to_localname() and the name used at the login prompt. When the |
||||
+ * users are provided by a case in-sensitive server, e.g. Active Directory, |
||||
+ * this might lead to login failures because the user typing the name at the |
||||
+ * login prompt might not be aware of the right case. Another issue might be |
||||
+ * caused if there are multiple alias names available for a single user. E.g. |
||||
+ * the canonical name of a user is user@group.department.example.com but there |
||||
+ * exists a shorter login name, e.g. user@example.com, to safe typing at the |
||||
+ * login prompt. Here krb5_aname_to_localname() can only return the canonical |
||||
+ * name, but if the short alias is used at the login prompt authentication |
||||
+ * will fail as well. All this can be avoided by using krb5_kuserok() and |
||||
+ * configuring krb5.conf or using a suitable plugin to meet the needs of the |
||||
+ * given environment. |
||||
+ * |
||||
+ * The Fedora and RHEL version of openssh contain two patches which modify the |
||||
+ * access control behavior: |
||||
+ * - openssh-6.6p1-kuserok.patch |
||||
+ * - openssh-6.6p1-force_krb.patch |
||||
+ * |
||||
+ * openssh-6.6p1-kuserok.patch adds a new option KerberosUseKuserok for |
||||
+ * sshd_config which controls if krb5_kuserok() is used to check if the |
||||
+ * principle is authorized or if krb5_aname_to_localname() should be used. |
||||
+ * The reason to add this patch was that krb5_kuserok() by default checks if |
||||
+ * a .k5login file exits in the users home-directory. With this the user can |
||||
+ * give access to his account for any given principal which might be |
||||
+ * in violation with company policies and it would be useful if this can be |
||||
+ * rejected. Nevertheless the patch ignores the fact that krb5_kuserok() does |
||||
+ * no only check .k5login but other sources as well and checking .k5login can |
||||
+ * be disabled for all applications in krb5.conf as well. With this new |
||||
+ * option KerberosUseKuserok set to 'no' (and this is the default for RHEL7 |
||||
+ * and Fedora 21) openssh can only use krb5_aname_to_localname() with the |
||||
+ * restrictions mentioned above. |
||||
+ * |
||||
+ * openssh-6.6p1-force_krb.patch adds a ksu like behaviour to ssh, i.e. when |
||||
+ * using GSSAPI authentication only commands configured in the .k5user can be |
||||
+ * executed. Here the wrong assumption that krb5_kuserok() only checks |
||||
+ * .k5login is made as well. In contrast ksu checks .k5login directly and |
||||
+ * does not use krb5_kuserok() which might be more useful for the given |
||||
+ * purpose. Additionally this patch is not synced with |
||||
+ * openssh-6.6p1-kuserok.patch. |
||||
+ * |
||||
+ * The current patch tries to restore the usage of krb5_kuserok() so that e.g. |
||||
+ * localauth plugins can be used. It does so by adding a forth parameter to |
||||
+ * ssh_krb5_kuserok() which indicates whether .k5login exists or not. If it |
||||
+ * does not exists krb5_kuserok() is called even if KerberosUseKuserok is set |
||||
+ * to 'no' because the intent of the option is to not check .k5login and if it |
||||
+ * does not exists krb5_kuserok() returns a result without checking .k5login. |
||||
+ * If .k5login does exists and KerberosUseKuserok is 'no' we fall back to |
||||
+ * krb5_aname_to_localname(). This is in my point of view an acceptable |
||||
+ * limitation and does not break the current behaviour. |
||||
+ * |
||||
+ * Additionally with this patch ssh_krb5_kuserok() is called in |
||||
+ * ssh_gssapi_krb5_cmdok() instead of only krb5_aname_to_localname() is |
||||
+ * neither .k5login nor .k5users exists to allow plugin evaluation via |
||||
+ * krb5_kuserok() as well. |
||||
+ * |
||||
+ * I tried to keep the patch as minimal as possible, nevertheless I see some |
||||
+ * areas for improvement which, if they make sense, have to be evaluated |
||||
+ * carefully because they might change existing behaviour and cause breaks |
||||
+ * during upgrade: |
||||
+ * - I wonder if disabling .k5login usage make sense in sshd or if it should |
||||
+ * be better disabled globally in krb5.conf |
||||
+ * - if really needed openssh-6.6p1-kuserok.patch should be fixed to really |
||||
+ * only disable checking .k5login and maybe .k5users |
||||
+ * - the ksu behaviour should be configurable and maybe check the .k5login and |
||||
+ * .k5users files directly like ksu itself does |
||||
+ * - to make krb5_aname_to_localname() more useful an option for sshd to use |
||||
+ * the canonical name (the one returned by getpwnam()) instead of the name |
||||
+ * given at the login prompt might be useful */ |
||||
+ |
||||
static int |
||||
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) |
||||
{ |
||||
@@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client |
||||
/* NOTE: .k5login and .k5users must opened as root, not the user, |
||||
* because if they are on a krb5-protected filesystem, user credentials |
||||
* to access these files aren't available yet. */ |
||||
- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { |
||||
+ if (ssh_krb5_kuserok(krb_context, princ, name, k5login_exists) |
||||
+ && k5login_exists) { |
||||
retval = 1; |
||||
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", |
||||
name, (char *)client->displayname.value); |
||||
@@ -171,9 +270,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri |
||||
snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); |
||||
/* If both .k5login and .k5users DNE, self-login is ok. */ |
||||
if (!k5login_exists && (access(file, F_OK) == -1)) { |
||||
- return (krb5_aname_to_localname(krb_context, principal, |
||||
- sizeof(kuser), kuser) == 0) && |
||||
- (strcmp(kuser, luser) == 0); |
||||
+ return ssh_krb5_kuserok(krb_context, principal, luser, |
||||
+ k5login_exists); |
||||
} |
||||
if ((fp = fopen(file, "r")) == NULL) { |
||||
int saved_errno = errno; |
||||
diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.kuserok 2017-02-09 09:20:00.951084326 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-09 09:21:29.802896034 +0100 |
||||
@@ -165,6 +165,7 @@ initialize_server_options(ServerOptions |
||||
options->ip_qos_interactive = -1; |
||||
options->ip_qos_bulk = -1; |
||||
options->version_addendum = NULL; |
||||
+ options->use_kuserok = -1; |
||||
options->fingerprint_hash = -1; |
||||
options->disable_forwarding = -1; |
||||
} |
||||
@@ -334,6 +335,8 @@ fill_default_server_options(ServerOption |
||||
options->version_addendum = xstrdup(""); |
||||
if (options->show_patchlevel == -1) |
||||
options->show_patchlevel = 0; |
||||
+ if (options->use_kuserok == -1) |
||||
+ options->use_kuserok = 1; |
||||
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) |
||||
options->fwd_opts.streamlocal_bind_mask = 0177; |
||||
if (options->fwd_opts.streamlocal_bind_unlink == -1) |
||||
@@ -399,7 +402,7 @@ typedef enum { |
||||
sPermitRootLogin, sLogFacility, sLogLevel, |
||||
sRhostsRSAAuthentication, sRSAAuthentication, |
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, |
||||
- sKerberosGetAFSToken, |
||||
+ sKerberosGetAFSToken, sKerberosUseKuserok, |
||||
sKerberosTgtPassing, sChallengeResponseAuthentication, |
||||
sPasswordAuthentication, sKbdInteractiveAuthentication, |
||||
sListenAddress, sAddressFamily, |
||||
@@ -478,11 +481,13 @@ static struct { |
||||
#else |
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, |
||||
#endif |
||||
+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, |
||||
#else |
||||
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL }, |
||||
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, |
||||
+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, |
||||
#endif |
||||
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, |
||||
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, |
||||
@@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions |
||||
*activep = value; |
||||
break; |
||||
|
||||
+ case sKerberosUseKuserok: |
||||
+ intptr = &options->use_kuserok; |
||||
+ goto parse_flag; |
||||
+ |
||||
case sPermitOpen: |
||||
arg = strdelim(&cp); |
||||
if (!arg || *arg == '\0') |
||||
@@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d |
||||
M_CP_INTOPT(client_alive_interval); |
||||
M_CP_INTOPT(ip_qos_interactive); |
||||
M_CP_INTOPT(ip_qos_bulk); |
||||
+ M_CP_INTOPT(use_kuserok); |
||||
M_CP_INTOPT(rekey_limit); |
||||
M_CP_INTOPT(rekey_interval); |
||||
|
||||
@@ -2308,6 +2318,7 @@ dump_config(ServerOptions *o) |
||||
dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); |
||||
dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); |
||||
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); |
||||
+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); |
||||
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); |
||||
|
||||
/* string arguments */ |
||||
diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h |
||||
--- openssh-7.4p1/servconf.h.kuserok 2017-02-09 09:20:00.951084326 +0100 |
||||
+++ openssh-7.4p1/servconf.h 2017-02-09 09:20:00.959084309 +0100 |
||||
@@ -174,6 +174,7 @@ typedef struct { |
||||
|
||||
int num_permitted_opens; |
||||
|
||||
+ int use_kuserok; |
||||
char *chroot_directory; |
||||
char *revoked_keys_file; |
||||
char *trusted_user_ca_keys; |
||||
diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.kuserok 2017-02-09 09:20:00.959084309 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2017-02-09 09:22:33.517761012 +0100 |
||||
@@ -846,6 +846,10 @@ Specifies whether to automatically destr |
||||
file on logout. |
||||
The default is |
||||
.Cm yes . |
||||
+.It Cm KerberosUseKuserok |
||||
+Specifies whether to look at .k5login file for user's aliases. |
||||
+The default is |
||||
+.Cm yes . |
||||
.It Cm KexAlgorithms |
||||
Specifies the available KEX (Key Exchange) algorithms. |
||||
Multiple algorithms must be comma-separated. |
||||
@@ -1074,6 +1078,7 @@ Available keywords are |
||||
.Cm IPQoS , |
||||
.Cm KbdInteractiveAuthentication , |
||||
.Cm KerberosAuthentication , |
||||
+.Cm KerberosUseKuserok , |
||||
.Cm MaxAuthTries , |
||||
.Cm MaxSessions , |
||||
.Cm PasswordAuthentication , |
||||
diff -up openssh-7.4p1/sshd_config.kuserok openssh-7.4p1/sshd_config |
||||
--- openssh-7.4p1/sshd_config.kuserok 2017-02-09 09:20:00.953084322 +0100 |
||||
+++ openssh-7.4p1/sshd_config 2017-02-09 09:20:00.959084309 +0100 |
||||
@@ -73,6 +73,7 @@ ChallengeResponseAuthentication no |
||||
#KerberosOrLocalPasswd yes |
||||
#KerberosTicketCleanup yes |
||||
#KerberosGetAFSToken no |
||||
+#KerberosUseKuserok yes |
||||
|
||||
# GSSAPI options |
||||
GSSAPIAuthentication yes |
@ -0,0 +1,263 @@
@@ -0,0 +1,263 @@
|
||||
diff -up openssh-7.4p1/dh.h.legacy openssh-7.4p1/dh.h |
||||
--- openssh-7.4p1/dh.h.legacy 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/dh.h 2017-03-02 17:00:37.640695985 +0100 |
||||
@@ -50,7 +50,7 @@ u_int dh_estimate(int); |
||||
* Max value from RFC4419. |
||||
* Miniumum increased in light of DH precomputation attacks. |
||||
*/ |
||||
-#define DH_GRP_MIN 2048 |
||||
+#define DH_GRP_MIN 1024 |
||||
#define DH_GRP_MAX 8192 |
||||
|
||||
/* |
||||
diff -up openssh-7.4p1/moduli.legacy openssh-7.4p1/moduli |
||||
--- openssh-7.4p1/moduli.legacy 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/moduli 2017-03-02 17:00:37.642695983 +0100 |
||||
@@ -1,5 +1,83 @@ |
||||
# $OpenBSD: moduli,v 1.18 2016/08/11 01:42:11 dtucker Exp $ |
||||
# Time Type Tests Tries Size Generator Modulus |
||||
+20150520233853 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2AC62AF |
||||
+20150520233854 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2BCC50F |
||||
+20150520233854 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2C241F3 |
||||
+20150520233855 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2DDF347 |
||||
+20150520233856 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA2E3FDBB |
||||
+20150520233857 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3006603 |
||||
+20150520233858 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA31D9C37 |
||||
+20150520233859 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA333355B |
||||
+20150520233900 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3428B23 |
||||
+20150520233902 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA37C9A43 |
||||
+20150520233903 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA384B367 |
||||
+20150520233903 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3903453 |
||||
+20150520233904 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3946C77 |
||||
+20150520233904 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA39F6A9B |
||||
+20150520233904 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3A0E88B |
||||
+20150520233905 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3A37763 |
||||
+20150520233906 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BBDD57 |
||||
+20150520233906 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BDCDD7 |
||||
+20150520233906 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3BF5D73 |
||||
+20150520233907 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3C9BB83 |
||||
+20150520233908 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3E5ADCF |
||||
+20150520233909 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA3F82077 |
||||
+20150520233910 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA406944F |
||||
+20150520233910 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA40F7457 |
||||
+20150520233912 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA438733B |
||||
+20150520233913 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA44707FB |
||||
+20150520233914 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA4588A2B |
||||
+20150520233916 2 6 100 1023 2 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA48CC01B |
||||
+20150520233917 2 6 100 1023 5 DB662973FB21C0B7BF21AB46AFD3E2002AE70C92DE6B9AEAFECF7B0A96D7ACB024B7C29DB18E70CB945FA54C7773519BC7161648AFE4939058AC40ECDBBD3636F5BF45863117E955007C9D0F9333BB4EF62F7C9F6298AB79A309C734F3CF201C61EBC3926ADD4E80968A65D9F60535164ACE7A7BFEDC1022002BB2BBA4960077 |
||||
+20150522025931 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD18DA1F |
||||
+20150522025936 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD3763B3 |
||||
+20150522025942 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD702B8B |
||||
+20150522025943 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD77C283 |
||||
+20150522025947 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAD96C25B |
||||
+20150522025953 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADD9B3DB |
||||
+20150522025956 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADE84F07 |
||||
+20150522025957 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DADEC1DB3 |
||||
+20150522030001 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE0E297F |
||||
+20150522030004 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE2A1E23 |
||||
+20150522030005 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE2ADE53 |
||||
+20150522030008 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE47B9F7 |
||||
+20150522030009 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE4E1343 |
||||
+20150522030014 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE715CBB |
||||
+20150522030016 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE7BC9EF |
||||
+20150522030018 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE84579B |
||||
+20150522030019 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAE8A564B |
||||
+20150522030023 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAEAF7AD7 |
||||
+20150522030025 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAEB9DC53 |
||||
+20150522030027 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAECD976F |
||||
+20150522030034 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF07F063 |
||||
+20150522030034 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF08ACBB |
||||
+20150522030037 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF192C07 |
||||
+20150522030039 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF241333 |
||||
+20150522030040 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF255B3B |
||||
+20150522030044 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF3DEC37 |
||||
+20150522030048 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF60F05B |
||||
+20150522030049 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF6255DF |
||||
+20150522030055 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAF8EE01F |
||||
+20150522030059 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFAD237B |
||||
+20150522030104 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFD13587 |
||||
+20150522030105 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFD2BE6F |
||||
+20150522030108 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFECF32F |
||||
+20150522030112 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DAFFDEED7 |
||||
+20150522030115 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB01CAA63 |
||||
+20150522030116 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB01F3647 |
||||
+20150522030119 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB034B30F |
||||
+20150522030122 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB04822EF |
||||
+20150522030124 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0528867 |
||||
+20150522030131 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB08D3CAB |
||||
+20150522030136 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0B10C6F |
||||
+20150522030138 2 6 100 1535 5 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0C688A7 |
||||
+20150522030140 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0CCDF9B |
||||
+20150522030141 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0CFD81B |
||||
+20150522030145 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB0F59763 |
||||
+20150522030148 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB10339FB |
||||
+20150522030149 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB10E3ACB |
||||
+20150522030150 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB11127F3 |
||||
+20150522030159 2 6 100 1535 2 F4EE15F22E5F49997A027769656DF0240598C9470C7D67A7D7DA2777883C1C243A6F3D04E1CFA6A0350B165ECABE89A684C11ABB7E5B93B54FD6EAC85BBA9F23C6306E485BB9AC5515ABC739CE9B1A79F7DEF6D00B643856DB903E23E7F985EDCAFF867FE15498E7EF6A91057DE337A9AAEDE941C934E65243AC7888A33C78FB2490BBA2BA06F18ECC51DE9AA54BADD061CC5BE1EA060CC3217CA11E26772BD088898D2882CB49A9FF40168E49AE6A90EE1F61132E1B6E4E7F99797DB15B8BDB |
||||
20160301052556 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D19F4647 |
||||
20160301052601 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1A5C13B |
||||
20160301052612 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1B7A3EF |
||||
diff -up openssh-7.4p1/myproposal.h.legacy openssh-7.4p1/myproposal.h |
||||
--- openssh-7.4p1/myproposal.h.legacy 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/myproposal.h 2017-03-02 17:05:12.353352522 +0100 |
||||
@@ -96,34 +96,40 @@ |
||||
KEX_SHA2_METHODS |
||||
|
||||
#define KEX_SERVER_KEX KEX_COMMON_KEX \ |
||||
+ "diffie-hellman-group-exchange-sha1," \ |
||||
KEX_SHA2_GROUP14 \ |
||||
- "diffie-hellman-group14-sha1" \ |
||||
+ "diffie-hellman-group14-sha1," \ |
||||
+ "diffie-hellman-group1-sha1" |
||||
|
||||
#define KEX_CLIENT_KEX KEX_COMMON_KEX \ |
||||
"diffie-hellman-group-exchange-sha1," \ |
||||
KEX_SHA2_GROUP14 \ |
||||
- "diffie-hellman-group14-sha1" |
||||
+ "diffie-hellman-group14-sha1," \ |
||||
+ "diffie-hellman-group1-sha1" |
||||
|
||||
#define KEX_DEFAULT_PK_ALG \ |
||||
HOSTKEY_ECDSA_CERT_METHODS \ |
||||
"ssh-ed25519-cert-v01@openssh.com," \ |
||||
"ssh-rsa-cert-v01@openssh.com," \ |
||||
+ "ssh-dss-cert-v01@openssh.com," \ |
||||
HOSTKEY_ECDSA_METHODS \ |
||||
"ssh-ed25519," \ |
||||
"rsa-sha2-512," \ |
||||
"rsa-sha2-256," \ |
||||
- "ssh-rsa" |
||||
+ "ssh-rsa," \ |
||||
+ "ssh-dss" |
||||
|
||||
/* the actual algorithms */ |
||||
|
||||
-#define KEX_SERVER_ENCRYPT \ |
||||
+#define KEX_CLIENT_ENCRYPT \ |
||||
"chacha20-poly1305@openssh.com," \ |
||||
"aes128-ctr,aes192-ctr,aes256-ctr" \ |
||||
- AESGCM_CIPHER_MODES |
||||
- |
||||
-#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \ |
||||
+ AESGCM_CIPHER_MODES "," \ |
||||
"aes128-cbc,aes192-cbc,aes256-cbc" |
||||
|
||||
+#define KEX_SERVER_ENCRYPT KEX_CLIENT_ENCRYPT "," \ |
||||
+ "blowfish-cbc,cast128-cbc,3des-cbc" |
||||
+ |
||||
#define KEX_SERVER_MAC \ |
||||
"umac-64-etm@openssh.com," \ |
||||
"umac-128-etm@openssh.com," \ |
||||
diff -up openssh-7.4p1/ssh_config.5.legacy openssh-7.4p1/ssh_config.5 |
||||
--- openssh-7.4p1/ssh_config.5.legacy 2017-03-02 17:00:37.620696010 +0100 |
||||
+++ openssh-7.4p1/ssh_config.5 2017-03-02 17:00:37.642695983 +0100 |
||||
@@ -833,8 +833,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com |
||||
ecdsa-sha2-nistp521-cert-v01@openssh.com, |
||||
ssh-ed25519-cert-v01@openssh.com, |
||||
ssh-rsa-cert-v01@openssh.com, |
||||
+ssh-dss-cert-v01@openssh.com, |
||||
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, |
||||
-ssh-ed25519,ssh-rsa |
||||
+ssh-ed25519,ssh-rsa,ssh-dss |
||||
.Ed |
||||
.Pp |
||||
The |
||||
@@ -856,8 +857,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com |
||||
ecdsa-sha2-nistp521-cert-v01@openssh.com, |
||||
ssh-ed25519-cert-v01@openssh.com, |
||||
ssh-rsa-cert-v01@openssh.com, |
||||
+ssh-dss-cert-v01@openssh.com, |
||||
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, |
||||
-ssh-ed25519,ssh-rsa |
||||
+ssh-ed25519,ssh-rsa,ssh-dss |
||||
.Ed |
||||
.Pp |
||||
If hostkeys are known for the destination host then this default is modified |
||||
@@ -1075,7 +1077,8 @@ curve25519-sha256,curve25519-sha256@libs |
||||
ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, |
||||
diffie-hellman-group-exchange-sha256, |
||||
diffie-hellman-group-exchange-sha1, |
||||
-diffie-hellman-group14-sha1 |
||||
+diffie-hellman-group14-sha1, |
||||
+diffie-hellman-group1-sha1 |
||||
.Ed |
||||
.Pp |
||||
The list of available key exchange algorithms may also be obtained using |
||||
@@ -1313,8 +1316,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com |
||||
ecdsa-sha2-nistp521-cert-v01@openssh.com, |
||||
ssh-ed25519-cert-v01@openssh.com, |
||||
ssh-rsa-cert-v01@openssh.com, |
||||
+ssh-dss-cert-v01@openssh.com, |
||||
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, |
||||
-ssh-ed25519,ssh-rsa |
||||
+ssh-ed25519,ssh-rsa,ssh-dsa |
||||
.Ed |
||||
.Pp |
||||
The list of available key types may also be obtained using |
||||
diff -up openssh-7.4p1/sshd_config.5.legacy openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.legacy 2017-03-02 17:00:37.636695990 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2017-03-02 17:04:17.528421067 +0100 |
||||
@@ -481,7 +481,9 @@ The default is: |
||||
.Bd -literal -offset indent |
||||
chacha20-poly1305@openssh.com, |
||||
aes128-ctr,aes192-ctr,aes256-ctr, |
||||
-aes128-gcm@openssh.com,aes256-gcm@openssh.com |
||||
+aes128-gcm@openssh.com,aes256-gcm@openssh.com, |
||||
+aes128-cbc,aes192-cbc,aes256-cbc, |
||||
+blowfish-cbc,cast128-cbc,3des-cbc |
||||
.Ed |
||||
.Pp |
||||
The list of available ciphers may also be obtained using |
||||
@@ -707,8 +709,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com |
||||
ecdsa-sha2-nistp521-cert-v01@openssh.com, |
||||
ssh-ed25519-cert-v01@openssh.com, |
||||
ssh-rsa-cert-v01@openssh.com, |
||||
+ssh-dss-cert-v01@openssh.com, |
||||
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, |
||||
-ssh-ed25519,ssh-rsa |
||||
+ssh-ed25519,ssh-rsa,ssh-dss |
||||
.Ed |
||||
.Pp |
||||
The list of available key types may also be obtained using |
||||
@@ -785,8 +788,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com |
||||
ecdsa-sha2-nistp521-cert-v01@openssh.com, |
||||
ssh-ed25519-cert-v01@openssh.com, |
||||
ssh-rsa-cert-v01@openssh.com, |
||||
+ssh-dss-cert-v01@openssh.com, |
||||
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, |
||||
-ssh-ed25519,ssh-rsa |
||||
+ssh-ed25519,ssh-rsa,ssh-dss |
||||
.Ed |
||||
.Pp |
||||
The list of available key types may also be obtained using |
||||
@@ -926,7 +930,8 @@ The default is: |
||||
curve25519-sha256,curve25519-sha256@libssh.org, |
||||
ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, |
||||
diffie-hellman-group-exchange-sha256, |
||||
-diffie-hellman-group14-sha1 |
||||
+diffie-hellman-group14-sha1, |
||||
+diffie-hellman-group1-sha1 |
||||
.Ed |
||||
.Pp |
||||
The list of available key exchange algorithms may also be obtained using |
||||
@@ -1040,7 +1045,8 @@ umac-64-etm@openssh.com,umac-128-etm@ope |
||||
hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, |
||||
hmac-sha1-etm@openssh.com, |
||||
umac-64@openssh.com,umac-128@openssh.com, |
||||
-hmac-sha2-256,hmac-sha2-512,hmac-sha1 |
||||
+hmac-sha2-256,hmac-sha2-512,hmac-sha1, |
||||
+hmac-sha1-etm@openssh.com |
||||
.Ed |
||||
.Pp |
||||
The list of available MAC algorithms may also be obtained using |
||||
@@ -1344,8 +1350,9 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com |
||||
ecdsa-sha2-nistp521-cert-v01@openssh.com, |
||||
ssh-ed25519-cert-v01@openssh.com, |
||||
ssh-rsa-cert-v01@openssh.com, |
||||
+ssh-dss-cert-v01@openssh.com, |
||||
ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, |
||||
-ssh-ed25519,ssh-rsa |
||||
+ssh-ed25519,ssh-rsa,ssh-dss |
||||
.Ed |
||||
.Pp |
||||
The list of available key types may also be obtained using |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
diff -up openssh-7.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id openssh-7.4p1/contrib/ssh-copy-id.1 |
||||
--- openssh-7.4p1/contrib/ssh-copy-id.1.legacy-ssh-copy-id 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/contrib/ssh-copy-id.1 2017-02-09 09:23:25.366651136 +0100 |
||||
@@ -185,6 +185,19 @@ should prove enlightening (N.B. the mode |
||||
.Fl W |
||||
option, rather than |
||||
.Xr nc 1 ) . |
||||
+.Sh ENVIRONMENT |
||||
+.Bl -tag -width Ds |
||||
+.Pp |
||||
+.It Pa SSH_COPY_ID_LEGACY |
||||
+If the |
||||
+.Cm SSH_COPY_ID_LEGACY |
||||
+environment variable is set, the |
||||
+.Nm |
||||
+is run in a legacy mode. In this mode, the |
||||
+.Nm |
||||
+doesn't check an existence of a private key and doesn't do remote checks |
||||
+of the remote server versions or if public keys are already installed. |
||||
+.El |
||||
.Sh "SEE ALSO" |
||||
.Xr ssh 1 , |
||||
.Xr ssh-agent 1 , |
||||
diff -up openssh-7.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id openssh-7.4p1/contrib/ssh-copy-id |
||||
--- openssh-7.4p1/contrib/ssh-copy-id.legacy-ssh-copy-id 2017-02-09 09:23:25.366651136 +0100 |
||||
+++ openssh-7.4p1/contrib/ssh-copy-id 2017-02-09 09:33:07.896518169 +0100 |
||||
@@ -99,6 +99,9 @@ if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L |
||||
GET_ID="ssh-add -L" |
||||
fi |
||||
|
||||
+# legacy environment variable implies forced copy |
||||
+[ "x$SSH_COPY_ID_LEGACY" != "x" ] && FORCED=1 |
||||
+ |
||||
while test "$#" -gt 0 |
||||
do |
||||
[ "${SEEN_OPT_I}" ] && expr "$1" : "[-]i" >/dev/null && { |
@ -0,0 +1,285 @@
@@ -0,0 +1,285 @@
|
||||
diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c |
||||
--- openssh-7.4p1/log.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/log.c 2017-02-09 09:51:07.571909000 +0100 |
||||
@@ -250,6 +250,11 @@ debug3(const char *fmt,...) |
||||
void |
||||
log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) |
||||
{ |
||||
+ log_init_handler(av0, level, facility, on_stderr, 1); |
||||
+} |
||||
+ |
||||
+void |
||||
+log_init_handler(char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) { |
||||
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) |
||||
struct syslog_data sdata = SYSLOG_DATA_INIT; |
||||
#endif |
||||
@@ -273,8 +278,10 @@ log_init(char *av0, LogLevel level, Sysl |
||||
exit(1); |
||||
} |
||||
|
||||
- log_handler = NULL; |
||||
- log_handler_ctx = NULL; |
||||
+ if (reset_handler) { |
||||
+ log_handler = NULL; |
||||
+ log_handler_ctx = NULL; |
||||
+ } |
||||
|
||||
log_on_stderr = on_stderr; |
||||
if (on_stderr) |
||||
diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h |
||||
--- openssh-7.4p1/log.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/log.h 2017-02-09 09:51:07.571909000 +0100 |
||||
@@ -49,6 +49,7 @@ typedef enum { |
||||
typedef void (log_handler_fn)(LogLevel, const char *, void *); |
||||
|
||||
void log_init(char *, LogLevel, SyslogFacility, int); |
||||
+void log_init_handler(char *, LogLevel, SyslogFacility, int, int); |
||||
void log_change_level(LogLevel); |
||||
int log_is_on_stderr(void); |
||||
void log_redirect_stderr_to(const char *); |
||||
diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c |
||||
--- openssh-7.4p1/monitor.c.log-in-chroot 2017-02-09 09:51:07.554909017 +0100 |
||||
+++ openssh-7.4p1/monitor.c 2017-02-09 10:05:21.067174230 +0100 |
||||
@@ -307,6 +307,8 @@ monitor_child_preauth(Authctxt *_authctx |
||||
close(pmonitor->m_log_sendfd); |
||||
pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; |
||||
|
||||
+ pmonitor->m_state = "preauth"; |
||||
+ |
||||
authctxt = _authctxt; |
||||
memset(authctxt, 0, sizeof(*authctxt)); |
||||
|
||||
@@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p |
||||
close(pmonitor->m_recvfd); |
||||
pmonitor->m_recvfd = -1; |
||||
|
||||
+ pmonitor->m_state = "postauth"; |
||||
+ |
||||
monitor_set_child_handler(pmonitor->m_pid); |
||||
signal(SIGHUP, &monitor_child_handler); |
||||
signal(SIGTERM, &monitor_child_handler); |
||||
@@ -472,7 +476,7 @@ monitor_read_log(struct monitor *pmonito |
||||
if (log_level_name(level) == NULL) |
||||
fatal("%s: invalid log level %u (corrupted message?)", |
||||
__func__, level); |
||||
- do_log2(level, "%s [preauth]", msg); |
||||
+ do_log2(level, "%s [%s]", msg, pmonitor->m_state); |
||||
|
||||
buffer_free(&logmsg); |
||||
free(msg); |
||||
@@ -1719,13 +1723,28 @@ monitor_init(void) |
||||
mon = xcalloc(1, sizeof(*mon)); |
||||
monitor_openfds(mon, 1); |
||||
|
||||
+ mon->m_state = ""; |
||||
+ |
||||
return mon; |
||||
} |
||||
|
||||
void |
||||
-monitor_reinit(struct monitor *mon) |
||||
+monitor_reinit(struct monitor *mon, const char *chroot_dir) |
||||
{ |
||||
- monitor_openfds(mon, 0); |
||||
+ struct stat dev_log_stat; |
||||
+ char *dev_log_path; |
||||
+ int do_logfds = 0; |
||||
+ |
||||
+ if (chroot_dir != NULL) { |
||||
+ xasprintf(&dev_log_path, "%s/dev/log", chroot_dir); |
||||
+ |
||||
+ if (stat(dev_log_path, &dev_log_stat) != 0) { |
||||
+ debug("%s: /dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", __func__, chroot_dir); |
||||
+ do_logfds = 1; |
||||
+ } |
||||
+ free(dev_log_path); |
||||
+ } |
||||
+ monitor_openfds(mon, do_logfds); |
||||
} |
||||
|
||||
#ifdef GSSAPI |
||||
diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h |
||||
--- openssh-7.4p1/monitor.h.log-in-chroot 2017-02-09 09:51:07.571909000 +0100 |
||||
+++ openssh-7.4p1/monitor.h 2017-02-09 10:05:49.792146561 +0100 |
||||
@@ -83,10 +83,11 @@ struct monitor { |
||||
int m_log_sendfd; |
||||
struct kex **m_pkex; |
||||
pid_t m_pid; |
||||
+ char *m_state; |
||||
}; |
||||
|
||||
struct monitor *monitor_init(void); |
||||
-void monitor_reinit(struct monitor *); |
||||
+void monitor_reinit(struct monitor *, const char *); |
||||
|
||||
struct Authctxt; |
||||
void monitor_child_preauth(struct Authctxt *, struct monitor *); |
||||
diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c |
||||
--- openssh-7.4p1/session.c.log-in-chroot 2017-02-09 09:51:07.570909002 +0100 |
||||
+++ openssh-7.4p1/session.c 2017-02-09 10:08:16.241005497 +0100 |
||||
@@ -160,6 +160,7 @@ login_cap_t *lc; |
||||
|
||||
static int is_child = 0; |
||||
static int in_chroot = 0; |
||||
+static int have_dev_log = 1; |
||||
|
||||
/* Name and directory of socket for authentication agent forwarding. */ |
||||
static char *auth_sock_name = NULL; |
||||
@@ -365,8 +366,8 @@ do_exec_no_pty(Session *s, const char *c |
||||
is_child = 1; |
||||
|
||||
/* Child. Reinitialize the log since the pid has changed. */ |
||||
- log_init(__progname, options.log_level, |
||||
- options.log_facility, log_stderr); |
||||
+ log_init_handler(__progname, options.log_level, |
||||
+ options.log_facility, log_stderr, have_dev_log); |
||||
|
||||
/* |
||||
* Create a new session and process group since the 4.4BSD |
||||
@@ -523,8 +524,8 @@ do_exec_pty(Session *s, const char *comm |
||||
close(ptymaster); |
||||
|
||||
/* Child. Reinitialize the log because the pid has changed. */ |
||||
- log_init(__progname, options.log_level, |
||||
- options.log_facility, log_stderr); |
||||
+ log_init_handler(__progname, options.log_level, |
||||
+ options.log_facility, log_stderr, have_dev_log); |
||||
/* Close the master side of the pseudo tty. */ |
||||
close(ptyfd); |
||||
|
||||
@@ -619,6 +620,7 @@ do_exec(Session *s, const char *command) |
||||
int ret; |
||||
const char *forced = NULL, *tty = NULL; |
||||
char session_type[1024]; |
||||
+ struct stat dev_log_stat; |
||||
|
||||
if (options.adm_forced_command) { |
||||
original_command = command; |
||||
@@ -676,6 +678,10 @@ do_exec(Session *s, const char *command) |
||||
tty += 5; |
||||
} |
||||
|
||||
+ if (lstat("/dev/log", &dev_log_stat) != 0) { |
||||
+ have_dev_log = 0; |
||||
+ } |
||||
+ |
||||
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", |
||||
session_type, |
||||
tty == NULL ? "" : " on ", |
||||
@@ -1490,14 +1496,6 @@ child_close_fds(void) |
||||
* descriptors left by system functions. They will be closed later. |
||||
*/ |
||||
endpwent(); |
||||
- |
||||
- /* |
||||
- * Close any extra open file descriptors so that we don't have them |
||||
- * hanging around in clients. Note that we want to do this after |
||||
- * initgroups, because at least on Solaris 2.3 it leaves file |
||||
- * descriptors open. |
||||
- */ |
||||
- closefrom(STDERR_FILENO + 1); |
||||
} |
||||
|
||||
/* |
||||
@@ -1633,8 +1631,6 @@ do_child(Session *s, const char *command |
||||
exit(1); |
||||
} |
||||
|
||||
- closefrom(STDERR_FILENO + 1); |
||||
- |
||||
do_rc_files(s, shell); |
||||
|
||||
/* restore SIGPIPE for child */ |
||||
@@ -1658,9 +1654,17 @@ do_child(Session *s, const char *command |
||||
argv[i] = NULL; |
||||
optind = optreset = 1; |
||||
__progname = argv[0]; |
||||
- exit(sftp_server_main(i, argv, s->pw)); |
||||
+ exit(sftp_server_main(i, argv, s->pw, have_dev_log)); |
||||
} |
||||
|
||||
+ /* |
||||
+ * Close any extra open file descriptors so that we don't have them |
||||
+ * hanging around in clients. Note that we want to do this after |
||||
+ * initgroups, because at least on Solaris 2.3 it leaves file |
||||
+ * descriptors open. |
||||
+ */ |
||||
+ closefrom(STDERR_FILENO + 1); |
||||
+ |
||||
fflush(NULL); |
||||
|
||||
/* Get the last component of the shell name. */ |
||||
diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h |
||||
--- openssh-7.4p1/sftp.h.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/sftp.h 2017-02-09 09:51:07.572908999 +0100 |
||||
@@ -97,5 +97,5 @@ |
||||
|
||||
struct passwd; |
||||
|
||||
-int sftp_server_main(int, char **, struct passwd *); |
||||
+int sftp_server_main(int, char **, struct passwd *, int); |
||||
void sftp_server_cleanup_exit(int) __attribute__((noreturn)); |
||||
diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c |
||||
--- openssh-7.4p1/sftp-server.c.log-in-chroot 2017-02-09 09:51:07.572908999 +0100 |
||||
+++ openssh-7.4p1/sftp-server.c 2017-02-09 10:09:39.662925141 +0100 |
||||
@@ -1497,7 +1497,7 @@ sftp_server_usage(void) |
||||
} |
||||
|
||||
int |
||||
-sftp_server_main(int argc, char **argv, struct passwd *user_pw) |
||||
+sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler) |
||||
{ |
||||
fd_set *rset, *wset; |
||||
int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; |
||||
@@ -1511,7 +1511,7 @@ sftp_server_main(int argc, char **argv, |
||||
|
||||
ssh_malloc_init(); /* must be called before any mallocs */ |
||||
__progname = ssh_get_progname(argv[0]); |
||||
- log_init(__progname, log_level, log_facility, log_stderr); |
||||
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); |
||||
|
||||
pw = pwcopy(user_pw); |
||||
|
||||
@@ -1582,7 +1582,7 @@ sftp_server_main(int argc, char **argv, |
||||
} |
||||
} |
||||
|
||||
- log_init(__progname, log_level, log_facility, log_stderr); |
||||
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); |
||||
|
||||
/* |
||||
* On platforms where we can, avoid making /proc/self/{mem,maps} |
||||
diff -up openssh-7.4p1/sftp-server-main.c.log-in-chroot openssh-7.4p1/sftp-server-main.c |
||||
--- openssh-7.4p1/sftp-server-main.c.log-in-chroot 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/sftp-server-main.c 2017-02-09 09:51:07.572908999 +0100 |
||||
@@ -49,5 +49,5 @@ main(int argc, char **argv) |
||||
return 1; |
||||
} |
||||
|
||||
- return (sftp_server_main(argc, argv, user_pw)); |
||||
+ return (sftp_server_main(argc, argv, user_pw, 0)); |
||||
} |
||||
diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c |
||||
--- openssh-7.4p1/sshd.c.log-in-chroot 2017-02-09 09:51:07.557909015 +0100 |
||||
+++ openssh-7.4p1/sshd.c 2017-02-09 09:51:07.573908998 +0100 |
||||
@@ -642,7 +642,7 @@ privsep_postauth(Authctxt *authctxt) |
||||
} |
||||
|
||||
/* New socket pair */ |
||||
- monitor_reinit(pmonitor); |
||||
+ monitor_reinit(pmonitor, options.chroot_directory); |
||||
|
||||
pmonitor->m_pid = fork(); |
||||
if (pmonitor->m_pid == -1) |
||||
@@ -660,6 +660,11 @@ privsep_postauth(Authctxt *authctxt) |
||||
|
||||
close(pmonitor->m_sendfd); |
||||
pmonitor->m_sendfd = -1; |
||||
+ close(pmonitor->m_log_recvfd); |
||||
+ pmonitor->m_log_recvfd = -1; |
||||
+ |
||||
+ if (pmonitor->m_log_sendfd != -1) |
||||
+ set_log_handler(mm_log_handler, pmonitor); |
||||
|
||||
/* Demote the private keys to public keys. */ |
||||
demote_sensitive_data(); |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
diff -up openssh-7.4p1/sshd.c.newline-banner openssh-7.4p1/sshd.c |
||||
--- openssh-7.4p1/sshd.c.newline-banner 2017-02-17 14:00:47.237168594 +0100 |
||||
+++ openssh-7.4p1/sshd.c 2017-02-17 14:02:10.933096707 +0100 |
||||
@@ -369,15 +369,15 @@ sshd_exchange_identification(struct ssh |
||||
{ |
||||
u_int i; |
||||
int remote_major, remote_minor; |
||||
- char *s, *newline = "\n"; |
||||
+ char *s; |
||||
char buf[256]; /* Must not be larger than remote_version. */ |
||||
char remote_version[256]; /* Must be at least as big as buf. */ |
||||
|
||||
- xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", |
||||
+ xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n", |
||||
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, |
||||
(options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, |
||||
*options.version_addendum == '\0' ? "" : " ", |
||||
- options.version_addendum, newline); |
||||
+ options.version_addendum); |
||||
|
||||
/* Send our protocol version identification. */ |
||||
if (atomicio(vwrite, sock_out, server_version_string, |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
diff -up openssh-7.4p1/servconf.c.permit-root openssh-7.4p1/servconf.c |
||||
--- openssh-7.4p1/servconf.c.permit-root 2017-02-10 10:27:18.109487568 +0100 |
||||
+++ openssh-7.4p1/servconf.c 2017-02-10 10:28:12.385776132 +0100 |
||||
@@ -231,7 +231,7 @@ fill_default_server_options(ServerOption |
||||
if (options->login_grace_time == -1) |
||||
options->login_grace_time = 120; |
||||
if (options->permit_root_login == PERMIT_NOT_SET) |
||||
- options->permit_root_login = PERMIT_NO_PASSWD; |
||||
+ options->permit_root_login = PERMIT_YES; |
||||
if (options->ignore_rhosts == -1) |
||||
options->ignore_rhosts = 1; |
||||
if (options->ignore_user_known_hosts == -1) |
||||
diff -up openssh-7.4p1/sshd_config.5.permit-root openssh-7.4p1/sshd_config.5 |
||||
--- openssh-7.4p1/sshd_config.5.permit-root 2017-02-10 10:28:24.174605582 +0100 |
||||
+++ openssh-7.4p1/sshd_config.5 2017-02-10 10:28:42.254344023 +0100 |
||||
@@ -1227,7 +1227,7 @@ The argument must be |
||||
or |
||||
.Cm no . |
||||
The default is |
||||
-.Cm prohibit-password . |
||||
+.Cm yes . |
||||
.Pp |
||||
If this option is set to |
||||
.Cm prohibit-password |
||||
diff -up openssh-7.4p1/sshd_config.permit-root openssh-7.4p1/sshd_config |
||||
--- openssh-7.4p1/sshd_config.permit-root 2017-02-10 10:26:52.256797645 +0100 |
||||
+++ openssh-7.4p1/sshd_config 2017-02-10 10:26:52.276797405 +0100 |
||||
@@ -35,7 +35,7 @@ SyslogFacility AUTHPRIV |
||||
# Authentication: |
||||
|
||||
#LoginGraceTime 2m |
||||
-#PermitRootLogin prohibit-password |
||||
+#PermitRootLogin yes |
||||
#StrictModes yes |
||||
#MaxAuthTries 6 |
||||
#MaxSessions 10 |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
diff -up openssh-7.4p1/ssh-agent.1.pkcs11-whitelist openssh-7.4p1/ssh-agent.1 |
||||
--- openssh-7.4p1/ssh-agent.1.pkcs11-whitelist 2017-01-03 10:41:01.916331710 +0100 |
||||
+++ openssh-7.4p1/ssh-agent.1 2017-01-03 10:40:06.549366029 +0100 |
||||
@@ -129,7 +129,7 @@ that may be added using the |
||||
option to |
||||
.Xr ssh-add 1 . |
||||
The default is to allow loading PKCS#11 libraries from |
||||
-.Dq /usr/lib/*,/usr/local/lib/* . |
||||
+.Dq /usr/lib*/*,/usr/local/lib*/* . |
||||
PKCS#11 libraries that do not match the whitelist will be refused. |
||||
See PATTERNS in |
||||
.Xr ssh_config 5 |
||||
diff -up openssh-7.4p1/ssh-agent.c.pkcs11-whitelist openssh-7.4p1/ssh-agent.c |
||||
--- openssh-7.4p1/ssh-agent.c.pkcs11-whitelist 2017-01-03 10:41:09.324327118 +0100 |
||||
+++ openssh-7.4p1/ssh-agent.c 2017-01-03 10:40:21.212356939 +0100 |
||||
@@ -89,7 +89,7 @@ |
||||
#endif |
||||
|
||||
#ifndef DEFAULT_PKCS11_WHITELIST |
||||
-# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" |
||||
+# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*" |
||||
#endif |
||||
|
||||
typedef enum { |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
diff --git a/serverloop.c b/serverloop.c |
||||
index b5eb3440..1535eeb2 100644 |
||||
--- a/serverloop.c |
||||
+++ b/serverloop.c |
||||
@@ -225,9 +225,10 @@ wait_until_can_do_something(int connection_in, int connection_out, |
||||
uint64_t keepalive_ms = |
||||
(uint64_t)options.client_alive_interval * 1000; |
||||
|
||||
- client_alive_scheduled = 1; |
||||
- if (max_time_ms == 0 || max_time_ms > keepalive_ms) |
||||
+ if (max_time_ms == 0 || max_time_ms > keepalive_ms) { |
||||
max_time_ms = keepalive_ms; |
||||
+ client_alive_scheduled = 1; |
||||
+ } |
||||
} |
||||
|
||||
#if 0 |
||||
|
@ -0,0 +1,840 @@
@@ -0,0 +1,840 @@
|
||||
diff -up openssh-7.4p1/auth2.c.role-mls openssh-7.4p1/auth2.c |
||||
--- openssh-7.4p1/auth2.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/auth2.c 2017-02-08 14:08:30.271308186 +0100 |
||||
@@ -215,6 +215,9 @@ input_userauth_request(int type, u_int32 |
||||
Authctxt *authctxt = ctxt; |
||||
Authmethod *m = NULL; |
||||
char *user, *service, *method, *style = NULL; |
||||
+#ifdef WITH_SELINUX |
||||
+ char *role = NULL; |
||||
+#endif |
||||
int authenticated = 0; |
||||
|
||||
if (authctxt == NULL) |
||||
@@ -226,6 +229,11 @@ input_userauth_request(int type, u_int32 |
||||
debug("userauth-request for user %s service %s method %s", user, service, method); |
||||
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+ if ((role = strchr(user, '/')) != NULL) |
||||
+ *role++ = 0; |
||||
+#endif |
||||
+ |
||||
if ((style = strchr(user, ':')) != NULL) |
||||
*style++ = 0; |
||||
|
||||
@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32 |
||||
use_privsep ? " [net]" : ""); |
||||
authctxt->service = xstrdup(service); |
||||
authctxt->style = style ? xstrdup(style) : NULL; |
||||
- if (use_privsep) |
||||
+#ifdef WITH_SELINUX |
||||
+ authctxt->role = role ? xstrdup(role) : NULL; |
||||
+#endif |
||||
+ if (use_privsep) { |
||||
mm_inform_authserv(service, style); |
||||
+#ifdef WITH_SELINUX |
||||
+ mm_inform_authrole(role); |
||||
+#endif |
||||
+ } |
||||
userauth_banner(); |
||||
if (auth2_setup_methods_lists(authctxt) != 0) |
||||
packet_disconnect("no authentication methods enabled"); |
||||
diff -up openssh-7.4p1/auth2-gss.c.role-mls openssh-7.4p1/auth2-gss.c |
||||
--- openssh-7.4p1/auth2-gss.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/auth2-gss.c 2017-02-08 14:08:30.270308187 +0100 |
||||
@@ -255,6 +255,7 @@ input_gssapi_mic(int type, u_int32_t ple |
||||
Authctxt *authctxt = ctxt; |
||||
Gssctxt *gssctxt; |
||||
int authenticated = 0; |
||||
+ char *micuser; |
||||
Buffer b; |
||||
gss_buffer_desc mic, gssbuf; |
||||
u_int len; |
||||
@@ -267,7 +268,13 @@ input_gssapi_mic(int type, u_int32_t ple |
||||
mic.value = packet_get_string(&len); |
||||
mic.length = len; |
||||
|
||||
- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, |
||||
+#ifdef WITH_SELINUX |
||||
+ if (authctxt->role && (strlen(authctxt->role) > 0)) |
||||
+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); |
||||
+ else |
||||
+#endif |
||||
+ micuser = authctxt->user; |
||||
+ ssh_gssapi_buildmic(&b, micuser, authctxt->service, |
||||
"gssapi-with-mic"); |
||||
|
||||
gssbuf.value = buffer_ptr(&b); |
||||
@@ -279,6 +286,8 @@ input_gssapi_mic(int type, u_int32_t ple |
||||
logit("GSSAPI MIC check failed"); |
||||
|
||||
buffer_free(&b); |
||||
+ if (micuser != authctxt->user) |
||||
+ free(micuser); |
||||
free(mic.value); |
||||
|
||||
authctxt->postponed = 0; |
||||
diff -up openssh-7.4p1/auth2-hostbased.c.role-mls openssh-7.4p1/auth2-hostbased.c |
||||
--- openssh-7.4p1/auth2-hostbased.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/auth2-hostbased.c 2017-02-08 14:08:30.270308187 +0100 |
||||
@@ -121,7 +121,15 @@ userauth_hostbased(Authctxt *authctxt) |
||||
buffer_put_string(&b, session_id2, session_id2_len); |
||||
/* reconstruct packet */ |
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); |
||||
- buffer_put_cstring(&b, authctxt->user); |
||||
+#ifdef WITH_SELINUX |
||||
+ if (authctxt->role) { |
||||
+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); |
||||
+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); |
||||
+ buffer_put_char(&b, '/'); |
||||
+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); |
||||
+ } else |
||||
+#endif |
||||
+ buffer_put_cstring(&b, authctxt->user); |
||||
buffer_put_cstring(&b, service); |
||||
buffer_put_cstring(&b, "hostbased"); |
||||
buffer_put_string(&b, pkalg, alen); |
||||
diff -up openssh-7.4p1/auth2-pubkey.c.role-mls openssh-7.4p1/auth2-pubkey.c |
||||
--- openssh-7.4p1/auth2-pubkey.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/auth2-pubkey.c 2017-02-08 14:08:30.270308187 +0100 |
||||
@@ -151,9 +151,11 @@ userauth_pubkey(Authctxt *authctxt) |
||||
} |
||||
/* reconstruct packet */ |
||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); |
||||
- xasprintf(&userstyle, "%s%s%s", authctxt->user, |
||||
+ xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user, |
||||
authctxt->style ? ":" : "", |
||||
- authctxt->style ? authctxt->style : ""); |
||||
+ authctxt->style ? authctxt->style : "", |
||||
+ authctxt->role ? "/" : "", |
||||
+ authctxt->role ? authctxt->role : ""); |
||||
buffer_put_cstring(&b, userstyle); |
||||
free(userstyle); |
||||
buffer_put_cstring(&b, |
||||
diff -up openssh-7.4p1/auth.h.role-mls openssh-7.4p1/auth.h |
||||
--- openssh-7.4p1/auth.h.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/auth.h 2017-02-08 14:08:30.270308187 +0100 |
||||
@@ -62,6 +62,9 @@ struct Authctxt { |
||||
char *service; |
||||
struct passwd *pw; /* set if 'valid' */ |
||||
char *style; |
||||
+#ifdef WITH_SELINUX |
||||
+ char *role; |
||||
+#endif |
||||
void *kbdintctxt; |
||||
char *info; /* Extra info for next auth_log */ |
||||
#ifdef BSD_AUTH |
||||
diff -up openssh-7.4p1/auth-pam.c.role-mls openssh-7.4p1/auth-pam.c |
||||
--- openssh-7.4p1/auth-pam.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/auth-pam.c 2017-02-08 14:08:30.270308187 +0100 |
||||
@@ -1087,7 +1087,7 @@ is_pam_session_open(void) |
||||
* during the ssh authentication process. |
||||
*/ |
||||
int |
||||
-do_pam_putenv(char *name, char *value) |
||||
+do_pam_putenv(char *name, const char *value) |
||||
{ |
||||
int ret = 1; |
||||
#ifdef HAVE_PAM_PUTENV |
||||
diff -up openssh-7.4p1/auth-pam.h.role-mls openssh-7.4p1/auth-pam.h |
||||
--- openssh-7.4p1/auth-pam.h.role-mls 2017-02-08 14:08:30.270308187 +0100 |
||||
+++ openssh-7.4p1/auth-pam.h 2017-02-08 14:09:09.711273302 +0100 |
||||
@@ -31,7 +31,7 @@ u_int do_pam_account(void); |
||||
void do_pam_session(void); |
||||
void do_pam_setcred(int ); |
||||
void do_pam_chauthtok(void); |
||||
-int do_pam_putenv(char *, char *); |
||||
+int do_pam_putenv(char *, const char *); |
||||
char ** fetch_pam_environment(void); |
||||
char ** fetch_pam_child_environment(void); |
||||
void free_pam_environment(char **); |
||||
diff -up openssh-7.4p1/misc.c.role-mls openssh-7.4p1/misc.c |
||||
--- openssh-7.4p1/misc.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/misc.c 2017-02-08 14:08:30.271308186 +0100 |
||||
@@ -432,6 +432,7 @@ char * |
||||
colon(char *cp) |
||||
{ |
||||
int flag = 0; |
||||
+ int start = 1; |
||||
|
||||
if (*cp == ':') /* Leading colon is part of file name. */ |
||||
return NULL; |
||||
@@ -447,6 +448,13 @@ colon(char *cp) |
||||
return (cp); |
||||
if (*cp == '/') |
||||
return NULL; |
||||
+ if (start) { |
||||
+ /* Slash on beginning or after dots only denotes file name. */ |
||||
+ if (*cp == '/') |
||||
+ return (0); |
||||
+ if (*cp != '.') |
||||
+ start = 0; |
||||
+ } |
||||
} |
||||
return NULL; |
||||
} |
||||
diff -up openssh-7.4p1/monitor.c.role-mls openssh-7.4p1/monitor.c |
||||
--- openssh-7.4p1/monitor.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/monitor.c 2017-02-08 14:18:13.289928913 +0100 |
||||
@@ -127,6 +127,9 @@ int mm_answer_sign(int, Buffer *); |
||||
int mm_answer_pwnamallow(int, Buffer *); |
||||
int mm_answer_auth2_read_banner(int, Buffer *); |
||||
int mm_answer_authserv(int, Buffer *); |
||||
+#ifdef WITH_SELINUX |
||||
+int mm_answer_authrole(int, Buffer *); |
||||
+#endif |
||||
int mm_answer_authpassword(int, Buffer *); |
||||
int mm_answer_bsdauthquery(int, Buffer *); |
||||
int mm_answer_bsdauthrespond(int, Buffer *); |
||||
@@ -202,6 +205,9 @@ struct mon_table mon_dispatch_proto20[] |
||||
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, |
||||
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, |
||||
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, |
||||
+#ifdef WITH_SELINUX |
||||
+ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, |
||||
+#endif |
||||
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, |
||||
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, |
||||
#ifdef USE_PAM |
||||
@@ -769,6 +775,9 @@ mm_answer_pwnamallow(int sock, Buffer *m |
||||
|
||||
/* Allow service/style information on the auth context */ |
||||
monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
||||
+#ifdef WITH_SELINUX |
||||
+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); |
||||
+#endif |
||||
monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
||||
|
||||
#ifdef USE_PAM |
||||
@@ -810,6 +819,25 @@ mm_answer_authserv(int sock, Buffer *m) |
||||
return (0); |
||||
} |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+int |
||||
+mm_answer_authrole(int sock, Buffer *m) |
||||
+{ |
||||
+ monitor_permit_authentications(1); |
||||
+ |
||||
+ authctxt->role = buffer_get_string(m, NULL); |
||||
+ debug3("%s: role=%s", |
||||
+ __func__, authctxt->role); |
||||
+ |
||||
+ if (strlen(authctxt->role) == 0) { |
||||
+ free(authctxt->role); |
||||
+ authctxt->role = NULL; |
||||
+ } |
||||
+ |
||||
+ return (0); |
||||
+} |
||||
+#endif |
||||
+ |
||||
int |
||||
mm_answer_authpassword(int sock, Buffer *m) |
||||
{ |
||||
@@ -1208,7 +1236,7 @@ monitor_valid_userblob(u_char *data, u_i |
||||
{ |
||||
Buffer b; |
||||
u_char *p; |
||||
- char *userstyle, *cp; |
||||
+ char *userstyle, *r, *cp; |
||||
u_int len; |
||||
int fail = 0; |
||||
|
||||
@@ -1234,6 +1262,8 @@ monitor_valid_userblob(u_char *data, u_i |
||||
if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) |
||||
fail++; |
||||
cp = buffer_get_cstring(&b, NULL); |
||||
+ if ((r = strchr(cp, '/')) != NULL) |
||||
+ *r = '\0'; |
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user, |
||||
authctxt->style ? ":" : "", |
||||
authctxt->style ? authctxt->style : ""); |
||||
@@ -1269,7 +1299,7 @@ monitor_valid_hostbasedblob(u_char *data |
||||
char *chost) |
||||
{ |
||||
Buffer b; |
||||
- char *p, *userstyle; |
||||
+ char *p, *r, *userstyle; |
||||
u_int len; |
||||
int fail = 0; |
||||
|
||||
@@ -1286,6 +1316,8 @@ monitor_valid_hostbasedblob(u_char *data |
||||
if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) |
||||
fail++; |
||||
p = buffer_get_cstring(&b, NULL); |
||||
+ if ((r = strchr(p, '/')) != NULL) |
||||
+ *r = '\0'; |
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user, |
||||
authctxt->style ? ":" : "", |
||||
authctxt->style ? authctxt->style : ""); |
||||
diff -up openssh-7.4p1/monitor.h.role-mls openssh-7.4p1/monitor.h |
||||
--- openssh-7.4p1/monitor.h.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/monitor.h 2017-02-08 14:08:30.271308186 +0100 |
||||
@@ -57,6 +57,10 @@ enum monitor_reqtype { |
||||
MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, |
||||
MONITOR_REQ_TERM = 50, |
||||
|
||||
+#ifdef WITH_SELINUX |
||||
+ MONITOR_REQ_AUTHROLE = 80, |
||||
+#endif |
||||
+ |
||||
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, |
||||
diff -up openssh-7.4p1/monitor_wrap.c.role-mls openssh-7.4p1/monitor_wrap.c |
||||
--- openssh-7.4p1/monitor_wrap.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/monitor_wrap.c 2017-02-08 14:08:30.271308186 +0100 |
||||
@@ -345,6 +345,25 @@ mm_inform_authserv(char *service, char * |
||||
buffer_free(&m); |
||||
} |
||||
|
||||
+/* Inform the privileged process about role */ |
||||
+ |
||||
+#ifdef WITH_SELINUX |
||||
+void |
||||
+mm_inform_authrole(char *role) |
||||
+{ |
||||
+ Buffer m; |
||||
+ |
||||
+ debug3("%s entering", __func__); |
||||
+ |
||||
+ buffer_init(&m); |
||||
+ buffer_put_cstring(&m, role ? role : ""); |
||||
+ |
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); |
||||
+ |
||||
+ buffer_free(&m); |
||||
+} |
||||
+#endif |
||||
+ |
||||
/* Do the password authentication */ |
||||
int |
||||
mm_auth_password(Authctxt *authctxt, char *password) |
||||
diff -up openssh-7.4p1/monitor_wrap.h.role-mls openssh-7.4p1/monitor_wrap.h |
||||
--- openssh-7.4p1/monitor_wrap.h.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/monitor_wrap.h 2016-12-23 12:19:58.588459376 +0100 |
||||
@@ -42,6 +42,9 @@ int mm_is_monitor(void); |
||||
DH *mm_choose_dh(int, int, int); |
||||
int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); |
||||
void mm_inform_authserv(char *, char *); |
||||
+#ifdef WITH_SELINUX |
||||
+void mm_inform_authrole(char *); |
||||
+#endif |
||||
struct passwd *mm_getpwnamallow(const char *); |
||||
char *mm_auth2_read_banner(void); |
||||
int mm_auth_password(struct Authctxt *, char *); |
||||
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in |
||||
index 6ecfb93..b912dbe 100644 |
||||
--- a/openbsd-compat/Makefile.in |
||||
+++ b/openbsd-compat/Makefile.in |
||||
@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di |
||||
|
||||
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.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 xcrypt.o kludge-fd_set.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-sshd.o port-solaris.o port-tun.o port-uw.o |
||||
|
||||
.c.o: |
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< |
||||
diff -up openssh-7.4p1/openbsd-compat/port-linux.c.role-mls openssh-7.4p1/openbsd-compat/port-linux.c |
||||
--- openssh-7.4p1/openbsd-compat/port-linux.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/openbsd-compat/port-linux.c 2017-02-08 14:08:30.272308185 +0100 |
||||
@@ -101,37 +101,6 @@ ssh_selinux_getctxbyname(char *pwname) |
||||
return sc; |
||||
} |
||||
|
||||
-/* Set the execution context to the default for the specified user */ |
||||
-void |
||||
-ssh_selinux_setup_exec_context(char *pwname) |
||||
-{ |
||||
- security_context_t user_ctx = NULL; |
||||
- |
||||
- if (!ssh_selinux_enabled()) |
||||
- return; |
||||
- |
||||
- debug3("%s: setting execution context", __func__); |
||||
- |
||||
- user_ctx = ssh_selinux_getctxbyname(pwname); |
||||
- if (setexeccon(user_ctx) != 0) { |
||||
- switch (security_getenforce()) { |
||||
- case -1: |
||||
- fatal("%s: security_getenforce() failed", __func__); |
||||
- case 0: |
||||
- error("%s: Failed to set SELinux execution " |
||||
- "context for %s", __func__, pwname); |
||||
- break; |
||||
- default: |
||||
- fatal("%s: Failed to set SELinux execution context " |
||||
- "for %s (in enforcing mode)", __func__, pwname); |
||||
- } |
||||
- } |
||||
- if (user_ctx != NULL) |
||||
- freecon(user_ctx); |
||||
- |
||||
- debug3("%s: done", __func__); |
||||
-} |
||||
- |
||||
/* Set the TTY context for the specified user */ |
||||
void |
||||
ssh_selinux_setup_pty(char *pwname, const char *tty) |
||||
diff -up openssh-7.4p1/openbsd-compat/port-linux.h.role-mls openssh-7.4p1/openbsd-compat/port-linux.h |
||||
--- openssh-7.4p1/openbsd-compat/port-linux.h.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/openbsd-compat/port-linux.h 2017-02-08 14:08:30.272308185 +0100 |
||||
@@ -20,9 +20,10 @@ |
||||
#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 *); |
||||
+ |
||||
+void sshd_selinux_setup_exec_context(char *); |
||||
#endif |
||||
|
||||
#ifdef LINUX_OOM_ADJUST |
||||
diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.role-mls openssh-7.4p1/openbsd-compat/port-linux-sshd.c |
||||
--- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.role-mls 2017-02-08 14:08:30.272308185 +0100 |
||||
+++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c 2017-02-08 14:08:30.272308185 +0100 |
||||
@@ -0,0 +1,415 @@ |
||||
+/* |
||||
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> |
||||
+ * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com> |
||||
+ * |
||||
+ * Permission to use, copy, modify, and distribute this software for any |
||||
+ * purpose with or without fee is hereby granted, provided that the above |
||||
+ * copyright notice and this permission notice appear in all copies. |
||||
+ * |
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
+ */ |
||||
+ |
||||
+/* |
||||
+ * Linux-specific portability code - just SELinux support for sshd at present |
||||
+ */ |
||||
+ |
||||
+#include "includes.h" |
||||
+ |
||||
+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) |
||||
+#include <errno.h> |
||||
+#include <stdarg.h> |
||||
+#include <string.h> |
||||
+#include <stdio.h> |
||||
+ |
||||
+#include "log.h" |
||||
+#include "xmalloc.h" |
||||
+#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ |
||||
+#include "servconf.h" |
||||
+#include "port-linux.h" |
||||
+#include "key.h" |
||||
+#include "hostfile.h" |
||||
+#include "auth.h" |
||||
+ |
||||
+#ifdef WITH_SELINUX |
||||
+#include <selinux/selinux.h> |
||||
+#include <selinux/flask.h> |
||||
+#include <selinux/context.h> |
||||
+#include <selinux/get_context_list.h> |
||||
+#include <selinux/get_default_type.h> |
||||
+#include <selinux/av_permissions.h> |
||||
+ |
||||
+#ifdef HAVE_LINUX_AUDIT |
||||
+#include <libaudit.h> |
||||
+#include <unistd.h> |
||||
+#endif |
||||
+ |
||||
+extern ServerOptions options; |
||||
+extern Authctxt *the_authctxt; |
||||
+extern int inetd_flag; |
||||
+extern int rexeced_flag; |
||||
+ |
||||
+/* Send audit message */ |
||||
+static int |
||||
+sshd_selinux_send_audit_message(int success, security_context_t default_context, |
||||
+ security_context_t selected_context) |
||||
+{ |
||||
+ int rc=0; |
||||
+#ifdef HAVE_LINUX_AUDIT |
||||
+ char *msg = NULL; |
||||
+ int audit_fd = audit_open(); |
||||
+ security_context_t default_raw=NULL; |
||||
+ security_context_t selected_raw=NULL; |
||||
+ rc = -1; |
||||
+ if (audit_fd < 0) { |
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT || |
||||
+ errno == EAFNOSUPPORT) |
||||
+ return 0; /* No audit support in kernel */ |
||||
+ error("Error connecting to audit system."); |
||||
+ return rc; |
||||
+ } |
||||
+ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { |
||||
+ error("Error translating default context."); |
||||
+ default_raw = NULL; |
||||
+ } |
||||
+ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { |
||||
+ error("Error translating selected context."); |
||||
+ selected_raw = NULL; |
||||
+ } |
||||
+ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s", |
||||
+ default_raw ? default_raw : (default_context ? default_context: "?"), |
||||
+ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) { |
||||
+ error("Error allocating memory."); |
||||
+ goto out; |
||||
+ } |
||||
+ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, |
||||
+ msg, NULL, NULL, NULL, success) <= 0) { |
||||
+ error("Error sending audit message."); |
||||
+ goto out; |
||||
+ } |
||||
+ rc = 0; |
||||
+ out: |
||||
+ free(msg); |
||||
+ freecon(default_raw); |
||||
+ freecon(selected_raw); |
||||
+ close(audit_fd); |
||||
+#endif |
||||
+ return rc; |
||||
+} |
||||
+ |
||||
+static int |
||||
+mls_range_allowed(security_context_t src, security_context_t dst) |
||||
+{ |
||||
+ struct av_decision avd; |
||||
+ int retval; |
||||
+ unsigned int bit = CONTEXT__CONTAINS; |
||||
+ |
||||
+ debug("%s: src:%s dst:%s", __func__, src, dst); |
||||
+ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); |
||||
+ if (retval || ((bit & avd.allowed) != bit)) |
||||
+ return 0; |
||||
+ |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
+static int |
||||
+get_user_context(const char *sename, const char *role, const char *lvl, |
||||
+ security_context_t *sc) { |
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
||||
+ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) { |
||||
+ /* User may have requested a level completely outside of his |
||||
+ allowed range. We get a context just for auditing as the |
||||
+ range check below will certainly fail for default context. */ |
||||
+#endif |
||||
+ if (get_default_context(sename, NULL, sc) != 0) { |
||||
+ *sc = NULL; |
||||
+ return -1; |
||||
+ } |
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
||||
+ } |
||||
+#endif |
||||
+ if (role != NULL && role[0]) { |
||||
+ context_t con; |
||||
+ char *type=NULL; |
||||
+ if (get_default_type(role, &type) != 0) { |
||||
+ error("get_default_type: failed to get default type for '%s'", |
||||
+ role); |
||||
+ goto out; |
||||
+ } |
||||
+ con = context_new(*sc); |
||||
+ if (!con) { |
||||
+ goto out; |
||||
+ } |
||||
+ context_role_set(con, role); |
||||
+ context_type_set(con, type); |
||||
+ freecon(*sc); |
||||
+ *sc = strdup(context_str(con)); |
||||
+ context_free(con); |
||||
+ if (!*sc) |
||||
+ return -1; |
||||
+ } |
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
||||
+ if (lvl != NULL && lvl[0]) { |
||||
+ /* verify that the requested range is obtained */ |
||||
+ context_t con; |
||||
+ security_context_t obtained_raw; |
||||
+ security_context_t requested_raw; |
||||
+ con = context_new(*sc); |
||||
+ if (!con) { |
||||
+ goto out; |
||||
+ } |
||||
+ context_range_set(con, lvl); |
||||
+ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) { |
||||
+ context_free(con); |
||||
+ goto out; |
||||
+ } |
||||
+ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) { |
||||
+ freecon(obtained_raw); |
||||
+ context_free(con); |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ debug("get_user_context: obtained context '%s' requested context '%s'", |
||||
+ obtained_raw, requested_raw); |
||||
+ if (strcmp(obtained_raw, requested_raw)) { |
||||
+ /* set the context to the real requested one but fail */ |
||||
+ freecon(requested_raw); |
||||
+ freecon(obtained_raw); |
||||
+ freecon(*sc); |
||||
+ *sc = strdup(context_str(con)); |
||||
+ context_free(con); |
||||
+ return -1; |
||||
+ } |
||||
+ freecon(requested_raw); |
||||
+ freecon(obtained_raw); |
||||
+ context_free(con); |
||||
+ } |
||||
+#endif |
||||
+ return 0; |
||||
+ out: |
||||
+ freecon(*sc); |
||||
+ *sc = NULL; |
||||
+ return -1; |
||||
+} |
||||
+ |
||||
+static void |
||||
+ssh_selinux_get_role_level(char **role, const char **level) |
||||
+{ |
||||
+ *role = NULL; |
||||
+ *level = NULL; |
||||
+ if (the_authctxt) { |
||||
+ if (the_authctxt->role != NULL) { |
||||
+ char *slash; |
||||
+ *role = xstrdup(the_authctxt->role); |
||||
+ if ((slash = strchr(*role, '/')) != NULL) { |
||||
+ *slash = '\0'; |
||||
+ *level = slash + 1; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+} |
||||
+ |
||||
+/* Return the default security context for the given username */ |
||||
+static int |
||||
+sshd_selinux_getctxbyname(char *pwname, |
||||
+ security_context_t *default_sc, security_context_t *user_sc) |
||||
+{ |
||||
+ char *sename, *lvl; |
||||
+ char *role; |
||||
+ const char *reqlvl; |
||||
+ int r = 0; |
||||
+ context_t con = NULL; |
||||
+ |
||||
+ ssh_selinux_get_role_level(&role, &reqlvl); |
||||
+ |
||||
+#ifdef HAVE_GETSEUSERBYNAME |
||||
+ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { |
||||
+ sename = NULL; |
||||
+ lvl = NULL; |
||||
+ } |
||||
+#else |
||||
+ sename = pwname; |
||||
+ lvl = ""; |
||||
+#endif |
||||
+ |
||||
+ if (r == 0) { |
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL |
||||
+ r = get_default_context_with_level(sename, lvl, NULL, default_sc); |
||||
+#else |
||||
+ r = get_default_context(sename, NULL, default_sc); |
||||
+#endif |
||||
+ } |
||||
+ |
||||
+ if (r == 0) { |
||||
+ /* If launched from xinetd, we must use current level */ |
||||
+ if (inetd_flag && !rexeced_flag) { |
||||
+ security_context_t sshdsc=NULL; |
||||
+ |
||||
+ if (getcon_raw(&sshdsc) < 0) |
||||
+ fatal("failed to allocate security context"); |
||||
+ |
||||
+ if ((con=context_new(sshdsc)) == NULL) |
||||
+ fatal("failed to allocate selinux context"); |
||||
+ reqlvl = context_range_get(con); |
||||
+ freecon(sshdsc); |
||||
+ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0) |
||||
+ /* we actually don't change level */ |
||||
+ reqlvl = ""; |
||||
+ |
||||
+ debug("%s: current connection level '%s'", __func__, reqlvl); |
||||
+ |
||||
+ } |
||||
+ |
||||
+ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { |
||||
+ r = get_user_context(sename, role, reqlvl, user_sc); |
||||
+ |
||||
+ if (r == 0 && reqlvl != NULL && reqlvl[0]) { |
||||
+ security_context_t default_level_sc = *default_sc; |
||||
+ if (role != NULL && role[0]) { |
||||
+ if (get_user_context(sename, role, lvl, &default_level_sc) < 0) |
||||
+ default_level_sc = *default_sc; |
||||
+ } |
||||
+ /* verify that the requested range is contained in the user range */ |
||||
+ if (mls_range_allowed(default_level_sc, *user_sc)) { |
||||
+ logit("permit MLS level %s (user range %s)", reqlvl, lvl); |
||||
+ } else { |
||||
+ r = -1; |
||||
+ error("deny MLS level %s (user range %s)", reqlvl, lvl); |
||||
+ } |
||||
+ if (default_level_sc != *default_sc) |
||||
+ freecon(default_level_sc); |
||||
+ } |
||||
+ } else { |
||||
+ *user_sc = *default_sc; |
||||
+ } |
||||
+ } |
||||
+ if (r != 0) { |
||||
+ error("%s: Failed to get default SELinux security " |
||||
+ "context for %s", __func__, pwname); |
||||
+ } |
||||
+ |
||||
+#ifdef HAVE_GETSEUSERBYNAME |
||||
+ free(sename); |
||||
+ free(lvl); |
||||
+#endif |
||||
+ |
||||
+ if (role != NULL) |
||||
+ free(role); |
||||
+ if (con) |
||||
+ context_free(con); |
||||
+ |
||||
+ return (r); |
||||
+} |
||||
+ |
||||
+/* Setup environment variables for pam_selinux */ |
||||
+static int |
||||
+sshd_selinux_setup_pam_variables(void) |
||||
+{ |
||||
+ const char *reqlvl; |
||||
+ char *role; |
||||
+ char *use_current; |
||||
+ int rv; |
||||
+ |
||||
+ debug3("%s: setting execution context", __func__); |
||||
+ |
||||
+ ssh_selinux_get_role_level(&role, &reqlvl); |
||||
+ |
||||
+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); |
||||
+ |
||||
+ if (inetd_flag && !rexeced_flag) { |
||||
+ use_current = "1"; |
||||
+ } else { |
||||
+ use_current = ""; |
||||
+ rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); |
||||
+ } |
||||
+ |
||||
+ rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); |
||||
+ |
||||
+ if (role != NULL) |
||||
+ free(role); |
||||
+ |
||||
+ return rv; |
||||
+} |
||||
+ |
||||
+/* Set the execution context to the default for the specified user */ |
||||
+void |
||||
+sshd_selinux_setup_exec_context(char *pwname) |
||||
+{ |
||||
+ security_context_t user_ctx = NULL; |
||||
+ int r = 0; |
||||
+ security_context_t default_ctx = NULL; |
||||
+ |
||||
+ if (!ssh_selinux_enabled()) |
||||
+ return; |
||||
+ |
||||
+ if (options.use_pam) { |
||||
+ /* do not compute context, just setup environment for pam_selinux */ |
||||
+ if (sshd_selinux_setup_pam_variables()) { |
||||
+ switch (security_getenforce()) { |
||||
+ case -1: |
||||
+ fatal("%s: security_getenforce() failed", __func__); |
||||
+ case 0: |
||||
+ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", |
||||
+ __func__); |
||||
+ break; |
||||
+ default: |
||||
+ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", |
||||
+ __func__); |
||||
+ } |
||||
+ } |
||||
+ return; |
||||
+ } |
||||
+ |
||||
+ debug3("%s: setting execution context", __func__); |
||||
+ |
||||
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); |
||||
+ if (r >= 0) { |
||||
+ r = setexeccon(user_ctx); |
||||
+ if (r < 0) { |
||||
+ error("%s: Failed to set SELinux execution context %s for %s", |
||||
+ __func__, user_ctx, pwname); |
||||
+ } |
||||
+#ifdef HAVE_SETKEYCREATECON |
||||
+ else if (setkeycreatecon(user_ctx) < 0) { |
||||
+ error("%s: Failed to set SELinux keyring creation context %s for %s", |
||||
+ __func__, user_ctx, pwname); |
||||
+ } |
||||
+#endif |
||||
+ } |
||||
+ if (user_ctx == NULL) { |
||||
+ user_ctx = default_ctx; |
||||
+ } |
||||
+ if (r < 0 || user_ctx != default_ctx) { |
||||
+ /* audit just the case when user changed a role or there was |
||||
+ a failure */ |
||||
+ sshd_selinux_send_audit_message(r >= 0, default_ctx, user_ctx); |
||||
+ } |
||||
+ if (r < 0) { |
||||
+ switch (security_getenforce()) { |
||||
+ case -1: |
||||
+ fatal("%s: security_getenforce() failed", __func__); |
||||
+ case 0: |
||||
+ error("%s: SELinux failure. Continuing in permissive mode.", |
||||
+ __func__); |
||||
+ break; |
||||
+ default: |
||||
+ fatal("%s: SELinux failure. Aborting connection.", |
||||
+ __func__); |
||||
+ } |
||||
+ } |
||||
+ if (user_ctx != NULL && user_ctx != default_ctx) |
||||
+ freecon(user_ctx); |
||||
+ if (default_ctx != NULL) |
||||
+ freecon(default_ctx); |
||||
+ |
||||
+ debug3("%s: done", __func__); |
||||
+} |
||||
+ |
||||
+#endif |
||||
+#endif |
||||
+ |
||||
diff -up openssh-7.4p1/platform.c.role-mls openssh-7.4p1/platform.c |
||||
--- openssh-7.4p1/platform.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/platform.c 2017-02-08 14:08:30.272308185 +0100 |
||||
@@ -184,7 +184,7 @@ platform_setusercontext_post_groups(stru |
||||
} |
||||
#endif /* HAVE_SETPCRED */ |
||||
#ifdef WITH_SELINUX |
||||
- ssh_selinux_setup_exec_context(pw->pw_name); |
||||
+ sshd_selinux_setup_exec_context(pw->pw_name); |
||||
#endif |
||||
} |
||||
|
||||
diff -up openssh-7.4p1/sshd.c.role-mls openssh-7.4p1/sshd.c |
||||
--- openssh-7.4p1/sshd.c.role-mls 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/sshd.c 2017-02-08 14:08:30.273308184 +0100 |
||||
@@ -2053,6 +2053,9 @@ main(int ac, char **av) |
||||
restore_uid(); |
||||
} |
||||
#endif |
||||
+#ifdef WITH_SELINUX |
||||
+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name); |
||||
+#endif |
||||
#ifdef USE_PAM |
||||
if (options.use_pam) { |
||||
do_pam_setcred(1); |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
diff --git a/sshd.c b/sshd.c |
||||
--- a/sshd.c |
||||
+++ b/sshd.c |
||||
@@ -1551,6 +1551,15 @@ main(int ac, char **av) |
||||
continue; |
||||
key = key_load_private(options.host_key_files[i], "", NULL); |
||||
pubkey = key_load_public(options.host_key_files[i], NULL); |
||||
+ |
||||
+ if ((pubkey != NULL && pubkey->type == KEY_RSA1) || |
||||
+ (key != NULL && key->type == KEY_RSA1)) { |
||||
+ verbose("Ignoring RSA1 key %s", |
||||
+ options.host_key_files[i]); |
||||
+ key_free(key); |
||||
+ key_free(pubkey); |
||||
+ continue; |
||||
+ } |
||||
if (pubkey == NULL && key != NULL) |
||||
pubkey = key_demote(key); |
||||
sensitive_data.host_keys[i] = key; |
@ -0,0 +1,211 @@
@@ -0,0 +1,211 @@
|
||||
From 5f1596e11d55539678c41f68aed358628d33d86f Mon Sep 17 00:00:00 2001 |
||||
From: Damien Miller <djm@mindrot.org> |
||||
Date: Tue, 14 Mar 2017 13:15:18 +1100 |
||||
Subject: [PATCH] support ioctls for ICA crypto card on Linux/s390 |
||||
|
||||
Based on patch from Eduardo Barretto; ok dtucker@ |
||||
--- |
||||
sandbox-seccomp-filter.c | 6 ++++++ |
||||
1 file changed, 6 insertions(+) |
||||
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c |
||||
index af5525a..6ceee33 100644 |
||||
--- a/sandbox-seccomp-filter.c |
||||
+++ b/sandbox-seccomp-filter.c |
||||
@@ -223,6 +223,12 @@ static const struct sock_filter preauth_insns[] = { |
||||
SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN), |
||||
SC_DENY(socketcall, EACCES), |
||||
#endif |
||||
+#if defined(__NR_ioctl) && defined(__s390__) |
||||
+ /* Allow ioctls for ICA crypto card on s390 */ |
||||
+ SC_ALLOW_ARG(ioctl, 1, Z90STAT_STATUS_MASK), |
||||
+ SC_ALLOW_ARG(ioctl, 1, ICARSAMODEXPO), |
||||
+ SC_ALLOW_ARG(ioctl, 1, ICARSACRT), |
||||
+#endif /* defined(__NR_ioctl) && defined(__s390__) */ |
||||
|
||||
/* Default deny */ |
||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), |
||||
|
||||
From 9e96b41682aed793fadbea5ccd472f862179fb02 Mon Sep 17 00:00:00 2001 |
||||
From: Damien Miller <djm@mindrot.org> |
||||
Date: Tue, 14 Mar 2017 12:24:47 +1100 |
||||
Subject: [PATCH] Fix weakness in seccomp-bpf sandbox arg inspection |
||||
|
||||
Syscall arguments are passed via an array of 64-bit values in struct |
||||
seccomp_data, but we were only inspecting the bottom 32 bits and not |
||||
even those correctly for BE systems. |
||||
|
||||
Fortunately, the only case argument inspection was used was in the |
||||
socketcall filtering so using this for sandbox escape seems |
||||
impossible. |
||||
|
||||
ok dtucker |
||||
--- |
||||
sandbox-seccomp-filter.c | 24 ++++++++++++++++++++---- |
||||
1 file changed, 20 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c |
||||
index 2e1ed2c..af5525a 100644 |
||||
--- a/sandbox-seccomp-filter.c |
||||
+++ b/sandbox-seccomp-filter.c |
||||
@@ -73,6 +73,16 @@ |
||||
# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP |
||||
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ |
||||
|
||||
+#if __BYTE_ORDER == __LITTLE_ENDIAN |
||||
+# define ARG_LO_OFFSET 0 |
||||
+# define ARG_HI_OFFSET sizeof(uint32_t) |
||||
+#elif __BYTE_ORDER == __BIG_ENDIAN |
||||
+# define ARG_LO_OFFSET sizeof(uint32_t) |
||||
+# define ARG_HI_OFFSET 0 |
||||
+#else |
||||
+#error "Unknown endianness" |
||||
+#endif |
||||
+ |
||||
/* Simple helpers to avoid manual errors (but larger BPF programs). */ |
||||
#define SC_DENY(_nr, _errno) \ |
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ |
||||
@@ -81,11 +91,17 @@ |
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ |
||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) |
||||
#define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \ |
||||
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \ |
||||
- /* load first syscall argument */ \ |
||||
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 6), \ |
||||
+ /* load and test first syscall argument, low word */ \ |
||||
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ |
||||
+ offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \ |
||||
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ |
||||
+ ((_arg_val) & 0xFFFFFFFF), 0, 3), \ |
||||
+ /* load and test first syscall argument, high word */ \ |
||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ |
||||
- offsetof(struct seccomp_data, args[(_arg_nr)])), \ |
||||
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \ |
||||
+ offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \ |
||||
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ |
||||
+ (((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \ |
||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ |
||||
/* reload syscall number; all rules expect it in accumulator */ \ |
||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ |
||||
|
||||
From 58b8cfa2a062b72139d7229ae8de567f55776f24 Mon Sep 17 00:00:00 2001 |
||||
From: Damien Miller <djm@mindrot.org> |
||||
Date: Wed, 22 Mar 2017 12:43:02 +1100 |
||||
Subject: [PATCH] Missing header on Linux/s390 |
||||
|
||||
Patch from Jakub Jelen |
||||
--- |
||||
sandbox-seccomp-filter.c | 3 +++ |
||||
1 file changed, 3 insertions(+) |
||||
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c |
||||
index a8d472a..2831e9d 100644 |
||||
--- a/sandbox-seccomp-filter.c |
||||
+++ b/sandbox-seccomp-filter.c |
||||
@@ -50,6 +50,9 @@ |
||||
#include <elf.h> |
||||
|
||||
#include <asm/unistd.h> |
||||
+#ifdef __s390__ |
||||
+#include <asm/zcrypt.h> |
||||
+#endif |
||||
|
||||
#include <errno.h> |
||||
#include <signal.h> |
||||
|
||||
getuid and geteuid are needed when using an openssl engine that calls a |
||||
crypto card, e.g. ICA (libica). |
||||
Those syscalls are also needed by the distros for audit code. |
||||
|
||||
Signed-off-by: Eduardo Barretto <ebarretto at linux.vnet.ibm.com> |
||||
--- |
||||
sandbox-seccomp-filter.c | 12 ++++++++++++ |
||||
1 file changed, 12 insertions(+) |
||||
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c |
||||
index 6e7de31..e86aa2c 100644 |
||||
--- a/sandbox-seccomp-filter.c |
||||
+++ b/sandbox-seccomp-filter.c |
||||
@@ -175,6 +175,18 @@ static const struct sock_filter preauth_insns[] = { |
||||
#ifdef __NR_getpid |
||||
SC_ALLOW(getpid), |
||||
#endif |
||||
+#ifdef __NR_getuid |
||||
+ SC_ALLOW(getuid), |
||||
+#endif |
||||
+#ifdef __NR_getuid32 |
||||
+ SC_ALLOW(getuid32), |
||||
+#endif |
||||
+#ifdef __NR_geteuid |
||||
+ SC_ALLOW(geteuid), |
||||
+#endif |
||||
+#ifdef __NR_geteuid32 |
||||
+ SC_ALLOW(geteuid32), |
||||
+#endif |
||||
#ifdef __NR_getrandom |
||||
SC_ALLOW(getrandom), |
||||
#endif |
||||
-- |
||||
1.9.1 |
||||
|
||||
The EP11 crypto card needs to make an ioctl call, which receives an |
||||
specific argument. This crypto card is for s390 only. |
||||
|
||||
Signed-off-by: Eduardo Barretto <ebarretto@xxxxxxxxxxxxxxxxxx> |
||||
--- |
||||
sandbox-seccomp-filter.c | 2 ++ |
||||
1 file changed, 2 insertions(+) |
||||
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c |
||||
index e86aa2c..98062f1 100644 |
||||
--- a/sandbox-seccomp-filter.c |
||||
+++ b/sandbox-seccomp-filter.c |
||||
@@ -250,6 +250,8 @@ static const struct sock_filter preauth_insns[] = { |
||||
SC_ALLOW_ARG(ioctl, 1, Z90STAT_STATUS_MASK), |
||||
SC_ALLOW_ARG(ioctl, 1, ICARSAMODEXPO), |
||||
SC_ALLOW_ARG(ioctl, 1, ICARSACRT), |
||||
+ /* Allow ioctls for EP11 crypto card on s390 */ |
||||
+ SC_ALLOW_ARG(ioctl, 1, ZSENDEP11CPRB), |
||||
#endif /* defined(__NR_ioctl) && defined(__s390__) */ |
||||
|
||||
/* Default deny */ |
||||
-- |
||||
1.9.1 |
||||
|
||||
In order to use the OpenSSL-ibmpkcs11 engine it is needed to allow flock |
||||
and ipc calls, because this engine calls OpenCryptoki (a PKCS#11 |
||||
implementation) which calls the libraries that will communicate with the |
||||
crypto cards. OpenCryptoki makes use of flock and ipc and, as of now, |
||||
this is only need on s390 architecture. |
||||
|
||||
Signed-off-by: Eduardo Barretto <ebarretto@xxxxxxxxxxxxxxxxxx> |
||||
--- |
||||
sandbox-seccomp-filter.c | 6 ++++++ |
||||
1 file changed, 6 insertions(+) |
||||
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c |
||||
index ca75cc7..6e7de31 100644 |
||||
--- a/sandbox-seccomp-filter.c |
||||
+++ b/sandbox-seccomp-filter.c |
||||
@@ -166,6 +166,9 @@ static const struct sock_filter preauth_insns[] = { |
||||
#ifdef __NR_exit_group |
||||
SC_ALLOW(exit_group), |
||||
#endif |
||||
+#if defined(__NR_flock) && defined(__s390__) |
||||
+ SC_ALLOW(flock), |
||||
+#endif |
||||
#ifdef __NR_getpgid |
||||
SC_ALLOW(getpgid), |
||||
#endif |
||||
@@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = { |
||||
#ifdef __NR_gettimeofday |
||||
SC_ALLOW(gettimeofday), |
||||
#endif |
||||
+#if defined(__NR_ipc) && defined(__s390__) |
||||
+ SC_ALLOW(ipc), |
||||
+#endif |
||||
#ifdef __NR_madvise |
||||
SC_ALLOW(madvise), |
||||
#endif |
||||
-- |
||||
1.9.1 |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
diff -up openssh-7.4p1/sandbox-seccomp-filter.c.sandbox openssh-7.4p1/sandbox-seccomp-filter.c |
||||
--- openssh-7.4p1/sandbox-seccomp-filter.c.sandbox 2017-04-21 13:30:49.692650798 +0200 |
||||
+++ openssh-7.4p1/sandbox-seccomp-filter.c 2017-04-21 13:30:52.259647579 +0200 |
||||
@@ -215,6 +215,7 @@ static const struct sock_filter preauth_ |
||||
#endif |
||||
#ifdef __NR_socketcall |
||||
SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN), |
||||
+ SC_DENY(socketcall, EACCES), |
||||
#endif |
||||
|
||||
/* Default deny */ |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
diff -up openssh-7.4p1/kex.c.sha2 openssh-7.4p1/kex.c |
||||
--- openssh-7.4p1/kex.c.sha2 2017-02-17 18:15:53.589835864 +0100 |
||||
+++ openssh-7.4p1/kex.c 2017-02-17 18:17:20.404781663 +0100 |
||||
@@ -379,21 +379,14 @@ static int |
||||
kex_send_ext_info(struct ssh *ssh) |
||||
{ |
||||
int r; |
||||
- char *algs; |
||||
|
||||
- if ((algs = sshkey_alg_list(0, 1, ',')) == NULL) |
||||
- return SSH_ERR_ALLOC_FAIL; |
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || |
||||
(r = sshpkt_put_u32(ssh, 1)) != 0 || |
||||
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 || |
||||
- (r = sshpkt_put_cstring(ssh, algs)) != 0 || |
||||
+ (r = sshpkt_put_cstring(ssh, "rsa-sha2-256,rsa-sha2-512")) != 0 || |
||||
(r = sshpkt_send(ssh)) != 0) |
||||
- goto out; |
||||
- /* success */ |
||||
- r = 0; |
||||
- out: |
||||
- free(algs); |
||||
- return r; |
||||
+ return r; |
||||
+ return 0; |
||||
} |
||||
|
||||
int |
@ -0,0 +1,315 @@
@@ -0,0 +1,315 @@
|
||||
diff -up openssh-7.4p1/clientloop.c.fingerprint openssh-7.4p1/clientloop.c |
||||
--- openssh-7.4p1/clientloop.c.fingerprint 2016-12-23 15:38:50.520432387 +0100 |
||||
+++ openssh-7.4p1/clientloop.c 2016-12-23 15:38:50.564432394 +0100 |
||||
@@ -2279,7 +2279,7 @@ update_known_hosts(struct hostkeys_updat |
||||
if (ctx->keys_seen[i] != 2) |
||||
continue; |
||||
if ((fp = sshkey_fingerprint(ctx->keys[i], |
||||
- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) |
||||
+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) |
||||
fatal("%s: sshkey_fingerprint failed", __func__); |
||||
do_log2(loglevel, "Learned new hostkey: %s %s", |
||||
sshkey_type(ctx->keys[i]), fp); |
||||
@@ -2287,7 +2287,7 @@ update_known_hosts(struct hostkeys_updat |
||||
} |
||||
for (i = 0; i < ctx->nold; i++) { |
||||
if ((fp = sshkey_fingerprint(ctx->old_keys[i], |
||||
- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) |
||||
+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) |
||||
fatal("%s: sshkey_fingerprint failed", __func__); |
||||
do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", |
||||
sshkey_type(ctx->old_keys[i]), fp); |
||||
@@ -2330,7 +2330,7 @@ update_known_hosts(struct hostkeys_updat |
||||
(r = hostfile_replace_entries(options.user_hostfiles[0], |
||||
ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, |
||||
options.hash_known_hosts, 0, |
||||
- options.fingerprint_hash)) != 0) |
||||
+ options.fingerprint_hash[0])) != 0) |
||||
error("%s: hostfile_replace_entries failed: %s", |
||||
__func__, ssh_err(r)); |
||||
} |
||||
@@ -2443,7 +2443,7 @@ client_input_hostkeys(void) |
||||
error("%s: parse key: %s", __func__, ssh_err(r)); |
||||
goto out; |
||||
} |
||||
- fp = sshkey_fingerprint(key, options.fingerprint_hash, |
||||
+ fp = sshkey_fingerprint(key, options.fingerprint_hash[0], |
||||
SSH_FP_DEFAULT); |
||||
debug3("%s: received %s key %s", __func__, |
||||
sshkey_type(key), fp); |
||||
diff -up openssh-7.4p1/readconf.c.fingerprint openssh-7.4p1/readconf.c |
||||
--- openssh-7.4p1/readconf.c.fingerprint 2016-12-23 15:38:50.559432393 +0100 |
||||
+++ openssh-7.4p1/readconf.c 2016-12-23 15:38:50.565432394 +0100 |
||||
@@ -1668,16 +1668,18 @@ parse_keytypes: |
||||
goto parse_string; |
||||
|
||||
case oFingerprintHash: |
||||
- intptr = &options->fingerprint_hash; |
||||
- arg = strdelim(&s); |
||||
- if (!arg || *arg == '\0') |
||||
- fatal("%.200s line %d: Missing argument.", |
||||
- filename, linenum); |
||||
- if ((value = ssh_digest_alg_by_name(arg)) == -1) |
||||
- fatal("%.200s line %d: Invalid hash algorithm \"%s\".", |
||||
- filename, linenum, arg); |
||||
- if (*activep && *intptr == -1) |
||||
- *intptr = value; |
||||
+ if (*activep && options->num_fingerprint_hash == 0) |
||||
+ while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
||||
+ value = ssh_digest_alg_by_name(arg); |
||||
+ if (value == -1) |
||||
+ fatal("%s line %d: unknown fingerprints algorithm specs: %s.", |
||||
+ filename, linenum, arg); |
||||
+ if (options->num_fingerprint_hash >= SSH_DIGEST_MAX) |
||||
+ fatal("%s line %d: too many fingerprints algorithm specs.", |
||||
+ filename, linenum); |
||||
+ options->fingerprint_hash[ |
||||
+ options->num_fingerprint_hash++] = value; |
||||
+ } |
||||
break; |
||||
|
||||
case oUpdateHostkeys: |
||||
@@ -1905,7 +1907,7 @@ initialize_options(Options * options) |
||||
options->canonicalize_fallback_local = -1; |
||||
options->canonicalize_hostname = -1; |
||||
options->revoked_host_keys = NULL; |
||||
- options->fingerprint_hash = -1; |
||||
+ options->num_fingerprint_hash = 0; |
||||
options->update_hostkeys = -1; |
||||
options->hostbased_key_types = NULL; |
||||
options->pubkey_key_types = NULL; |
||||
@@ -2102,8 +2104,10 @@ fill_default_options(Options * options) |
||||
options->canonicalize_fallback_local = 1; |
||||
if (options->canonicalize_hostname == -1) |
||||
options->canonicalize_hostname = SSH_CANONICALISE_NO; |
||||
- if (options->fingerprint_hash == -1) |
||||
- options->fingerprint_hash = SSH_FP_HASH_DEFAULT; |
||||
+ if (options->num_fingerprint_hash == 0) { |
||||
+ options->fingerprint_hash[options->num_fingerprint_hash++] = SSH_DIGEST_SHA256; |
||||
+ options->fingerprint_hash[options->num_fingerprint_hash++] = (FIPS_mode() ? SSH_DIGEST_SHA1 : SSH_DIGEST_MD5); |
||||
+ } |
||||
if (options->update_hostkeys == -1) |
||||
options->update_hostkeys = 0; |
||||
if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 || |
||||
@@ -2489,6 +2493,17 @@ dump_cfg_strarray(OpCodes code, u_int co |
||||
} |
||||
|
||||
static void |
||||
+dump_cfg_fmtarray(OpCodes code, u_int count, int *vals) |
||||
+{ |
||||
+ u_int i; |
||||
+ |
||||
+ printf("%s", lookup_opcode_name(code)); |
||||
+ for (i = 0; i < count; i++) |
||||
+ printf(" %s", fmt_intarg(code, vals[i])); |
||||
+ printf("\n"); |
||||
+} |
||||
+ |
||||
+static void |
||||
dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) |
||||
{ |
||||
u_int i; |
||||
@@ -2564,7 +2579,6 @@ dump_client_config(Options *o, const cha |
||||
dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); |
||||
dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); |
||||
dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); |
||||
- dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); |
||||
dump_cfg_fmtint(oForwardAgent, o->forward_agent); |
||||
dump_cfg_fmtint(oForwardX11, o->forward_x11); |
||||
dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); |
||||
@@ -2634,6 +2648,7 @@ dump_client_config(Options *o, const cha |
||||
dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); |
||||
dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); |
||||
dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); |
||||
+ dump_cfg_fmtarray(oFingerprintHash, o->num_fingerprint_hash, o->fingerprint_hash); |
||||
|
||||
/* Special cases */ |
||||
|
||||
diff -up openssh-7.4p1/readconf.h.fingerprint openssh-7.4p1/readconf.h |
||||
--- openssh-7.4p1/readconf.h.fingerprint 2016-12-23 15:38:50.559432393 +0100 |
||||
+++ openssh-7.4p1/readconf.h 2016-12-23 15:38:50.565432394 +0100 |
||||
@@ -21,6 +21,7 @@ |
||||
#define MAX_SEND_ENV 256 |
||||
#define SSH_MAX_HOSTS_FILES 32 |
||||
#define MAX_CANON_DOMAINS 32 |
||||
+#define MAX_SSH_DIGESTS 8 |
||||
#define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) |
||||
|
||||
struct allowed_cname { |
||||
@@ -162,7 +163,8 @@ typedef struct { |
||||
|
||||
char *revoked_host_keys; |
||||
|
||||
- int fingerprint_hash; |
||||
+ int num_fingerprint_hash; |
||||
+ int fingerprint_hash[MAX_SSH_DIGESTS]; |
||||
|
||||
int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ |
||||
|
||||
diff -up openssh-7.4p1/ssh_config.5.fingerprint openssh-7.4p1/ssh_config.5 |
||||
--- openssh-7.4p1/ssh_config.5.fingerprint 2016-12-23 15:38:50.565432394 +0100 |
||||
+++ openssh-7.4p1/ssh_config.5 2016-12-23 15:40:03.754444166 +0100 |
||||
@@ -652,12 +652,13 @@ or |
||||
.Cm no |
||||
(the default). |
||||
.It Cm FingerprintHash |
||||
-Specifies the hash algorithm used when displaying key fingerprints. |
||||
+Specifies the hash algorithms used when displaying key fingerprints. |
||||
Valid options are: |
||||
.Cm md5 |
||||
and |
||||
-.Cm sha256 |
||||
-(the default). |
||||
+.Cm sha256 . |
||||
+The default is |
||||
+.Cm "sha256 md5". |
||||
.It Cm ForwardAgent |
||||
Specifies whether the connection to the authentication agent (if any) |
||||
will be forwarded to the remote machine. |
||||
diff -up openssh-7.4p1/sshconnect2.c.fingerprint openssh-7.4p1/sshconnect2.c |
||||
--- openssh-7.4p1/sshconnect2.c.fingerprint 2016-12-23 15:38:50.561432394 +0100 |
||||
+++ openssh-7.4p1/sshconnect2.c 2016-12-23 15:38:50.566432394 +0100 |
||||
@@ -677,7 +677,7 @@ input_userauth_pk_ok(int type, u_int32_t |
||||
key->type, pktype); |
||||
goto done; |
||||
} |
||||
- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, |
||||
+ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], |
||||
SSH_FP_DEFAULT)) == NULL) |
||||
goto done; |
||||
debug2("input_userauth_pk_ok: fp %s", fp); |
||||
@@ -1172,7 +1172,7 @@ sign_and_send_pubkey(Authctxt *authctxt, |
||||
int matched, ret = -1, have_sig = 1; |
||||
char *fp; |
||||
|
||||
- if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, |
||||
+ if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash[0], |
||||
SSH_FP_DEFAULT)) == NULL) |
||||
return 0; |
||||
debug3("%s: %s %s", __func__, key_type(id->key), fp); |
||||
@@ -1864,7 +1864,7 @@ userauth_hostbased(Authctxt *authctxt) |
||||
goto out; |
||||
} |
||||
|
||||
- if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, |
||||
+ if ((fp = sshkey_fingerprint(private, options.fingerprint_hash[0], |
||||
SSH_FP_DEFAULT)) == NULL) { |
||||
error("%s: sshkey_fingerprint failed", __func__); |
||||
goto out; |
||||
diff -up openssh-7.4p1/sshconnect.c.fingerprint openssh-7.4p1/sshconnect.c |
||||
--- openssh-7.4p1/sshconnect.c.fingerprint 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/sshconnect.c 2016-12-23 15:38:50.566432394 +0100 |
||||
@@ -922,9 +922,9 @@ check_host_key(char *hostname, struct so |
||||
"of known hosts.", type, ip); |
||||
} else if (options.visual_host_key) { |
||||
fp = sshkey_fingerprint(host_key, |
||||
- options.fingerprint_hash, SSH_FP_DEFAULT); |
||||
+ options.fingerprint_hash[0], SSH_FP_DEFAULT); |
||||
ra = sshkey_fingerprint(host_key, |
||||
- options.fingerprint_hash, SSH_FP_RANDOMART); |
||||
+ options.fingerprint_hash[0], SSH_FP_RANDOMART); |
||||
if (fp == NULL || ra == NULL) |
||||
fatal("%s: sshkey_fingerprint fail", __func__); |
||||
logit("Host key fingerprint is %s\n%s", fp, ra); |
||||
@@ -966,12 +966,6 @@ check_host_key(char *hostname, struct so |
||||
else |
||||
snprintf(msg1, sizeof(msg1), "."); |
||||
/* The default */ |
||||
- fp = sshkey_fingerprint(host_key, |
||||
- options.fingerprint_hash, SSH_FP_DEFAULT); |
||||
- ra = sshkey_fingerprint(host_key, |
||||
- options.fingerprint_hash, SSH_FP_RANDOMART); |
||||
- if (fp == NULL || ra == NULL) |
||||
- fatal("%s: sshkey_fingerprint fail", __func__); |
||||
msg2[0] = '\0'; |
||||
if (options.verify_host_key_dns) { |
||||
if (matching_host_key_dns) |
||||
@@ -985,16 +979,28 @@ check_host_key(char *hostname, struct so |
||||
} |
||||
snprintf(msg, sizeof(msg), |
||||
"The authenticity of host '%.200s (%s)' can't be " |
||||
- "established%s\n" |
||||
- "%s key fingerprint is %s.%s%s\n%s" |
||||
+ "established%s\n", host, ip, msg1); |
||||
+ for (i = 0; i < (u_int) options.num_fingerprint_hash; i++) { |
||||
+ fp = sshkey_fingerprint(host_key, |
||||
+ options.fingerprint_hash[i], SSH_FP_DEFAULT); |
||||
+ ra = sshkey_fingerprint(host_key, |
||||
+ options.fingerprint_hash[i], SSH_FP_RANDOMART); |
||||
+ if (fp == NULL || ra == NULL) |
||||
+ fatal("%s: sshkey_fingerprint fail", __func__); |
||||
+ len = strlen(msg); |
||||
+ snprintf(msg+len, sizeof(msg)-len, |
||||
+ "%s key fingerprint is %s.%s%s\n%s", |
||||
+ type, fp, |
||||
+ options.visual_host_key ? "\n" : "", |
||||
+ options.visual_host_key ? ra : "", |
||||
+ msg2); |
||||
+ free(ra); |
||||
+ free(fp); |
||||
+ } |
||||
+ len = strlen(msg); |
||||
+ snprintf(msg+len, sizeof(msg)-len, |
||||
"Are you sure you want to continue connecting " |
||||
- "(yes/no)? ", |
||||
- host, ip, msg1, type, fp, |
||||
- options.visual_host_key ? "\n" : "", |
||||
- options.visual_host_key ? ra : "", |
||||
- msg2); |
||||
- free(ra); |
||||
- free(fp); |
||||
+ "(yes/no)? "); |
||||
if (!confirm(msg)) |
||||
goto fail; |
||||
hostkey_trusted = 1; /* user explicitly confirmed */ |
||||
@@ -1244,7 +1250,7 @@ verify_host_key(char *host, struct socka |
||||
struct sshkey *plain = NULL; |
||||
|
||||
if ((fp = sshkey_fingerprint(host_key, |
||||
- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { |
||||
+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { |
||||
error("%s: fingerprint host key: %s", __func__, ssh_err(r)); |
||||
r = -1; |
||||
goto out; |
||||
@@ -1252,7 +1258,7 @@ verify_host_key(char *host, struct socka |
||||
|
||||
if (sshkey_is_cert(host_key)) { |
||||
if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, |
||||
- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { |
||||
+ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { |
||||
error("%s: fingerprint CA key: %s", |
||||
__func__, ssh_err(r)); |
||||
r = -1; |
||||
@@ -1432,9 +1438,9 @@ show_other_keys(struct hostkeys *hostkey |
||||
if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) |
||||
continue; |
||||
fp = sshkey_fingerprint(found->key, |
||||
- options.fingerprint_hash, SSH_FP_DEFAULT); |
||||
+ options.fingerprint_hash[0], SSH_FP_DEFAULT); |
||||
ra = sshkey_fingerprint(found->key, |
||||
- options.fingerprint_hash, SSH_FP_RANDOMART); |
||||
+ options.fingerprint_hash[0], SSH_FP_RANDOMART); |
||||
if (fp == NULL || ra == NULL) |
||||
fatal("%s: sshkey_fingerprint fail", __func__); |
||||
logit("WARNING: %s key found for host %s\n" |
||||
@@ -1457,7 +1463,7 @@ warn_changed_key(Key *host_key) |
||||
{ |
||||
char *fp; |
||||
|
||||
- fp = sshkey_fingerprint(host_key, options.fingerprint_hash, |
||||
+ fp = sshkey_fingerprint(host_key, options.fingerprint_hash[0], |
||||
SSH_FP_DEFAULT); |
||||
if (fp == NULL) |
||||
fatal("%s: sshkey_fingerprint fail", __func__); |
||||
diff -up openssh-7.4p1/ssh-keysign.c.fingerprint openssh-7.4p1/ssh-keysign.c |
||||
--- openssh-7.4p1/ssh-keysign.c.fingerprint 2016-12-19 05:59:41.000000000 +0100 |
||||
+++ openssh-7.4p1/ssh-keysign.c 2016-12-23 15:38:50.566432394 +0100 |
||||
@@ -285,7 +285,7 @@ main(int argc, char **argv) |
||||
} |
||||
} |
||||
if (!found) { |
||||
- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, |
||||
+ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], |
||||
SSH_FP_DEFAULT)) == NULL) |
||||
fatal("%s: sshkey_fingerprint failed", __progname); |
||||
fatal("no matching hostkey found for key %s %s", |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
Revert 3cd5103c1e1aaa59bd66f7f52f6ebbcd5deb12f9 |
||||
|
||||
diff --git a/servconf.c b/servconf.c |
||||
index 475076bf2..318546290 100644 |
||||
--- a/servconf.c |
||||
+++ b/servconf.c |
||||
@@ -308,7 +308,7 @@ fill_default_server_options(ServerOptions *options) |
||||
if (options->max_sessions == -1) |
||||
options->max_sessions = DEFAULT_SESSIONS_MAX; |
||||
if (options->use_dns == -1) |
||||
- options->use_dns = 0; |
||||
+ options->use_dns = 1; |
||||
if (options->client_alive_interval == -1) |
||||
options->client_alive_interval = 0; |
||||
if (options->client_alive_count_max == -1) |
||||
diff --git a/sshd_config b/sshd_config |
||||
index e9045bc4d..c9042ac3c 100644 |
||||
--- a/sshd_config |
||||
+++ b/sshd_config |
||||
@@ -112,7 +112,7 @@ UsePrivilegeSeparation sandbox # Default for new installations. |
||||
#ClientAliveInterval 0 |
||||
#ClientAliveCountMax 3 |
||||
#ShowPatchLevel no |
||||
-#UseDNS no |
||||
+#UseDNS yes |
||||
#PidFile /var/run/sshd.pid |
||||
#MaxStartups 10:30:100 |
||||
#PermitTunnel no |
||||
diff --git a/sshd_config.5 b/sshd_config.5 |
||||
index 4fd93d68e..cf57c609f 100644 |
||||
--- a/sshd_config.5 |
||||
+++ b/sshd_config.5 |
||||
@@ -1379,10 +1379,12 @@ should look up the remote host name and check that |
||||
should look up the remote host name, and to check that |
||||
the resolved host name for the remote IP address maps back to the |
||||
very same IP address. |
||||
+The default is |
||||
+.Dq yes . |
||||
.Pp |
||||
If this option is set to |
||||
.Cm no |
||||
-(the default) then only addresses and not host names may be used in |
||||
+then only addresses and not host names may be used in |
||||
.Pa ~/.ssh/authorized_keys |
||||
.Cm from |
||||
and |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
commit 2985d4062ebf4204bbd373456a810d558698f9f5 |
||||
Author: dtucker@openbsd.org <dtucker@openbsd.org> |
||||
Date: Tue Jul 25 09:22:25 2017 +0000 |
||||
|
||||
upstream commit |
||||
|
||||
Make WinSCP patterns for SSH_OLD_DHGEX more specific to |
||||
exclude WinSCP 5.10.x and up. bz#2748, from martin at winscp.net, ok djm@ |
||||
|
||||
Upstream-ID: 6fd7c32e99af3952db007aa180e73142ddbc741a |
||||
|
||||
diff --git a/compat.c b/compat.c |
||||
index 156a5ea8..d82135e2 100644 |
||||
--- a/compat.c |
||||
+++ b/compat.c |
||||
@@ -177,9 +177,12 @@ compat_datafellows(const char *version) |
||||
"TTSSH/2.72*", SSH_BUG_HOSTKEYS }, |
||||
{ "WinSCP_release_4*," |
||||
"WinSCP_release_5.0*," |
||||
- "WinSCP_release_5.1*," |
||||
- "WinSCP_release_5.5*," |
||||
- "WinSCP_release_5.6*," |
||||
+ "WinSCP_release_5.1," |
||||
+ "WinSCP_release_5.1.*," |
||||
+ "WinSCP_release_5.5," |
||||
+ "WinSCP_release_5.5.*," |
||||
+ "WinSCP_release_5.6," |
||||
+ "WinSCP_release_5.6.*," |
||||
"WinSCP_release_5.7," |
||||
"WinSCP_release_5.7.1," |
||||
"WinSCP_release_5.7.2," |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
From 4d827f0d75a53d3952288ab882efbddea7ffadfe Mon Sep 17 00:00:00 2001 |
||||
From: "djm@openbsd.org" <djm@openbsd.org> |
||||
Date: Tue, 4 Apr 2017 00:24:56 +0000 |
||||
Subject: [PATCH] upstream commit |
||||
|
||||
disallow creation (of empty files) in read-only mode; |
||||
reported by Michal Zalewski, feedback & ok deraadt@ |
||||
|
||||
Upstream-ID: 5d9c8f2fa8511d4ecf95322994ffe73e9283899b |
||||
--- |
||||
sftp-server.c | 6 +++--- |
||||
1 file changed, 3 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/sftp-server.c b/sftp-server.c |
||||
index 3619cdfc0..df0fb5068 100644 |
||||
--- a/sftp-server.c |
||||
+++ b/sftp-server.c |
||||
@@ -1,4 +1,4 @@ |
||||
-/* $OpenBSD: sftp-server.c,v 1.110 2016/09/12 01:22:38 deraadt Exp $ */ |
||||
+/* $OpenBSD: sftp-server.c,v 1.111 2017/04/04 00:24:56 djm Exp $ */ |
||||
/* |
||||
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved. |
||||
* |
||||
@@ -691,8 +691,8 @@ process_open(u_int32_t id) |
||||
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)) { |
||||
+ ((flags & O_ACCMODE) != O_RDONLY || |
||||
+ (flags & (O_CREAT|O_TRUNC)) != 0)) { |
||||
verbose("Refusing open request in read-only mode"); |
||||
status = SSH2_FX_PERMISSION_DENIED; |
||||
} else { |
||||
|
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
authfd.c |
||||
authfd.h |
||||
atomicio.c |
||||
atomicio.h |
||||
bufaux.c |
||||
bufbn.c |
||||
buffer.h |
||||
buffer.c |
||||
cleanup.c |
||||
cipher.h |
||||
compat.h |
||||
defines.h |
||||
entropy.c |
||||
entropy.h |
||||
fatal.c |
||||
includes.h |
||||
kex.h |
||||
key.c |
||||
key.h |
||||
log.c |
||||
log.h |
||||
match.h |
||||
misc.c |
||||
misc.h |
||||
pathnames.h |
||||
platform.h |
||||
rsa.h |
||||
ssh-dss.c |
||||
ssh-rsa.c |
||||
ssh.h |
||||
ssh2.h |
||||
uidswap.c |
||||
uidswap.h |
||||
uuencode.c |
||||
uuencode.h |
||||
xmalloc.c |
||||
xmalloc.h |
@ -0,0 +1,693 @@
@@ -0,0 +1,693 @@
|
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-agent openssh-7.4p1/pam_ssh_agent_auth-0.10.3/get_command_line.c |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-agent 2017-02-14 10:19:16.466070259 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/get_command_line.c 2017-02-14 10:26:10.062866980 +0100 |
||||
@@ -65,8 +65,8 @@ proc_pid_cmdline(char *** inargv) |
||||
case EOF: |
||||
case '\0': |
||||
if (len > 0) { |
||||
- argv = pamsshagentauth_xrealloc(argv, count + 1, sizeof(*argv)); |
||||
- argv[count] = pamsshagentauth_xcalloc(len + 1, sizeof(*argv[count])); |
||||
+ argv = xrealloc(argv, count + 1, sizeof(*argv)); |
||||
+ argv[count] = xcalloc(len + 1, sizeof(*argv[count])); |
||||
strncpy(argv[count++], argbuf, len); |
||||
memset(argbuf, '\0', MAX_LEN_PER_CMDLINE_ARG + 1); |
||||
len = 0; |
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/identity.h.psaa-agent openssh-7.4p1/pam_ssh_agent_auth-0.10.3/identity.h |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/identity.h.psaa-agent 2016-11-13 04:24:32.000000000 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/identity.h 2017-02-14 10:19:12.225071868 +0100 |
||||
@@ -38,6 +38,12 @@ |
||||
typedef struct identity Identity; |
||||
typedef struct idlist Idlist; |
||||
|
||||
+typedef struct { |
||||
+ int fd; |
||||
+ Buffer identities; |
||||
+ int howmany; |
||||
+} AuthenticationConnection; |
||||
+ |
||||
struct identity { |
||||
TAILQ_ENTRY(identity) next; |
||||
AuthenticationConnection *ac; /* set if agent supports key */ |
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-agent openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-agent 2017-02-14 10:19:12.224071868 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c 2017-02-14 10:19:12.226071867 +0100 |
||||
@@ -52,12 +52,15 @@ |
||||
#include <openssl/evp.h> |
||||
#include "ssh2.h" |
||||
#include "misc.h" |
||||
+#include "ssherr.h" |
||||
|
||||
#include "userauth_pubkey_from_id.h" |
||||
#include "identity.h" |
||||
#include "get_command_line.h" |
||||
extern char **environ; |
||||
|
||||
+#define PAM_SSH_AGENT_AUTH_REQUESTv1 101 |
||||
+ |
||||
static char * |
||||
log_action(char ** action, size_t count) |
||||
{ |
||||
@@ -67,7 +70,7 @@ log_action(char ** action, size_t count) |
||||
if (count == 0) |
||||
return NULL; |
||||
|
||||
- buf = pamsshagentauth_xcalloc((count * MAX_LEN_PER_CMDLINE_ARG) + (count * 3), sizeof(*buf)); |
||||
+ buf = xcalloc((count * MAX_LEN_PER_CMDLINE_ARG) + (count * 3), sizeof(*buf)); |
||||
for (i = 0; i < count; i++) { |
||||
strcat(buf, (i > 0) ? " '" : "'"); |
||||
strncat(buf, action[i], MAX_LEN_PER_CMDLINE_ARG); |
||||
@@ -80,12 +83,12 @@ void |
||||
agent_action(Buffer *buf, char ** action, size_t count) |
||||
{ |
||||
size_t i; |
||||
- pamsshagentauth_buffer_init(buf); |
||||
+ buffer_init(buf); |
||||
|
||||
- pamsshagentauth_buffer_put_int(buf, count); |
||||
+ buffer_put_int(buf, count); |
||||
|
||||
for (i = 0; i < count; i++) { |
||||
- pamsshagentauth_buffer_put_cstring(buf, action[i]); |
||||
+ buffer_put_cstring(buf, action[i]); |
||||
} |
||||
} |
||||
|
||||
@@ -109,17 +112,17 @@ pamsshagentauth_session_id2_gen(Buffer * |
||||
char * retc; |
||||
int32_t reti; |
||||
|
||||
- rnd = pamsshagentauth_arc4random(); |
||||
+ rnd = arc4random(); |
||||
cookie_len = ((uint8_t) rnd); |
||||
while (cookie_len < 16) { |
||||
cookie_len += 16; /* Add 16 bytes to the size to ensure that while the length is random, the length is always reasonable; ticket #18 */ |
||||
} |
||||
|
||||
- cookie = pamsshagentauth_xcalloc(1,cookie_len); |
||||
+ cookie = xcalloc(1,cookie_len); |
||||
|
||||
for (i = 0; i < cookie_len; i++) { |
||||
if (i % 4 == 0) { |
||||
- rnd = pamsshagentauth_arc4random(); |
||||
+ rnd = arc4random(); |
||||
} |
||||
cookie[i] = (char) rnd; |
||||
rnd >>= 8; |
||||
@@ -134,7 +137,7 @@ pamsshagentauth_session_id2_gen(Buffer * |
||||
} |
||||
else { |
||||
action_logbuf = "unknown on this platform"; |
||||
- pamsshagentauth_buffer_init(&action_agentbuf); /* stays empty, means unavailable */ |
||||
+ buffer_init(&action_agentbuf); /* stays empty, means unavailable */ |
||||
} |
||||
|
||||
/* |
||||
@@ -151,35 +154,35 @@ pamsshagentauth_session_id2_gen(Buffer * |
||||
retc = getcwd(pwd, sizeof(pwd) - 1); |
||||
time(&ts); |
||||
|
||||
- pamsshagentauth_buffer_init(session_id2); |
||||
+ buffer_init(session_id2); |
||||
|
||||
- pamsshagentauth_buffer_put_int(session_id2, PAM_SSH_AGENT_AUTH_REQUESTv1); |
||||
- /* pamsshagentauth_debug3("cookie: %s", pamsshagentauth_tohex(cookie, cookie_len)); */ |
||||
- pamsshagentauth_buffer_put_string(session_id2, cookie, cookie_len); |
||||
- /* pamsshagentauth_debug3("user: %s", user); */ |
||||
- pamsshagentauth_buffer_put_cstring(session_id2, user); |
||||
- /* pamsshagentauth_debug3("ruser: %s", ruser); */ |
||||
- pamsshagentauth_buffer_put_cstring(session_id2, ruser); |
||||
- /* pamsshagentauth_debug3("servicename: %s", servicename); */ |
||||
- pamsshagentauth_buffer_put_cstring(session_id2, servicename); |
||||
- /* pamsshagentauth_debug3("pwd: %s", pwd); */ |
||||
+ buffer_put_int(session_id2, PAM_SSH_AGENT_AUTH_REQUESTv1); |
||||
+ /* debug3("cookie: %s", tohex(cookie, cookie_len)); */ |
||||
+ buffer_put_string(session_id2, cookie, cookie_len); |
||||
+ /* debug3("user: %s", user); */ |
||||
+ buffer_put_cstring(session_id2, user); |
||||
+ /* debug3("ruser: %s", ruser); */ |
||||
+ buffer_put_cstring(session_id2, ruser); |
||||
+ /* debug3("servicename: %s", servicename); */ |
||||
+ buffer_put_cstring(session_id2, servicename); |
||||
+ /* debug3("pwd: %s", pwd); */ |
||||
if(retc) |
||||
- pamsshagentauth_buffer_put_cstring(session_id2, pwd); |
||||
+ buffer_put_cstring(session_id2, pwd); |
||||
else |
||||
- pamsshagentauth_buffer_put_cstring(session_id2, ""); |
||||
- /* pamsshagentauth_debug3("action: %s", action_logbuf); */ |
||||
- pamsshagentauth_buffer_put_string(session_id2, action_agentbuf.buf + action_agentbuf.offset, action_agentbuf.end - action_agentbuf.offset); |
||||
+ buffer_put_cstring(session_id2, ""); |
||||
+ /* debug3("action: %s", action_logbuf); */ |
||||
+ buffer_put_string(session_id2, sshbuf_ptr(&action_agentbuf), sshbuf_len(&action_agentbuf)); |
||||
if (free_logbuf) { |
||||
free(action_logbuf); |
||||
- pamsshagentauth_buffer_free(&action_agentbuf); |
||||
+ buffer_free(&action_agentbuf); |
||||
} |
||||
- /* pamsshagentauth_debug3("hostname: %s", hostname); */ |
||||
+ /* debug3("hostname: %s", hostname); */ |
||||
if(reti >= 0) |
||||
- pamsshagentauth_buffer_put_cstring(session_id2, hostname); |
||||
+ buffer_put_cstring(session_id2, hostname); |
||||
else |
||||
- pamsshagentauth_buffer_put_cstring(session_id2, ""); |
||||
- /* pamsshagentauth_debug3("ts: %ld", ts); */ |
||||
- pamsshagentauth_buffer_put_int64(session_id2, (uint64_t) ts); |
||||
+ buffer_put_cstring(session_id2, ""); |
||||
+ /* debug3("ts: %ld", ts); */ |
||||
+ buffer_put_int64(session_id2, (uint64_t) ts); |
||||
|
||||
free(cookie); |
||||
return; |
||||
@@ -288,39 +291,47 @@ pamsshagentauth_find_authorized_keys(con |
||||
{ |
||||
Buffer session_id2 = { 0 }; |
||||
Identity *id; |
||||
- Key *key; |
||||
AuthenticationConnection *ac; |
||||
- char *comment; |
||||
uint8_t retval = 0; |
||||
uid_t uid = getpwnam(ruser)->pw_uid; |
||||
+ struct ssh_identitylist *idlist; |
||||
+ int r; |
||||
+ unsigned int i; |
||||
|
||||
OpenSSL_add_all_digests(); |
||||
pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename); |
||||
|
||||
if ((ac = ssh_get_authentication_connection_for_uid(uid))) { |
||||
- pamsshagentauth_verbose("Contacted ssh-agent of user %s (%u)", ruser, uid); |
||||
- for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2)) |
||||
+ verbose("Contacted ssh-agent of user %s (%u)", ruser, uid); |
||||
+ if ((r = ssh_fetch_identitylist(ac->fd, 2, |
||||
+ &idlist)) != 0) { |
||||
+ if (r != SSH_ERR_AGENT_NO_IDENTITIES) |
||||
+ fprintf(stderr, "error fetching identities for " |
||||
+ "protocol %d: %s\n", 2, ssh_err(r)); |
||||
+ } else { |
||||
+ for (i = 0; i < idlist->nkeys; i++) |
||||
{ |
||||
- if(key != NULL) { |
||||
- id = pamsshagentauth_xcalloc(1, sizeof(*id)); |
||||
- id->key = key; |
||||
- id->filename = comment; |
||||
+ if(idlist->keys[i] != NULL) { |
||||
+ id = xcalloc(1, sizeof(*id)); |
||||
+ id->key = idlist->keys[i]; |
||||
+ id->filename = idlist->comments[i]; |
||||
id->ac = ac; |
||||
if(userauth_pubkey_from_id(ruser, id, &session_id2)) { |
||||
retval = 1; |
||||
} |
||||
- free(id->filename); |
||||
- pamsshagentauth_key_free(id->key); |
||||
free(id); |
||||
if(retval == 1) |
||||
break; |
||||
} |
||||
} |
||||
- pamsshagentauth_buffer_free(&session_id2); |
||||
- ssh_close_authentication_connection(ac); |
||||
+ buffer_free(&session_id2); |
||||
+ ssh_free_identitylist(idlist); |
||||
+ ssh_close_authentication_socket(ac->fd); |
||||
+ free(ac); |
||||
+ } |
||||
} |
||||
else { |
||||
- pamsshagentauth_verbose("No ssh-agent could be contacted"); |
||||
+ verbose("No ssh-agent could be contacted"); |
||||
} |
||||
/* pamsshagentauth_xfree(session_id2); */ |
||||
EVP_cleanup(); |
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-agent openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-agent 2017-02-14 10:19:12.223071868 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c 2017-02-14 10:19:12.226071867 +0100 |
||||
@@ -104,7 +104,7 @@ pam_sm_authenticate(pam_handle_t * pamh, |
||||
* a patch 8-) |
||||
*/ |
||||
#if ! HAVE___PROGNAME || HAVE_BUNDLE |
||||
- __progname = pamsshagentauth_xstrdup(servicename); |
||||
+ __progname = xstrdup(servicename); |
||||
#endif |
||||
|
||||
for(i = argc, argv_ptr = (char **) argv; i > 0; ++argv_ptr, i--) { |
||||
@@ -130,11 +130,11 @@ pam_sm_authenticate(pam_handle_t * pamh, |
||||
#endif |
||||
} |
||||
|
||||
- pamsshagentauth_log_init(__progname, log_lvl, facility, getenv("PAM_SSH_AGENT_AUTH_DEBUG") ? 1 : 0); |
||||
+ log_init(__progname, log_lvl, facility, getenv("PAM_SSH_AGENT_AUTH_DEBUG") ? 1 : 0); |
||||
pam_get_item(pamh, PAM_USER, (void *) &user); |
||||
pam_get_item(pamh, PAM_RUSER, (void *) &ruser_ptr); |
||||
|
||||
- pamsshagentauth_verbose("Beginning pam_ssh_agent_auth for user %s", user); |
||||
+ verbose("Beginning pam_ssh_agent_auth for user %s", user); |
||||
|
||||
if(ruser_ptr) { |
||||
strncpy(ruser, ruser_ptr, sizeof(ruser) - 1); |
||||
@@ -149,12 +149,12 @@ pam_sm_authenticate(pam_handle_t * pamh, |
||||
#ifdef ENABLE_SUDO_HACK |
||||
if( (strlen(sudo_service_name) > 0) && strncasecmp(servicename, sudo_service_name, sizeof(sudo_service_name) - 1) == 0 && getenv("SUDO_USER") ) { |
||||
strncpy(ruser, getenv("SUDO_USER"), sizeof(ruser) - 1 ); |
||||
- pamsshagentauth_verbose( "Using environment variable SUDO_USER (%s)", ruser ); |
||||
+ verbose( "Using environment variable SUDO_USER (%s)", ruser ); |
||||
} else |
||||
#endif |
||||
{ |
||||
if( ! getpwuid(getuid()) ) { |
||||
- pamsshagentauth_verbose("Unable to getpwuid(getuid())"); |
||||
+ verbose("Unable to getpwuid(getuid())"); |
||||
goto cleanexit; |
||||
} |
||||
strncpy(ruser, getpwuid(getuid())->pw_name, sizeof(ruser) - 1); |
||||
@@ -163,11 +163,11 @@ pam_sm_authenticate(pam_handle_t * pamh, |
||||
|
||||
/* Might as well explicitely confirm the user exists here */ |
||||
if(! getpwnam(ruser) ) { |
||||
- pamsshagentauth_verbose("getpwnam(%s) failed, bailing out", ruser); |
||||
+ verbose("getpwnam(%s) failed, bailing out", ruser); |
||||
goto cleanexit; |
||||
} |
||||
if( ! getpwnam(user) ) { |
||||
- pamsshagentauth_verbose("getpwnam(%s) failed, bailing out", user); |
||||
+ verbose("getpwnam(%s) failed, bailing out", user); |
||||
goto cleanexit; |
||||
} |
||||
|
||||
@@ -177,8 +177,8 @@ pam_sm_authenticate(pam_handle_t * pamh, |
||||
*/ |
||||
parse_authorized_key_file(user, authorized_keys_file_input); |
||||
} else { |
||||
- pamsshagentauth_verbose("Using default file=/etc/security/authorized_keys"); |
||||
- authorized_keys_file = pamsshagentauth_xstrdup("/etc/security/authorized_keys"); |
||||
+ verbose("Using default file=/etc/security/authorized_keys"); |
||||
+ authorized_keys_file = xstrdup("/etc/security/authorized_keys"); |
||||
} |
||||
|
||||
/* |
||||
@@ -187,19 +187,19 @@ pam_sm_authenticate(pam_handle_t * pamh, |
||||
*/ |
||||
|
||||
if(user && strlen(ruser) > 0) { |
||||
- pamsshagentauth_verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file); |
||||
+ verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file); |
||||
|
||||
/* |
||||
* this pw_uid is used to validate the SSH_AUTH_SOCK, and so must be the uid of the ruser invoking the program, not the target-user |
||||
*/ |
||||
if(pamsshagentauth_find_authorized_keys(user, ruser, servicename)) { /* getpwnam(ruser)->pw_uid)) { */ |
||||
- pamsshagentauth_logit("Authenticated: `%s' as `%s' using %s", ruser, user, authorized_keys_file); |
||||
+ logit("Authenticated: `%s' as `%s' using %s", ruser, user, authorized_keys_file); |
||||
retval = PAM_SUCCESS; |
||||
} else { |
||||
- pamsshagentauth_logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file); |
||||
+ logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file); |
||||
} |
||||
} else { |
||||
- pamsshagentauth_logit("No %s specified, cannot continue with this form of authentication", (user) ? "ruser" : "user" ); |
||||
+ logit("No %s specified, cannot continue with this form of authentication", (user) ? "ruser" : "user" ); |
||||
} |
||||
|
||||
cleanexit: |
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c.psaa-agent openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c.psaa-agent 2016-11-13 04:24:32.000000000 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c 2017-02-14 10:19:12.226071867 +0100 |
||||
@@ -117,12 +117,12 @@ parse_authorized_key_file(const char *us |
||||
} else { |
||||
slash_ptr = strchr(auth_keys_file_buf, '/'); |
||||
if(!slash_ptr) |
||||
- pamsshagentauth_fatal |
||||
+ fatal |
||||
("cannot expand tilde in path without a `/'"); |
||||
|
||||
owner_uname_len = slash_ptr - auth_keys_file_buf - 1; |
||||
if(owner_uname_len > (sizeof(owner_uname) - 1)) |
||||
- pamsshagentauth_fatal("Username too long"); |
||||
+ fatal("Username too long"); |
||||
|
||||
strncat(owner_uname, auth_keys_file_buf + 1, owner_uname_len); |
||||
if(!authorized_keys_file_allowed_owner_uid) |
||||
@@ -130,11 +130,11 @@ parse_authorized_key_file(const char *us |
||||
getpwnam(owner_uname)->pw_uid; |
||||
} |
||||
authorized_keys_file = |
||||
- pamsshagentauth_tilde_expand_filename(auth_keys_file_buf, |
||||
+ tilde_expand_filename(auth_keys_file_buf, |
||||
authorized_keys_file_allowed_owner_uid); |
||||
strncpy(auth_keys_file_buf, authorized_keys_file, |
||||
sizeof(auth_keys_file_buf) - 1); |
||||
- pamsshagentauth_xfree(authorized_keys_file) /* when we |
||||
+ free(authorized_keys_file) /* when we |
||||
percent_expand |
||||
later, we'd step |
||||
on this, so free |
||||
@@ -150,7 +150,7 @@ parse_authorized_key_file(const char *us |
||||
strncat(hostname, fqdn, strcspn(fqdn, ".")); |
||||
#endif |
||||
authorized_keys_file = |
||||
- pamsshagentauth_percent_expand(auth_keys_file_buf, "h", |
||||
+ percent_expand(auth_keys_file_buf, "h", |
||||
getpwnam(user)->pw_dir, "H", hostname, |
||||
"f", fqdn, "u", user, NULL); |
||||
} |
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-agent openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-agent 2017-02-14 10:19:12.224071868 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c 2017-02-14 10:19:12.226071867 +0100 |
||||
@@ -35,6 +35,7 @@ |
||||
#include <sys/stat.h> |
||||
#include <sys/wait.h> |
||||
#include <fcntl.h> |
||||
+#include <unistd.h> |
||||
|
||||
#include <pwd.h> |
||||
#include <stdio.h> |
||||
@@ -53,6 +54,7 @@ |
||||
#include "misc.h" |
||||
#include "secure_filename.h" |
||||
#include "uidswap.h" |
||||
+#include "digest.h" |
||||
|
||||
#include "identity.h" |
||||
|
||||
@@ -68,7 +70,7 @@ pamsshagentauth_check_authkeys_file(FILE |
||||
char *fp; |
||||
|
||||
found_key = 0; |
||||
- found = pamsshagentauth_key_new(key->type); |
||||
+ found = key_new(key->type); |
||||
|
||||
while(read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { |
||||
char *cp = NULL; /* *key_options = NULL; */ |
||||
@@ -78,11 +80,11 @@ pamsshagentauth_check_authkeys_file(FILE |
||||
if(!*cp || *cp == '\n' || *cp == '#') |
||||
continue; |
||||
|
||||
- if(pamsshagentauth_key_read(found, &cp) != 1) { |
||||
+ if(key_read(found, &cp) != 1) { |
||||
/* no key? check if there are options for this key */ |
||||
int quoted = 0; |
||||
|
||||
- pamsshagentauth_verbose("user_key_allowed: check options: '%s'", cp); |
||||
+ verbose("user_key_allowed: check options: '%s'", cp); |
||||
/* key_options = cp; */ |
||||
for(; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { |
||||
if(*cp == '\\' && cp[1] == '"') |
||||
@@ -92,26 +94,26 @@ pamsshagentauth_check_authkeys_file(FILE |
||||
} |
||||
/* Skip remaining whitespace. */ |
||||
for(; *cp == ' ' || *cp == '\t'; cp++); |
||||
- if(pamsshagentauth_key_read(found, &cp) != 1) { |
||||
- pamsshagentauth_verbose("user_key_allowed: advance: '%s'", cp); |
||||
+ if(key_read(found, &cp) != 1) { |
||||
+ verbose("user_key_allowed: advance: '%s'", cp); |
||||
/* still no key? advance to next line */ |
||||
continue; |
||||
} |
||||
} |
||||
- if(pamsshagentauth_key_equal(found, key)) { |
||||
+ if(key_equal(found, key)) { |
||||
found_key = 1; |
||||
- pamsshagentauth_logit("matching key found: file/command %s, line %lu", file, |
||||
+ logit("matching key found: file/command %s, line %lu", file, |
||||
linenum); |
||||
- fp = pamsshagentauth_key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); |
||||
- pamsshagentauth_logit("Found matching %s key: %s", |
||||
- pamsshagentauth_key_type(found), fp); |
||||
+ fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); |
||||
+ logit("Found matching %s key: %s", |
||||
+ key_type(found), fp); |
||||
free(fp); |
||||
break; |
||||
} |
||||
} |
||||
- pamsshagentauth_key_free(found); |
||||
+ key_free(found); |
||||
if(!found_key) |
||||
- pamsshagentauth_verbose("key not found"); |
||||
+ verbose("key not found"); |
||||
return found_key; |
||||
} |
||||
|
||||
@@ -128,11 +130,11 @@ pamsshagentauth_user_key_allowed2(struct |
||||
char buf[SSH_MAX_PUBKEY_BYTES]; |
||||
|
||||
/* Temporarily use the user's uid. */ |
||||
- pamsshagentauth_verbose("trying public key file %s", file); |
||||
+ verbose("trying public key file %s", file); |
||||
|
||||
/* Fail not so quietly if file does not exist */ |
||||
if(stat(file, &st) < 0) { |
||||
- pamsshagentauth_verbose("File not found: %s", file); |
||||
+ verbose("File not found: %s", file); |
||||
return 0; |
||||
} |
||||
|
||||
@@ -144,7 +146,7 @@ pamsshagentauth_user_key_allowed2(struct |
||||
|
||||
if(pamsshagentauth_secure_filename(f, file, pw, buf, sizeof(buf)) != 0) { |
||||
fclose(f); |
||||
- pamsshagentauth_logit("Authentication refused: %s", buf); |
||||
+ logit("Authentication refused: %s", buf); |
||||
return 0; |
||||
} |
||||
|
||||
@@ -187,44 +189,44 @@ pamsshagentauth_user_key_command_allowed |
||||
else { |
||||
pw = getpwnam(authorized_keys_command_user); |
||||
if(pw == NULL) { |
||||
- pamsshagentauth_logerror("authorized_keys_command_user \"%s\" not found: %s", |
||||
+ error("authorized_keys_command_user \"%s\" not found: %s", |
||||
authorized_keys_command_user, strerror(errno)); |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
- pamsshagentauth_temporarily_use_uid(pw); |
||||
+ temporarily_use_uid(pw); |
||||
|
||||
if(stat(authorized_keys_command, &st) < 0) { |
||||
- pamsshagentauth_logerror |
||||
+ error |
||||
("Could not stat AuthorizedKeysCommand \"%s\": %s", |
||||
authorized_keys_command, strerror(errno)); |
||||
goto out; |
||||
} |
||||
if(pamsshagentauth_auth_secure_path |
||||
(authorized_keys_command, &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) { |
||||
- pamsshagentauth_logerror("Unsafe AuthorizedKeysCommand: %s", errmsg); |
||||
+ error("Unsafe AuthorizedKeysCommand: %s", errmsg); |
||||
goto out; |
||||
} |
||||
|
||||
/* open the pipe and read the keys */ |
||||
if(pipe(p) != 0) { |
||||
- pamsshagentauth_logerror("%s: pipe: %s", __func__, strerror(errno)); |
||||
+ error("%s: pipe: %s", __func__, strerror(errno)); |
||||
goto out; |
||||
} |
||||
|
||||
- pamsshagentauth_debug("Running AuthorizedKeysCommand: \"%s\" as \"%s\" with argument: \"%s\"", |
||||
+ debug("Running AuthorizedKeysCommand: \"%s\" as \"%s\" with argument: \"%s\"", |
||||
authorized_keys_command, pw->pw_name, username); |
||||
|
||||
/* |
||||
* Don't want to call this in the child, where it can fatal() and |
||||
* run cleanup_exit() code. |
||||
*/ |
||||
- pamsshagentauth_restore_uid(); |
||||
+ restore_uid(); |
||||
|
||||
switch ((pid = fork())) { |
||||
case -1: /* error */ |
||||
- pamsshagentauth_logerror("%s: fork: %s", __func__, strerror(errno)); |
||||
+ error("%s: fork: %s", __func__, strerror(errno)); |
||||
close(p[0]); |
||||
close(p[1]); |
||||
return 0; |
||||
@@ -234,13 +236,13 @@ pamsshagentauth_user_key_command_allowed |
||||
|
||||
/* do this before the setresuid so thta they can be logged */ |
||||
if((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { |
||||
- pamsshagentauth_logerror("%s: open %s: %s", __func__, _PATH_DEVNULL, |
||||
+ error("%s: open %s: %s", __func__, _PATH_DEVNULL, |
||||
strerror(errno)); |
||||
_exit(1); |
||||
} |
||||
if(dup2(devnull, STDIN_FILENO) == -1 || dup2(p[1], STDOUT_FILENO) == -1 |
||||
|| dup2(devnull, STDERR_FILENO) == -1) { |
||||
- pamsshagentauth_logerror("%s: dup2: %s", __func__, strerror(errno)); |
||||
+ error("%s: dup2: %s", __func__, strerror(errno)); |
||||
_exit(1); |
||||
} |
||||
#if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID) |
||||
@@ -248,7 +250,7 @@ pamsshagentauth_user_key_command_allowed |
||||
#else |
||||
if (setgid(pw->pw_gid) != 0 || setegid(pw->pw_gid) != 0) { |
||||
#endif |
||||
- pamsshagentauth_logerror("setresgid %u: %s", (u_int) pw->pw_gid, |
||||
+ error("setresgid %u: %s", (u_int) pw->pw_gid, |
||||
strerror(errno)); |
||||
_exit(1); |
||||
} |
||||
@@ -258,7 +260,7 @@ pamsshagentauth_user_key_command_allowed |
||||
#else |
||||
if (setuid(pw->pw_uid) != 0 || seteuid(pw->pw_uid) != 0) { |
||||
#endif |
||||
- pamsshagentauth_logerror("setresuid %u: %s", (u_int) pw->pw_uid, |
||||
+ error("setresuid %u: %s", (u_int) pw->pw_uid, |
||||
strerror(errno)); |
||||
_exit(1); |
||||
} |
||||
@@ -270,18 +272,18 @@ pamsshagentauth_user_key_command_allowed |
||||
|
||||
/* pretty sure this will barf because we are now suid, but since we |
||||
should't reach this anyway, I'll leave it here */ |
||||
- pamsshagentauth_logerror("AuthorizedKeysCommand %s exec failed: %s", |
||||
+ error("AuthorizedKeysCommand %s exec failed: %s", |
||||
authorized_keys_command, strerror(errno)); |
||||
_exit(127); |
||||
default: /* parent */ |
||||
break; |
||||
} |
||||
|
||||
- pamsshagentauth_temporarily_use_uid(pw); |
||||
+ temporarily_use_uid(pw); |
||||
|
||||
close(p[1]); |
||||
if((f = fdopen(p[0], "r")) == NULL) { |
||||
- pamsshagentauth_logerror("%s: fdopen: %s", __func__, strerror(errno)); |
||||
+ error("%s: fdopen: %s", __func__, strerror(errno)); |
||||
close(p[0]); |
||||
/* Don't leave zombie child */ |
||||
while(waitpid(pid, NULL, 0) == -1 && errno == EINTR); |
||||
@@ -292,22 +294,22 @@ pamsshagentauth_user_key_command_allowed |
||||
|
||||
while(waitpid(pid, &status, 0) == -1) { |
||||
if(errno != EINTR) { |
||||
- pamsshagentauth_logerror("%s: waitpid: %s", __func__, |
||||
+ error("%s: waitpid: %s", __func__, |
||||
strerror(errno)); |
||||
goto out; |
||||
} |
||||
} |
||||
if(WIFSIGNALED(status)) { |
||||
- pamsshagentauth_logerror("AuthorizedKeysCommand %s exited on signal %d", |
||||
+ error("AuthorizedKeysCommand %s exited on signal %d", |
||||
authorized_keys_command, WTERMSIG(status)); |
||||
goto out; |
||||
} else if(WEXITSTATUS(status) != 0) { |
||||
- pamsshagentauth_logerror("AuthorizedKeysCommand %s returned status %d", |
||||
+ error("AuthorizedKeysCommand %s returned status %d", |
||||
authorized_keys_command, WEXITSTATUS(status)); |
||||
goto out; |
||||
} |
||||
found_key = ok; |
||||
out: |
||||
- pamsshagentauth_restore_uid(); |
||||
+ restore_uid(); |
||||
return found_key; |
||||
} |
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/secure_filename.c.psaa-agent openssh-7.4p1/pam_ssh_agent_auth-0.10.3/secure_filename.c |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/secure_filename.c.psaa-agent 2016-11-13 04:24:32.000000000 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/secure_filename.c 2017-02-14 10:19:12.226071867 +0100 |
||||
@@ -80,7 +80,7 @@ pamsshagentauth_auth_secure_path(const c |
||||
int comparehome = 0; |
||||
struct stat st; |
||||
|
||||
- pamsshagentauth_verbose("auth_secure_filename: checking for uid: %u", uid); |
||||
+ verbose("auth_secure_filename: checking for uid: %u", uid); |
||||
|
||||
if (realpath(name, buf) == NULL) { |
||||
snprintf(err, errlen, "realpath %s failed: %s", name, |
||||
@@ -115,9 +115,9 @@ pamsshagentauth_auth_secure_path(const c |
||||
snprintf(err, errlen, "dirname() failed"); |
||||
return -1; |
||||
} |
||||
- pamsshagentauth_strlcpy(buf, cp, sizeof(buf)); |
||||
+ strlcpy(buf, cp, sizeof(buf)); |
||||
|
||||
- pamsshagentauth_verbose("secure_filename: checking '%s'", buf); |
||||
+ verbose("secure_filename: checking '%s'", buf); |
||||
if (stat(buf, &st) < 0 || |
||||
(st.st_uid != 0 && st.st_uid != uid) || |
||||
(st.st_mode & 022) != 0) { |
||||
@@ -128,7 +128,7 @@ pamsshagentauth_auth_secure_path(const c |
||||
|
||||
/* If are passed the homedir then we can stop */ |
||||
if (comparehome && strcmp(homedir, buf) == 0) { |
||||
- pamsshagentauth_verbose("secure_filename: terminating check at '%s'", |
||||
+ verbose("secure_filename: terminating check at '%s'", |
||||
buf); |
||||
break; |
||||
} |
||||
diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-agent openssh-7.4p1/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c |
||||
--- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-agent 2017-02-14 10:19:12.224071868 +0100 |
||||
+++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c 2017-02-14 10:19:12.226071867 +0100 |
||||
@@ -48,6 +48,8 @@ |
||||
#include "identity.h" |
||||
#include "pam_user_authorized_keys.h" |
||||
|
||||
+#define SSH2_MSG_USERAUTH_TRUST_REQUEST 54 |
||||
+ |
||||
/* extern u_char *session_id2; |
||||
extern uint8_t session_id_len; |
||||
*/ |
||||
@@ -58,40 +60,41 @@ userauth_pubkey_from_id(const char *ruse |
||||
Buffer b = { 0 }; |
||||
char *pkalg = NULL; |
||||
u_char *pkblob = NULL, *sig = NULL; |
||||
- u_int blen = 0, slen = 0; |
||||
+ u_int blen = 0; |
||||
+ size_t slen = 0; |
||||
int authenticated = 0; |
||||
|
||||
pkalg = (char *) key_ssh_name(id->key); |
||||
|
||||
+ /* construct packet to sign and test */ |
||||
+ buffer_init(&b); |
||||
+ |
||||
/* first test if this key is even allowed */ |
||||
if(! pam_user_key_allowed(ruser, id->key)) |
||||
goto user_auth_clean_exit; |
||||
|
||||
- if(pamsshagentauth_key_to_blob(id->key, &pkblob, &blen) == 0) |
||||
+ if(key_to_blob(id->key, &pkblob, &blen) == 0) |
||||
goto user_auth_clean_exit; |
||||
|
||||
- /* construct packet to sign and test */ |
||||
- pamsshagentauth_buffer_init(&b); |
||||
- |
||||
- pamsshagentauth_buffer_put_string(&b, session_id2->buf + session_id2->offset, session_id2->end - session_id2->offset); |
||||
- pamsshagentauth_buffer_put_char(&b, SSH2_MSG_USERAUTH_TRUST_REQUEST); |
||||
- pamsshagentauth_buffer_put_cstring(&b, ruser); |
||||
- pamsshagentauth_buffer_put_cstring(&b, "pam_ssh_agent_auth"); |
||||
- pamsshagentauth_buffer_put_cstring(&b, "publickey"); |
||||
- pamsshagentauth_buffer_put_char(&b, 1); |
||||
- pamsshagentauth_buffer_put_cstring(&b, pkalg); |
||||
- pamsshagentauth_buffer_put_string(&b, pkblob, blen); |
||||
+ buffer_put_string(&b, sshbuf_ptr(session_id2), sshbuf_len(session_id2)); |
||||
+ buffer_put_char(&b, SSH2_MSG_USERAUTH_TRUST_REQUEST); |
||||
+ buffer_put_cstring(&b, ruser); |
||||
+ buffer_put_cstring(&b, "pam_ssh_agent_auth"); |
||||
+ buffer_put_cstring(&b, "publickey"); |
||||
+ buffer_put_char(&b, 1); |
||||
+ buffer_put_cstring(&b, pkalg); |
||||
+ buffer_put_string(&b, pkblob, blen); |
||||
|
||||
- if(ssh_agent_sign(id->ac, id->key, &sig, &slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) != 0) |
||||
+ if(ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, buffer_ptr(&b), buffer_len(&b), NULL, 0) != 0) |
||||
goto user_auth_clean_exit; |
||||
|
||||
/* test for correct signature */ |
||||
- if(pamsshagentauth_key_verify(id->key, sig, slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) == 1) |
||||
+ if(key_verify(id->key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) |
||||
authenticated = 1; |
||||
|
||||
user_auth_clean_exit: |
||||
/* if(&b != NULL) */ |
||||
- pamsshagentauth_buffer_free(&b); |
||||
+ buffer_free(&b); |
||||
if(sig != NULL) |
||||
free(sig); |
||||
if(pkblob != NULL) |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue